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

Главная → Документация → Скрыть номер на фото

Как скрыть или замазать номер машины на фото

Скрывает госномер на фото автомобиля перед публикацией объявления: замазывает цветом, закрывает вашим логотипом или размывает точно по контуру номера, с учётом наклона и перспективы. По желанию скрывает и лица людей. До 10 фото за раз, фото остаётся в своём размере, метаданные (координаты съёмки, модель телефона) удаляются. Работает через API и в личном кабинете, без программиста.

Хост api.avtovincod.ruМетод POST /plate-hideДо 10 фото за запросСписание за фото с найденным номером

Как скрыть номер на фото онлайн за минуту

  1. Зарегистрируйтесь в личном кабинете и пополните баланс.
  2. Откройте "Скрыть номер и лица на фото" и загрузите снимки машины, можно сразу несколько.
  3. Выберите способ: размыть, замазать цветом, мозаика или ваш логотип. Если номер не нашёлся, обведите его мышкой или пальцем.
  4. Скачайте готовые фото по одному или все архивом и публикуйте объявление.

Кабинет работает в браузере телефона (iPhone и Android): фото выбираются прямо из галереи, программы ставить не нужно.

Для сайтов, досок объявлений и программ то же самое делает один запрос к API (описание ниже).

Для чего

Зачем замазывают номера машин на фото

Покупателю номер всё равно понадобится, чтобы проверить машину. Его удобно сообщать по запросу, когда разговор уже идёт.

Что закрыть: номер, лица или всё сразу

targetЧто закрываетсяКогда платно
plates (по умолчанию)госномеранайден хотя бы один номер
facesтолько лица людей, номер остаётсянайдено хотя бы одно лицо
allномера и лицанайден номер или лицо

Для одних лиц есть короткий адрес POST /face-hide и отдельное описание: Размытие лиц на фото.

Как замазать номер: цветом, логотипом, размытием или мозаикой

modeКак выглядит
blurразмытие (по умолчанию): номер превращается в мягкое пятно, буквы не восстановить; сила - параметр strength
pixelмозаика крупными блоками
fillзаливка цветом color по контуру номера, с учётом наклона
logoваш логотип на табличке цвета color по контуру номера, с наклоном и перспективой; логотип загружается заранее (POST /plate-hide/logo). Без логотипа - табличка цветом

Номер закрывается с запасом: лучше закрыть чуть больше, чем оставить видимым край. Для заливки и логотипа после закрытия проверяется, что все символы номера оказались под закрытием; если контур найти не удалось, закрывается прямоугольник с запасом.

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

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

Эндпоинт

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

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

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

Параметры

В адресе запроса, полями формы или ключами JSON.

ПараметрОписание
modeblur, pixel, fill, logo; по умолчанию blur
colorцвет заливки или фона таблички с логотипом, RRGGBB без решётки: 2b2b2b, ffffff
strengthсила размытия и мозаики: 1 (по умолчанию), 2, 3
targetчто закрыть: plates - номера (по умолчанию), faces - только лица, all - номера и лица
faces1: то же, что target=all (оставлен для совместимости)
faceModeкак закрывать лица: blur (по умолчанию), pixel, fill; при target=faces можно передать способ просто в mode
qualityкачество JPEG готового фото, 60-95 (по умолчанию 90)
formatimage - готовое фото в ответе (по умолчанию для одного фото); json - сведения и ссылка на фото (по умолчанию для нескольких и для запроса в JSON); zip - архив с фото и result.json
inline1: в JSON вместе со ссылкой положить фото в base64 (поле image.base64)
boxesсвои рамки номеров для одного фото: [[x1,y1,x2,y2], ...] в точках фото после поворота по EXIF (в тех же координатах, что image.width x image.height и рамки в ответе); поиск номеров тогда не выполняется, закрывается ровно указанное
recognize1: заодно распознать номер, марку и цвет методом Госномер по фото (по его цене и правилам, ответ в поле recognition); только для одного фото
test1: бесплатная проба - фото обрабатывается, но приходит уменьшенным (до 800 точек) и с пометкой TEST

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

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

# одно фото: в ответе готовое фото
curl -X POST "https://api.avtovincod.ru/plate-hide?mode=logo&color=ffffff" \
  -H "Authorization: Bearer $TOKEN" \
  -F "photo=@car.jpg" -o car_hidden.jpg

# несколько фото: JSON со ссылками на готовые фото
curl -X POST "https://api.avtovincod.ru/plate-hide?mode=blur&target=all" \
  -H "Authorization: Bearer $TOKEN" \
  -F "photos[]=@front.jpg" -F "photos[]=@back.jpg" -F "photos[]=@salon.jpg"

# архивом
curl -X POST "https://api.avtovincod.ru/plate-hide?format=zip" \
  -H "Authorization: Bearer $TOKEN" \
  -F "photos[]=@front.jpg" -F "photos[]=@back.jpg" -o photos.zip

Ответ: одно фото

По умолчанию в ответе само готовое фото, а сведения о нём - в заголовках.

HTTP/1.1 200 OK
Content-Type: image/jpeg
Content-Disposition: inline; filename="car_hidden.jpg"
X-Plates-Found: 1
X-Faces-Found: 0
X-Needs-Review: 0
X-Charged: 0.5
X-Balance: 999.5
X-Request-Id: 1234567
X-Result-Url: https://api.avtovincod.ru/plate-hide/file?id=1234567&until=...&sig=...

<байты готового фото>
ЗаголовокЗначение
X-Plates-Foundсколько номеров закрыто
X-Faces-Foundсколько лиц закрыто (при faces=1)
X-Needs-Review1: стоит посмотреть фото глазами
X-Charged, X-Balance, X-Request-Idсписано за запрос, остаток баланса, номер в истории
X-Result-Urlссылка на это же готовое фото, действует 24 часа

С format=json приходят сведения и ссылка на фото:

{
  "success": 1,
  "name": "car",
  "found": 1,
  "platesCount": 1,
  "facesCount": 0,
  "needsReview": false,
  "plates": [
    { "box": [412, 905, 655, 980],
      "corners": [[412.0, 905.3], [655.0, 941.8], [655.0, 980.1], [412.0, 942.6]],
      "confidence": 0.93, "manual": false }
  ],
  "faces": [],
  "image": {
    "contentType": "image/jpeg",
    "width": 1600,
    "height": 1200,
    "bytes": 284113,
    "url": "https://api.avtovincod.ru/plate-hide/file?id=1234567&until=1792400000&sig=...",
    "urlExpiresAt": "2026-10-19T12:00:00+03:00"
  },
  "requestId": 1234567,
  "charged": 0.5,
  "billing": { "charged": 0.5, "currency": "RUB", "billed": true, "balance": 999.5, "requestId": 1234567 }
}

Поля ответа

ПолеЗначение
found1: закрыто то, что просили (номер, лицо), 0: ничего не найдено
targetчто закрывалось: plates, faces или all
platesCount / platesсколько номеров закрыто и где: box - рамка [x1, y1, x2, y2] в точках фото, corners - четыре угла номера (если контур найден; иначе null и закрыт прямоугольник с запасом), confidence - уверенность 0-1, manual - рамка ваша (boxes)
facesCount / facesсколько лиц закрыто и где (при target=faces или all)
needsReviewtrue: стоит посмотреть глазами - номер очень мелкий или найден неуверенно
imageготовое фото: тип, размер, байты, url для скачивания (24 часа) и urlExpiresAt; base64 при inline=1
requestId / chargedномер в истории запросов и сколько списано за это фото
name / indexимя файла без расширения и номер фото в запросе (для нескольких фото)

Ответ: несколько фото

Каждое фото обрабатывается и оплачивается отдельно; ошибка одного фото не мешает остальным. processed - сколько фото обработано успешно.

{
  "success": 1,
  "count": 3,
  "processed": 2,
  "results": [
    { "index": 0, "name": "front", "success": 1, "found": 1, "platesCount": 1, "facesCount": 0,
      "needsReview": false, "plates": [ ... ], "faces": [],
      "image": { "contentType": "image/jpeg", "width": 4032, "height": 3024, "bytes": 1893422,
                 "url": "https://api.avtovincod.ru/plate-hide/file?id=1234568&...", "urlExpiresAt": "..." },
      "requestId": 1234568, "charged": 0.5 },
    { "index": 1, "name": "salon", "success": 1, "found": 0, "platesCount": 0, "facesCount": 0,
      "needsReview": false, "plates": [], "faces": [],
      "image": { "contentType": "image/jpeg", "width": 4032, "height": 3024, "bytes": 2210510,
                 "url": "https://api.avtovincod.ru/plate-hide/file?id=1234569&...", "urlExpiresAt": "..." },
      "requestId": 1234569, "charged": 0 },
    { "index": 2, "name": "doc", "success": 0, "code": "BAD_PHOTO",
      "error": "Не удалось прочитать фото (JPEG, PNG, WebP)." }
  ],
  "billing": { "charged": 0.5, "currency": "RUB", "billed": true, "balance": 999,
               "requestId": 1234569, "requestIds": [1234568, 1234569] }
}

С format=zip приходит архив: готовые фото с окончанием _hidden и result.json с теми же сведениями.

Свой логотип

# загрузить (PNG с прозрачным фоном, JPEG или WebP, до 2 МБ; хранится, пока не замените)
curl -X POST "https://api.avtovincod.ru/plate-hide/logo" -H "Authorization: Bearer $TOKEN" -F "logo=@logo.png"
# есть ли логотип
curl "https://api.avtovincod.ru/plate-hide/logo" -H "Authorization: Bearer $TOKEN"
# удалить
curl -X POST "https://api.avtovincod.ru/plate-hide/logo?delete=1" -H "Authorization: Bearer $TOKEN"

Лучше широкий логотип (как номер, примерно 4:1) на прозрачном фоне: он ставится на табличку цвета color по центру с полями. Загрузка и удаление логотипа бесплатны.

Если номер закрыт не там

Если номер не нашёлся (platesCount: 0) или закрыто лишнее, передайте свои рамки: boxes=[[x1,y1,x2,y2]] в точках фото, как в ответе (после поворота по EXIF: те же координаты, что у plates[].box и image.width x image.height). Поиск номеров тогда не выполняется. Пустой список boxes=[] - номера не закрывать (только удалить метаданные; закрыть одни лица проще через target=faces).

Коды ошибок

КодЗначение
NO_TOKENтокен не передан
TOKEN_INVALIDтокен недействителен или деактивирован
NOT_ALLOWEDметод не подключён вашему токену
API_DISABLEDметод временно отключён
IP_NOT_ALLOWEDзапрос с IP вне вашего белого списка
METHOD_POSTзапрос не POST
NO_PHOTOфото не передано или пустое
BAD_PHOTOфайл не удалось прочитать как фото (JPEG, PNG, WebP)
PHOTO_TOO_SMALLфото меньше 64 на 64 точки
PHOTO_TOO_BIGфайл больше 20 МБ, фото больше 40 мегапикселей или запрос больше допустимого (HTTP 413)
TOO_MANY_PHOTOSбольше 10 фото в одном запросе
BAD_MODEmode=logo вместе с target=faces: логотип ставится только на номер
BAD_BOXESпараметр boxes не в формате [[x1,y1,x2,y2], ...] или передан для нескольких фото
RECOGNIZE_SINGLErecognize=1 передан для нескольких фото
INSUFFICIENT_BALANCEнедостаточно средств на все фото запроса
RATE_LIMITпревышен лимит запросов в минуту
SERVICE_UNAVAILABLEобработка временно недоступна, повторите позже (HTTP 503)
TIMEOUTфото пакета не успело обработаться за время запроса, отправьте его ещё раз
LINK_INVALID / FILE_GONEссылка на готовое фото неверная или её срок (24 часа) вышел

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

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

Примеры готовы к запуску: токен из переменной окружения AVC_TOKEN, фото из файла car.jpg, результат в car_hidden.jpg. В адресе стоит test=1: фото обрабатывается бесплатно, но приходит уменьшенным и с пометкой TEST. Уберите test=1 для настоящей обработки.

curl -s --max-time 45 -X POST "https://api.avtovincod.ru/plate-hide?test=1&mode=blur" \
  -H "Authorization: Bearer $AVC_TOKEN" \
  -F "photo=@car.jpg" -o car_hidden.jpg
<?php
$ch = curl_init('https://api.avtovincod.ru/plate-hide?test=1&mode=blur');
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,
]);
$img = curl_exec($ch);
$type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
if (strpos((string)$type, 'image/') === 0) {
    file_put_contents('car_hidden.jpg', $img);       // номер закрыт
} else {
    echo json_decode($img, true)['error'] ?? 'ошибка', PHP_EOL;
}
import os, requests

with open("car.jpg", "rb") as f:
    r = requests.post("https://api.avtovincod.ru/plate-hide", params={"test": 1, "mode": "blur"},
                      headers={"Authorization": "Bearer " + os.environ["AVC_TOKEN"]},
                      files={"photo": ("car.jpg", f, "image/jpeg")}, timeout=45)
if r.headers.get("Content-Type", "").startswith("image/"):
    open("car_hidden.jpg", "wb").write(r.content)
    print("номеров закрыто:", r.headers.get("X-Plates-Found"))
else:
    print(r.json().get("error"))
// Node.js 18+
import { readFile, writeFile } 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/plate-hide?test=1&mode=blur", {
  method: "POST",
  headers: { Authorization: "Bearer " + process.env.AVC_TOKEN },
  body: form,
  signal: AbortSignal.timeout(45000),
});
if ((res.headers.get("content-type") || "").startsWith("image/")) {
  await writeFile("car_hidden.jpg", Buffer.from(await res.arrayBuffer()));
  console.log("номеров закрыто:", res.headers.get("x-plates-found"));
} else {
  console.log((await res.json()).error);
}
package main

import (
	"bytes"
	"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/plate-hide?test=1&mode=blur", &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()
	body, _ := io.ReadAll(res.Body)
	os.WriteFile("car_hidden.jpg", body, 0644)
	fmt.Println("номеров закрыто:", res.Header.Get("X-Plates-Found"))
}
// 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/plate-hide?test=1&mode=blur"))
            .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<Path> res = HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofFile(Path.of("car_hidden.jpg")));
        System.out.println("номеров закрыто: " + res.headers().firstValue("X-Plates-Found").orElse("?"));
    }
}
using System.Net.Http.Headers;

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/plate-hide?test=1&mode=blur", body);
if (res.Content.Headers.ContentType?.MediaType?.StartsWith("image/") == true)
    await File.WriteAllBytesAsync("car_hidden.jpg", await res.Content.ReadAsByteArrayAsync());
else
    Console.WriteLine(await res.Content.ReadAsStringAsync());
require "net/http"

uri = URI("https://api.avtovincod.ru/plate-hide?test=1&mode=blur")
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) }
if res["Content-Type"].to_s.start_with?("image/")
  File.binwrite("car_hidden.jpg", res.body)
else
  puts res.body
end
Токен = "ВАШ_ТОКЕН";
Соединение = Новый HTTPСоединение("api.avtovincod.ru", , , , , 45, Новый ЗащищенноеСоединениеOpenSSL);
Запрос = Новый HTTPЗапрос("/plate-hide?test=1&mode=blur");
Запрос.Заголовки.Вставить("Authorization", "Bearer " + Токен);
Запрос.Заголовки.Вставить("Content-Type", "image/jpeg");
Запрос.УстановитьТелоИзДвоичныхДанных(Новый ДвоичныеДанные("C:\Фото\car.jpg"));
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Если СтрНачинаетсяС(Ответ.Заголовки.Получить("Content-Type"), "image/") Тогда
    Ответ.ПолучитьТелоКакДвоичныеДанные().Записать("C:\Фото\car_hidden.jpg");
Иначе
    Сообщить(Ответ.ПолучитьТелоКакСтроку("UTF-8"));
КонецЕсли;

Бесплатных тестовых периодов и долгих согласований нет: пополните баланс в личном кабинете и сразу обрабатывайте реальные фото.

Тарификация

Оплата за каждое фото, на котором закрыто то, что вы просили: номер (target=plates), лицо (faces), номер или лицо (all). Ничего не найдено, ошибка, сервис недоступен: бесплатно. Перед обработкой проверяется, что баланса хватает на все фото запроса. Актуальная цена в личном кабинете.

В ответе JSON есть блок billing (для нескольких фото - сумма за запрос и список requestIds), те же данные в заголовках X-Charged, X-Balance, X-Request-Id. Подробнее о блоке billing.

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

Исходный файл не хранится нигде: он используется только для ответа на ваш запрос. Готовое фото (номер уже закрыт, метаданных нет) хранится 24 часа, чтобы его можно было скачать по ссылке из ответа, затем удаляется автоматически. Ссылка подписана и действует только до указанного в ней срока.

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

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

Как скрыть номер машины на фото для объявления?

Без программиста: в личном кабинете откройте "Скрыть номер и лица на фото", загрузите снимки, выберите способ и скачайте готовые фото по одному или архивом. Из своей программы или сайта: отправьте фото POST-запросом на https://api.avtovincod.ru/plate-hide с токеном (поле photo в multipart/form-data), в ответ придёт то же фото с закрытым номером.

Можно ли замазать номер на фото бесплатно?

Попробовать можно бесплатно: кнопка "Попробовать бесплатно" в кабинете (или test=1 в API) обрабатывает фото, но отдаёт его уменьшенным и с пометкой TEST. Настоящее фото в полном размере - платно, и только если номер найден и закрыт; если номера на фото нет, ничего не списывается.

Как замазать номер машины на фото: размыть или закрасить?

Оба способа есть. Размытие (mode=blur) и мозаика (mode=pixel) выглядят мягче, заливка цветом (mode=fill) и логотип (mode=logo) аккуратнее на фото для продажи. Номер закрывается по его контуру с учётом наклона, так что пятно не выходит далеко за табличку.

Можно ли поставить свой логотип на место номера?

Да. Загрузите логотип один раз (POST /plate-hide/logo или в личном кабинете) и передавайте mode=logo. Логотип ставится на табличку по контуру номера, с учётом наклона и перспективы, фон таблички задаётся параметром color.

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

До 10. В ответе JSON со ссылками на готовые фото (действуют 24 часа) или ZIP-архив, если передать format=zip.

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

За каждое фото, на котором найден и закрыт хотя бы один номер (или лицо, если вы попросили закрывать лица). Если на фото нет номера или произошла ошибка, фото бесплатное.

Что если номер не нашёлся или закрыт не там?

Передайте свои рамки параметром boxes в точках фото, как рамки в ответе (после поворота по EXIF), например [[120,340,260,380]]: номер закроется ровно там. В личном кабинете рамку можно нарисовать мышкой или пальцем.

Скрываются ли лица людей?

Да: target=all закрывает и номера, и лица (лица размываются или закрываются мозаикой или цветом, параметр faceMode), target=faces - только лица, номер остаётся. Для одних лиц есть короткий адрес /face-hide, описание на странице Размытие лиц на фото.

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

Исходный файл не хранится нигде. Готовое фото (номер уже закрыт, метаданных нет) держим 24 часа, чтобы его можно было скачать по ссылке из ответа, затем оно удаляется автоматически.

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

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

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