Личный кабинет

Главная → Документация → Госномер по фото

Госномер, марка и цвет по фото

Распознавание автомобиля по фотографии: госномер, марка, модель, цвет и тип кузова в одном ответе, плюс признак, есть ли на снимке люди. Фото с телефона, камеры парковки или из объявления, до трёх машин на снимке. Госномер приходит в формате РФ и сразу подходит для проверки истории, залогов и ограничений.

Хост api.avtovincod.ruМетод POST /photo-plateВход фото JPEG, PNG, WebPСписание если есть номер или марка

Что распознаётся

Номер в ответе только целиком: если знак прочитан частично или неуверенно, plate будет null, а видимая часть попадёт в plateRaw. Так в проверки не уйдёт чужой номер.

Аутентификация

Токен передаётся заголовком Authorization: Bearer <токен> либо параметром ?token=. Токен один для всех API, он выдаётся в личном кабинете сразу после регистрации.

Эндпоинт

POST https://api.avtovincod.ru/photo-plate

Как передать фото

СпособКак
multipart/form-dataполе photo с файлом (подойдут и имена image, file): так отправляют формы и большинство HTTP-библиотек
image/jpegфото в теле запроса как есть, заголовок Content-Type: image/jpeg (или image/png, image/webp)
application/json{"image": "<base64>"}, допускается и data:image/jpeg;base64,...

Параметры в адресе

ПараметрОписание
testзначение 1: ответ-образец по схеме метода, бесплатно и без распознавания (фото можно не передавать)

Какое фото подходит

Пример запроса

curl -X POST "https://api.avtovincod.ru/photo-plate" \
  -H "Authorization: Bearer $TOKEN" \
  -F "photo=@car.jpg"

# фото в теле запроса
curl -X POST "https://api.avtovincod.ru/photo-plate" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: image/jpeg" \
  --data-binary @car.jpg

Пример ответа: машина и номер

Номер, марка, модель, цвет и кузов определены. Запрос платный.

{
  "success": 1,
  "found": 1,
  "query": { "image": { "width": 1280, "height": 622, "sha256": "5d0e7c93...a41f6c" } },
  "hasPeople": false,
  "plate": "В321ТК147",
  "plateRaw": "В321ТК147",
  "plateRegion": "147",
  "plateCountry": "RU",
  "plateReadable": true,
  "plateConfidence": "high",
  "brand": "Lada",
  "model": "2107",
  "color": "коричневый",
  "colorCode": "brown",
  "bodyType": "седан",
  "bodyTypeCode": "sedan",
  "confidence": "high",
  "carsCount": 1,
  "cars": [
    { "plate": "В321ТК147", "plateRaw": "В321ТК147", "plateRegion": "147", "plateCountry": "RU",
      "plateReadable": true, "plateConfidence": "high", "brand": "Lada", "model": "2107",
      "color": "коричневый", "colorCode": "brown", "bodyType": "седан", "bodyTypeCode": "sedan",
      "confidence": "high" }
  ],
  "billing": { "charged": 3, "currency": "RUB", "billed": true, "balance": 994, "requestId": 1234568 }
}

Поля ответа

ПолеЗначение
found1: на фото есть автомобиль, 0: автомобиля нет
hasPeopletrue: на фото видны люди (в том числе в машине), false: людей нет, null: не удалось определить. Пригодится, чтобы размыть лица перед публикацией, не хранить такие снимки или отправить их на ручную проверку
plateгосномер главной машины в формате РФ, кириллицей, без пробелов (А123ВС777); null, если номер не виден или прочитан не полностью
plateRawчто удалось прочитать на номерном знаке как есть, в том числе часть номера или номер другой страны; null, если номера не видно
plateRegionкод региона из номера (77, 777) либо null
plateCountryRU, если номер российского формата, иначе null
plateReadabletrue, если номер прочитан полностью и подходит для проверок
plateConfidenceнасколько уверенно прочитан номер: high, medium, low; null, если номера не видно. При low сверьте номер с фото
brand / modelмарка и модель латиницей в официальном написании: Lada / Vesta, Mercedes-Benz / E-Class; null, если не определены
color / colorCodeцвет по-русски и код: белый white, чёрный black, серый gray, серебристый silver, синий blue, голубой lightblue, красный red, бордовый burgundy, зелёный green, жёлтый yellow, оранжевый orange, коричневый brown, бежевый beige, фиолетовый purple, золотистый gold, другой other
bodyType / bodyTypeCodeтип кузова и код: седан sedan, хэтчбек hatchback, лифтбек liftback, универсал wagon, внедорожник suv, кроссовер crossover, купе coupe, кабриолет convertible, минивэн minivan, пикап pickup, фургон van, грузовик truck, автобус bus, мотоцикл motorcycle, другой other
confidenceнасколько уверенно определены марка и модель: high, medium, low
carsCount / carsсколько машин найдено на фото (до трёх) и все они с теми же полями; главная машина (самая крупная) первая, её поля продублированы на верхнем уровне
query.imageразмер исходного фото и его sha256: по нему видно, что повторно отправлен тот же файл

Схема ответа всегда одна и та же: если значение не определено, ключ остаётся со значением null.

Пример ответа: несколько машин на фото

Номер прочитан у главной машины, у двух других определены марка, модель и цвет. Списание одно за весь запрос.

{
  "success": 1,
  "found": 1,
  "query": { "image": { "width": 1280, "height": 960, "sha256": "c4f1a2b7...e19b20" } },
  "hasPeople": false,
  "plate": "А123ВС761",
  "plateRaw": "А123ВС761",
  "plateRegion": "761",
  "plateCountry": "RU",
  "plateReadable": true,
  "plateConfidence": "high",
  "brand": "Lada",
  "model": "Granta",
  "color": "синий",
  "colorCode": "blue",
  "bodyType": "седан",
  "bodyTypeCode": "sedan",
  "confidence": "high",
  "carsCount": 3,
  "cars": [
    { "plate": "А123ВС761", "plateRaw": "А123ВС761", "plateRegion": "761", "plateCountry": "RU",
      "plateReadable": true, "plateConfidence": "high", "brand": "Lada", "model": "Granta",
      "color": "синий", "colorCode": "blue", "bodyType": "седан", "bodyTypeCode": "sedan",
      "confidence": "high" },
    { "plate": null, "plateRaw": null, "plateRegion": null, "plateCountry": null,
      "plateReadable": false, "plateConfidence": null, "brand": "Mitsubishi", "model": "Outlander",
      "color": "чёрный", "colorCode": "black", "bodyType": "внедорожник", "bodyTypeCode": "suv",
      "confidence": "medium" },
    { "plate": null, "plateRaw": null, "plateRegion": null, "plateCountry": null,
      "plateReadable": false, "plateConfidence": null, "brand": "Volkswagen", "model": "Polo",
      "color": "белый", "colorCode": "white", "bodyType": "седан", "bodyTypeCode": "sedan",
      "confidence": "low" }
  ],
  "billing": { "charged": 3, "currency": "RUB", "billed": true, "balance": 997, "requestId": 1234567 }
}

Пример ответа: номер не читается, марка определена

Машина найдена, номер виден частично (он в plateRaw, а plate равен null). Запрос платный: марка и модель определены. На фото есть люди.

{
  "success": 1,
  "found": 1,
  "hasPeople": true,
  "plate": null,
  "plateRaw": "А123В",
  "plateRegion": null,
  "plateCountry": null,
  "plateReadable": false,
  "plateConfidence": "low",
  "brand": "Toyota",
  "model": "Camry",
  "color": "чёрный",
  "colorCode": "black",
  "bodyType": "седан",
  "bodyTypeCode": "sedan",
  "confidence": "high",
  "carsCount": 1,
  "cars": [ ... ],
  "billing": { "charged": 3, "currency": "RUB", "billed": true, "balance": 991, "requestId": 1234569 }
}

Пример ответа: видны только цвет и кузов

Машина на фото есть, но ни номер, ни марку определить нельзя (машина далеко, сзади, в темноте). Цвет и тип кузова в ответе есть, а запрос бесплатный.

{
  "success": 1,
  "found": 1,
  "query": { "image": { "width": 1280, "height": 960, "sha256": "9b27d0e4...3c58f1" } },
  "hasPeople": false,
  "plate": null,
  "plateRaw": null,
  "plateRegion": null,
  "plateCountry": null,
  "plateReadable": false,
  "plateConfidence": null,
  "brand": null,
  "model": null,
  "color": "белый",
  "colorCode": "white",
  "bodyType": "внедорожник",
  "bodyTypeCode": "suv",
  "confidence": "low",
  "carsCount": 1,
  "cars": [ ... ],
  "billing": { "charged": 0, "currency": "RUB", "billed": false, "balance": 991, "requestId": 1234570 }
}

Пример ответа: на фото нет машины

Ответ успешный, но пустой. Такой запрос бесплатный.

{
  "success": 1,
  "found": 0,
  "query": { "image": { "width": 1280, "height": 960, "sha256": "..." } },
  "hasPeople": true,
  "plate": null, "plateRaw": null, "plateRegion": null, "plateCountry": null,
  "plateReadable": false, "plateConfidence": null,
  "brand": null, "model": null, "color": null, "colorCode": null,
  "bodyType": null, "bodyTypeCode": null, "confidence": null,
  "carsCount": 0,
  "cars": [],
  "billing": { "charged": 0, "currency": "RUB", "billed": false, "balance": 991, "requestId": 1234571 }
}

Как показать пользователю

  1. Если plate не null, покажите номер крупно и предложите проверку по нему: VIN по госномеру, история регистрации, залоги.
  2. Если plateConfidence равно low или medium, попросите сверить номер с фото перед проверкой.
  3. Если plate null, покажите марку, модель и цвет и подсказку "снимите номер ближе".
  4. Для нескольких машин выведите cars списком, главная первой.
  5. Если hasPeople равно true, а снимок дальше публикуется (объявление, отчёт), закройте лица или предупредите пользователя.

Коды ошибок

КодЗначение
NO_TOKENтокен не передан
TOKEN_INVALIDтокен недействителен или деактивирован
NOT_ALLOWEDметод не подключён вашему токену
API_DISABLEDметод временно отключён
IP_NOT_ALLOWEDзапрос с IP вне вашего белого списка
METHOD_POSTзапрос не POST: фото передаётся POST-запросом
NO_PHOTOфото не передано или пустое
BAD_PHOTOфайл не удалось прочитать как фото
BAD_PHOTO_TYPEформат не JPEG, PNG или WebP (например, HEIC: сохраните как JPEG)
PHOTO_TOO_SMALLфото меньше 64 на 64 точки
PHOTO_TOO_BIGфайл больше 10 МБ или фото больше 40 мегапикселей (HTTP 413)
INSUFFICIENT_BALANCEнедостаточно средств на балансе
RATE_LIMITпревышен лимит запросов в минуту
RATE_LIMIT_IPслишком много запросов с одного IP
SERVICE_UNAVAILABLEраспознавание временно недоступно, повторите позже (HTTP 503)

Ошибка приходит в виде {"success": 0, "error": "...", "code": "..."} и никогда не тарифицируется.

Примеры кода: PHP, Python, JavaScript, Go, Java, C#, Ruby, 1С

Примеры готовы к запуску: токен берётся из переменной окружения AVC_TOKEN, фото из файла car.jpg, а в адресе стоит test=1. С ним приходит ответ-образец по схеме метода: бесплатно, без списания и даже при нулевом балансе, с полем "testMode": true. Уберите test=1, и фото будет распознано по-настоящему. Тестовый режим других методов.

curl -s --max-time 45 -X POST "https://api.avtovincod.ru/photo-plate?test=1" \
  -H "Authorization: Bearer $AVC_TOKEN" \
  -F "photo=@car.jpg"
<?php
$ch = curl_init('https://api.avtovincod.ru/photo-plate?test=1');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => ['photo' => new CURLFile('car.jpg', 'image/jpeg')],
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . getenv('AVC_TOKEN')],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 45,
]);
$d = json_decode(curl_exec($ch), true);
if (!empty($d['success']) && $d['found']) {
    echo ($d['plate'] ?? 'номер не прочитан') . ' ' . $d['brand'] . ' ' . $d['model'] . ', ' . $d['color'] . PHP_EOL;
} else {
    echo ($d['error'] ?? 'автомобиль на фото не найден') . PHP_EOL;
}
import os, requests

with open("car.jpg", "rb") as f:
    r = requests.post("https://api.avtovincod.ru/photo-plate", params={"test": 1},
                      headers={"Authorization": "Bearer " + os.environ["AVC_TOKEN"]},
                      files={"photo": ("car.jpg", f, "image/jpeg")}, timeout=45)
d = r.json()
if d.get("success") and d.get("found"):
    print(d["plate"] or "номер не прочитан", d["brand"], d["model"], d["color"])
else:
    print(d.get("error") or "автомобиль на фото не найден")
// Node.js 18+
import { readFile } from "node:fs/promises";

const form = new FormData();
form.append("photo", new Blob([await readFile("car.jpg")], { type: "image/jpeg" }), "car.jpg");
const res = await fetch("https://api.avtovincod.ru/photo-plate?test=1", {
  method: "POST",
  headers: { Authorization: "Bearer " + process.env.AVC_TOKEN },
  body: form,
  signal: AbortSignal.timeout(45000),
});
const d = await res.json();
console.log(d.success && d.found
  ? `${d.plate ?? "номер не прочитан"} ${d.brand} ${d.model}, ${d.color}`
  : d.error ?? "автомобиль на фото не найден");
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"os"
	"time"
)

func main() {
	var buf bytes.Buffer
	w := multipart.NewWriter(&buf)
	part, _ := w.CreateFormFile("photo", "car.jpg")
	f, err := os.Open("car.jpg")
	if err != nil {
		panic(err)
	}
	io.Copy(part, f)
	f.Close()
	w.Close()

	req, _ := http.NewRequest("POST", "https://api.avtovincod.ru/photo-plate?test=1", &buf)
	req.Header.Set("Authorization", "Bearer "+os.Getenv("AVC_TOKEN"))
	req.Header.Set("Content-Type", w.FormDataContentType())
	res, err := (&http.Client{Timeout: 45 * time.Second}).Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	var d map[string]any
	json.NewDecoder(res.Body).Decode(&d)
	fmt.Println(d["plate"], d["brand"], d["model"], d["color"])
}
// Java 11+: фото в теле запроса как есть (Content-Type: image/jpeg)
import java.net.URI;
import java.net.http.*;
import java.nio.file.Path;
import java.time.Duration;

public class Main {
    public static void main(String[] args) throws Exception {
        HttpRequest req = HttpRequest.newBuilder(URI.create("https://api.avtovincod.ru/photo-plate?test=1"))
            .header("Authorization", "Bearer " + System.getenv("AVC_TOKEN"))
            .header("Content-Type", "image/jpeg")
            .timeout(Duration.ofSeconds(45))
            .POST(HttpRequest.BodyPublishers.ofFile(Path.of("car.jpg")))
            .build();
        HttpResponse<String> res = HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString());
        System.out.println(res.body());   // plate, brand, model, color: разберите любой JSON-библиотекой
    }
}
using System.Net.Http.Headers;
using System.Text.Json;

using var http = new HttpClient { Timeout = TimeSpan.FromSeconds(45) };
http.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("AVC_TOKEN"));
var body = new ByteArrayContent(await File.ReadAllBytesAsync("car.jpg"));
body.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
var res = await http.PostAsync("https://api.avtovincod.ru/photo-plate?test=1", body);
using var doc = JsonDocument.Parse(await res.Content.ReadAsStringAsync());
var d = doc.RootElement;
if (d.GetProperty("success").GetInt32() == 1 && d.GetProperty("found").GetInt32() == 1)
    Console.WriteLine($"{d.GetProperty("plate")} {d.GetProperty("brand")} {d.GetProperty("model")}, {d.GetProperty("color")}");
else
    Console.WriteLine(d.TryGetProperty("error", out var e) ? e.GetString() : "автомобиль на фото не найден");
require "net/http"
require "json"

uri = URI("https://api.avtovincod.ru/photo-plate?test=1")
req = Net::HTTP::Post.new(uri, "Authorization" => "Bearer #{ENV['AVC_TOKEN']}", "Content-Type" => "image/jpeg")
req.body = File.binread("car.jpg")
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true, read_timeout: 45) { |h| h.request(req) }
d = JSON.parse(res.body)
if d["success"] == 1 && d["found"] == 1
  puts "#{d['plate'] || 'номер не прочитан'} #{d['brand']} #{d['model']}, #{d['color']}"
else
  puts d["error"] || "автомобиль на фото не найден"
end
Токен = "ВАШ_ТОКЕН";
Соединение = Новый HTTPСоединение("api.avtovincod.ru", , , , , 45, Новый ЗащищенноеСоединениеOpenSSL);
Запрос = Новый HTTPЗапрос("/photo-plate?test=1");
Запрос.Заголовки.Вставить("Authorization", "Bearer " + Токен);
Запрос.Заголовки.Вставить("Content-Type", "image/jpeg");
Запрос.УстановитьТелоИзДвоичныхДанных(Новый ДвоичныеДанные("C:\Фото\car.jpg"));
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку("UTF-8"));
Данные = ПрочитатьJSON(Чтение);
Если Данные.success = 1 И Данные.found = 1 Тогда
    Сообщить(Строка(Данные.plate) + " " + Данные.brand + " " + Данные.model + ", " + Данные.color);
Иначе
    Сообщить("Автомобиль на фото не найден");
КонецЕсли;

Бесплатных тестовых периодов и долгих согласований нет: пополните баланс в личном кабинете и сразу распознавайте реальные фото. Токен выдаётся при регистрации, деньги списываются только по правилам метода (раздел "Тарификация").

Примеры ответов: успешный, ошибка, сервис недоступен

Успешный запрос

POST https://api.avtovincod.ru/photo-plate
Authorization: Bearer ВАШ_ТОКЕН
Content-Type: multipart/form-data; boundary=...

HTTP 200, success: 1. Списание по тарифу метода, если определён госномер или марка; сумма и остаток в блоке billing (цифры в примерах выше условные).

Неуспешный запрос

Файл не является фото: HTTP 400, код BAD_PHOTO, текст ошибки можно показать пользователю. Бесплатно.

{
  "success": 0,
  "error": "Не удалось прочитать фото. Подходят JPEG, PNG и WebP.",
  "code": "BAD_PHOTO"
}

Сервис недоступен

Распознавание не выполнено: HTTP 503, SERVICE_UNAVAILABLE. Бесплатно, повторите запрос позже.

{
  "success": 0,
  "error": "Распознавание временно недоступно, деньги не списаны. Повторите позже.",
  "code": "SERVICE_UNAVAILABLE"
}

Тарификация

Деньги списываются один раз за запрос, если хотя бы у одной машины на фото определён госномер или марка. Номер не прочитан, но марка определена: платно. Видны только цвет и тип кузова, на фото нет машины, ошибки: бесплатно. Актуальная цена в личном кабинете.

В ответ добавляется блок billing: сколько списано за этот запрос (charged, в рублях), платный ли он (billed), остаток баланса после запроса (balance) и номер в истории запросов (requestId). Те же данные в заголовках X-Charged, X-Balance, X-Request-Id. Подробнее о блоке billing.

Хранение фото

Фото используется только для ответа на ваш запрос. Исходный файл не хранится. Уменьшенная копия без метаданных (координат съёмки, модели телефона и т.п.) хранится до 7 дней для разбора спорных случаев и затем удаляется автоматически.

Смежные методы

Частые вопросы

Как узнать номер машины по фото?

Отправьте фото POST-запросом на https://api.avtovincod.ru/photo-plate с токеном (поле photo в multipart/form-data или само фото в теле запроса). В ответе госномер, марка, модель, цвет и тип кузова.

Можно ли определить марку и модель автомобиля по фото без номера?

Да. Если номер не виден или не читается, в ответе всё равно будут марка, модель, цвет и тип кузова, а поле plate будет null. Такой запрос платный: марка определена.

Что если номер прочитан не полностью?

В plate попадает только полный номер в формате РФ. Если видна часть, она будет в plateRaw, а plate будет null: такой номер не стоит отправлять в проверки.

Когда списываются деньги?

Только если хотя бы у одной машины на фото определён госномер или марка. Если видны только цвет и тип кузова, на фото нет машины или произошла ошибка, запрос бесплатный.

Как узнать, есть ли на фото люди?

Поле hasPeople: true, если на снимке видны люди, в том числе в машине. Удобно, чтобы размыть лица перед публикацией, не сохранять такие фото или отправить их на ручную проверку.

Сколько машин можно распознать на одном фото?

До трёх. Главная (самая крупная) машина в полях верхнего уровня, все найденные в массиве cars.

Храните ли вы фото?

Исходный файл не храним. Уменьшенную копию без метаданных (координат съёмки, модели телефона) держим до 7 дней для разбора спорных случаев, затем она удаляется.

Попробовать без программиста

В личном кабинете есть страница распознавания: сфотографируйте машину телефоном или загрузите снимок, по номеру сразу откройте полный отчёт.

Открыть кабинет