РАЗРАБОТЧИКАМ / API V1

API изображений

Удаляйте фон и создавайте каталожные изображения через единый production API.

Быстрый старт

Удаление фона работает асинхронно. Генерация каталожного изображения синхронно возвращает сохранённый PNG. Production URL:

https://api.blankground.ru
curl -X POST https://api.blankground.ru/v1/removals \
  -H "Authorization: Bearer $BLANKGROUND_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Prefer: wait=8" \
  -F "image=@product.jpg" \
  -F 'options={"quality":"balanced","alpha":{"mode":"raw","feather":0},"output":"cutout"}'

Быстрое задание вернёт 200 OK. Через восемь секунд вы получите 202 Accepted и адрес задания в Location.

Контракт и health checks

Метод и путьНазначение
GET /openapi.jsonКонтракт OpenAPI 3.1 для генерации SDK
GET /health/liveПроверяет, что процесс API запущен
GET /health/readyПоказывает готовность необходимых обработчиков

Авторизация

Защищённые запросы используют API-ключ:

Authorization: Bearer bg_live_••••••••••••••••••••

Секрет показывается один раз и хранится как хеш. У ключа есть права и срок. Не кладите его в браузер, URL, логи или обращения.

ScopeВозможности
images:writeЗагрузки, удаления, пакеты, уточнения и экспорты
jobs:readЗадания, события, результаты, история и кредиты
webhooks:writeУправление webhook endpoints
keys:writeУправление API-ключами

Анонимный запрос использует подписанный cookie. Полное разрешение, пакеты, ключи, webhooks и проекты требуют входа.

Общие правила запросов

Идемпотентность

Создающие endpoints требуют Idempotency-Key. Повторяйте тот же запрос с тем же ключом. Другое содержимое вернёт 409 idempotency_conflict.

Ограниченное ожидание

Prefer: wait=8 ждёт завершение не более восьми секунд. При успехе возвращается 200, иначе обычный 202.

Состояния

Состояния: queued, processing, succeeded, failed, canceled. Этапы: preparing, segmenting, refining, rendering, storing, complete.

Лимиты

ОграничениеЗначение
ВходJPEG, PNG, WebP, AVIF, HEIC, HEIF
РазмерыОт 32×32 до 25 мегапикселей
ОбъёмДо 50 МБ
ПакетДо 100 изображений
Перенаправления URLДо 5
AI-уточненияДо 20 на проект
Ссылка на результат10 минут
Хранение файлов24 часа после завершения

URL должен быть публичным HTTP/HTTPS. Частные сети, metadata services и небезопасный DNS блокируются.

Загрузки

POST/v1/uploads

Создаёт короткую загрузочную сессию. Тело не требуется.

{
  "id": "019c…",
  "uploadUrl": "/v1/uploads/019c…/content",
  "expiresAt": "2026-08-05T12:15:00.000Z"
}
PUT/v1/uploads/{id}/content

Загружает сырые байты изображения. Укажите Content-Type; сервер всё равно проверит сигнатуру и декодирует файл.

curl -X PUT "$BASE_URL/v1/uploads/$UPLOAD_ID/content" \
  -H "Authorization: Bearer $BLANKGROUND_API_KEY" \
  -H "Content-Type: image/jpeg" \
  --data-binary @product.jpg
POST/v1/uploads/{id}/complete

Завершает загрузку после проверки и возвращает подтверждённые width, height, mimeType и статус ready.

Удаление фона

POST/v1/removals

Принимает multipart с image либо JSON ровно с одним из uploadId и sourceUrl.

Multipart-параметрТипОбязательныйОписание
imagefileдаJPEG, PNG, WebP, AVIF, HEIC или HEIF
optionsJSON stringдаСтрогий объект параметров удаления
ПолеЗначенияНазначение
qualityfast, balanced, highУправляет разрешением инференса
alpha.moderaw, binaryСырая альфа модели или жёсткая маска
alpha.thresholdчисло от 0 до 1Обязательно для binary, запрещено для raw
alpha.featherчисло от 0 до 4Смягчение края в пикселях; 0 не изменяет край
outputmask, cutoutСерая PNG-маска или прозрачный PNG

Объект обязателен и не допускает лишних полей. Старые format и recipe отклоняются.

{
  "uploadId": "019c…",
  "options": {
    "quality": "high",
    "alpha": { "mode": "binary", "threshold": 0.55, "feather": 1 },
    "output": "mask"
  }
}

Ответ содержит id, projectId, status, stage, format, createdAt, result, error, warnings, links и Location: /v1/jobs/{id}.

Генерация каталожного изображения

POST/v1/catalog-images

Создаёт PNG товара по одному–четырём упорядоченным референсам и сохраняет результат в приватном MinIO. Нужен аккаунт или API-ключ со scope images:write.

curl --fail-with-body https://api.blankground.ru/v1/catalog-images \
  -H "Authorization: Bearer $BLANKGROUND_API_KEY" \
  -F "references=@front.webp" \
  -F "references=@back.webp" \
  -F "references=@detail.webp" \
  -F "prompt=Создай точное каталожное изображение товара строго спереди" \
  -F "width=768" \
  -F "height=768" \
  -F "steps=6" \
  --output catalog.png

Первым передавайте чистый вид спереди, затем вид сзади, сбоку и детали. Prompt принимает Unicode; английский обычно точнее для материалов, конструкции, света и композиции. Ответ — 201 image/png. Заголовок Location указывает на сохранённый результат, X-Catalog-Image-Id содержит ID, а X-Generation-Seed позволяет повторить генерацию.

GET/v1/catalog-images/{id}

Скачивает сохранённый PNG для того же workspace. Срок хранения — 24 часа, как у результатов удаления фона.

Задания и результаты

GET/v1/jobs/{id}

Возвращает состояние, этап, время, версию модели, результат или стабильную ошибку. Владение пространством проверяется.

GET/v1/jobs

Возвращает историю авторизованного пространства.

GET/v1/jobs/{id}/events

Поток text/event-stream. Событие содержит id, type, occurredAt, workspaceId, aggregateId, correlationId и data.

id: 019c…
event: image.job.completed.v1
data: {"id":"019c…","type":"image.job.completed.v1","data":{"jobId":"019c…"}}

После разрыва всегда сверяйтесь с GET /v1/jobs/{id}.

DELETE/v1/jobs/{id}

Ожидающее задание отменяется сразу. Активное может ненадолго остаться processing. Резерв кредита освободится.

GET/v1/jobs/{id}/result

Возвращает файл или подписанную ссылку. Удалённый файл вернёт 410 expired_asset; метаданные останутся.

Пакеты

POST/v1/batches

Создаёт до 100 заданий из завершённых uploadIds. Нужны авторизация и Idempotency-Key.

{
  "uploadIds": ["019c…", "019d…"],
  "options": {
    "quality": "balanced",
    "alpha": { "mode": "raw", "feather": 0 },
    "output": "cutout"
  }
}
GET/v1/batches/{id}

Возвращает прогресс и дочерние задания. Частичная ошибка не удаляет успешные результаты.

Проекты и редактирование

POST/v1/projects/{id}/revisions

Создаёт неизменяемую версию. baseRevisionId защищает от параллельной перезаписи; устаревшая база возвращает 409 revision_conflict.

{
  "baseRevisionId": "019c…",
  "strokes": [
    {
      "tool": "restore",
      "points": [
        [0.42, 0.17],
        [0.43, 0.18]
      ],
      "size": 0.02,
      "hardness": 0.7,
      "opacity": 1
    }
  ],
  "recipe": { "version": 1, "background": { "type": "transparent" } }
}

Координаты нормализованы к исходнику, поэтому сервер растеризует штрихи в полном разрешении.

POST/v1/projects/{id}/refinements

Ставит в очередь уточнение точками или рамкой. Оно делит общий слот, не тратит кредит и ограничено 20 попытками.

POST/v1/projects/{id}/exports

Рендерит версию в png, webp, jpeg, zip или psd с переданным рецептом. Новый кредит не списывается.

Кредиты

GET/v1/usage
{
  "kind": "workspace",
  "limit": 100,
  "available": 87,
  "held": 2,
  "used": 11,
  "periodEndsAt": "2026-09-01T00:00:00.000Z"
}

Кредит резервируется на старте, списывается после успеха и возвращается при ошибке или отмене. Анонимный ответ показывает остаток и сброс UTC.

DELETE/v1/device

Удаляет анонимный cookie браузера. Аккаунт и лимит не сбрасываются.

Вход по email

POST/v1/auth/email/start

Тело: { "email": "person@example.com" }. Отправляет одноразовый шестизначный код на десять минут.

POST/v1/auth/email/verify

Тело: { "email": "person@example.com", "code": "123456" }. Проверяет код, при необходимости создаёт личное пространство и выдаёт сессию. Пять ошибок инвалидируют challenge.

API-ключи

GET/v1/api-keys

Список метаданных: ID, имя, префикс, scopes, создание, срок и последнее использование. Секрет не возвращается.

POST/v1/api-keys
{
  "name": "Catalog production",
  "scopes": ["images:write", "jobs:read"],
  "expiresAt": "2027-01-01T00:00:00.000Z"
}

Ответ 201 показывает секрет один раз.

DELETE/v1/api-keys/{id}

Сразу отзывает ключ. Для ротации сначала создайте новый, затем удалите старый.

Webhooks

GET/v1/webhooks

Возвращает endpoints пространства без секретов подписи.

POST/v1/webhooks
{
  "url": "https://example.com/hooks/blankground",
  "events": ["image.job.completed.v1", "image.job.failed.v1"]
}

Секрет показывается один раз. Публичный URL обязан использовать HTTPS.

DELETE/v1/webhooks/{id}

Отключает доставку, сохраняя audit history.

GET/v1/webhooks/{id}/deliveries

Возвращает последние 100 попыток, HTTP-статусы и причины ошибок.

POST/v1/webhooks/{endpointId}/deliveries/{deliveryId}/replay

Ставит доставку в очередь повторно с тем же delivery ID для дедупликации.

Отключает доставку и удаляет endpoint.

Проверка подписи

Вычислите HMAC-SHA256 от строки:

{timestamp}.{deliveryId}.{rawRequestBody}

Сравнивайте подпись в constant time, отклоняйте старые timestamps и храните delivery ID. Возвращайте 2xx после надёжной записи. Повторы идут до 24 часов.

Device authorization

POST/v1/device-authorizations

Тело { "client": "photoshop" }. Возвращает deviceCode, удобный userCode, адрес подтверждения, срок и интервал опроса.

POST/v1/device-authorizations/{code}/approve

Авторизованный браузер подтверждает код и пространство. Код короткоживущий и одноразовый.

POST/v1/device-authorizations/token

Тело { "deviceCode": "…" }. До подтверждения возвращает 428 authorization_pending, после — access и refresh credentials. Соблюдайте интервал опроса.

Ошибки

{
  "type": "https://docs.blankground.ru/errors/quota-exhausted",
  "status": 402,
  "code": "quota_exhausted",
  "title": "Quota Exhausted",
  "detail": "No full-resolution credits remain for this period.",
  "retryable": false,
  "requestId": "req_019c…"
}
HTTPКодЗначение
400invalid_inputНеверное тело, параметры, файл или размеры
401invalid_api_keyКлюч отсутствует, неверен, истёк или отозван
403insufficient_scopeНедостаточная область доступа
404job_not_foundРесурс не существует в пространстве
409idempotency_conflictКлюч повторён с другим запросом
409revision_conflictУстаревшая база версии
402quota_exhaustedНет доступной ёмкости обработки
410asset_expiredМетаданные есть, файл удалён
413image_too_largeПревышен объём или пиксели
415unsupported_mediaФормат или сигнатура не поддерживается
422unsafe_urlURL ведёт к запрещённой сети
428authorization_pendingDevice flow ждёт подтверждения
429rate_limit_exceededПревышен лимит запросов или safety cap
500processing_failedТерминальная ошибка обработки
503processor_unavailableНет здорового обработчика

500, 502, 503, 504 можно повторять с backoff и jitter, если операция идемпотентна. Неверный ввод без изменения не повторяйте. Каждый ответ содержит X-Request-Id, RateLimit и RateLimit-Policy; для retryable throttling и availability ошибок также приходит Retry-After.

Примеры SDK

TypeScript и Python SDK генерируются из OpenAPI 3.1 по адресу /openapi.json.

import { Blankground } from "@bg/sdk";

const client = new Blankground(process.env.BLANKGROUND_API_KEY!);
const result = await client.remove({ image: file, waitSeconds: 8 });
import os
from blankground_api_client import AuthenticatedClient
from blankground_api_client.api.processing import create_removal
from blankground_api_client.models.create_removal_files_body import CreateRemovalFilesBody
from blankground_api_client.types import File

client = AuthenticatedClient(
    base_url="https://api.blankground.ru",
    token=os.environ["BLANKGROUND_API_KEY"],
)

with open("product.jpg", "rb") as image:
    response = create_removal.sync_detailed(
        client=client,
        body=CreateRemovalFilesBody(image=File(payload=image, file_name="product.jpg")),
        idempotency_key="catalog-item-184-v1",
        prefer="wait=8",
    )

Точные multipart-типы зависят от версии сгенерированного клиента; сверяйтесь с README конкретного SDK.