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

API удаления фона

Загружайте, обрабатывайте, редактируйте и экспортируйте изображения через API.

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

API асинхронный: отправьте изображение, получите задание, затем опрашивайте его, читайте события или примите webhook. Локальный адрес:

http://127.0.0.1:3001
curl -X POST http://127.0.0.1:3001/v1/background-removals \
  -H "Authorization: Bearer $BLANKGROUND_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Prefer: wait=8" \
  -F "image=@product.jpg" \
  -F 'format=png' \
  -F 'recipe={"version":1,"background":{"type":"transparent"}}'

Быстрое задание вернёт 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
РазмерыОт 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/background-removals

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

Multipart-параметрТипОбязательныйОписание
imagefileдаJPEG, PNG, WebP или AVIF
formatstringнетpng, webp, jpeg, zip, psd; по умолчанию png
recipeJSON stringнетВерсионируемый рецепт композиции
{
  "uploadId": "019c…",
  "format": "jpeg",
  "recipe": {
    "version": 1,
    "background": { "type": "color", "color": "#ffffff" },
    "crop": true,
    "margin": 48,
    "width": 1600,
    "height": 1600,
    "scale": 0.92,
    "positionX": 0.5,
    "positionY": 0.5,
    "quality": 92,
    "shadow": { "color": "#000000", "opacity": 0.2, "blur": 24, "distance": 14, "angle": 90 }
  }
}

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

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

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}.

POST/v1/jobs/{id}/cancel

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

GET/v1/jobs/{id}/result

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

Пакеты

POST/v1/batches

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

{
  "uploadIds": ["019c…", "019d…"],
  "format": "png",
  "recipe": { "version": 1, "background": { "type": "transparent" } }
}
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/credits
{
  "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}

Отключает доставку и удаляет 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. Соблюдайте интервал опроса.

Ошибки

{
  "error": {
    "code": "quota_exhausted",
    "message": "No full-resolution credits remain for this period.",
    "requestId": "019c…"
  }
}
HTTPКодЗначение
400invalid_inputНеверное тело, параметры, файл или размеры
401invalid_api_keyКлюч отсутствует, неверен, истёк или отозван
403insufficient_scopeНедостаточная область доступа
404job_not_foundРесурс не существует в пространстве
409idempotency_conflictКлюч повторён с другим запросом
409revision_conflictУстаревшая база версии
410expired_assetМетаданные есть, файл удалён
413image_too_largeПревышен объём или пиксели
415unsupported_mediaФормат или сигнатура не поддерживается
422unsafe_urlURL ведёт к запрещённой сети
428authorization_pendingDevice flow ждёт подтверждения
429quota_exhaustedЛимит исчерпан
500processing_failedТерминальная ошибка обработки
503processor_unavailableНет здорового обработчика

500, 502, 503, 504 можно повторять с backoff и jitter, если операция идемпотентна. Неверный ввод без изменения не повторяйте.

Примеры SDK

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

import { postV1BackgroundRemovals } from "@blankground/sdk";

const result = await postV1BackgroundRemovals({
  body: { image: file },
  headers: {
    Authorization: `Bearer ${process.env.BLANKGROUND_API_KEY}`,
    "Idempotency-Key": crypto.randomUUID(),
    Prefer: "wait=8",
  },
});
import os
from background_removal_api_client import AuthenticatedClient
from background_removal_api_client.api.jobs import post_v1_background_removals

client = AuthenticatedClient(
    base_url="http://127.0.0.1:3001",
    token=os.environ["BLANKGROUND_API_KEY"],
)

with open("product.jpg", "rb") as image:
    response = post_v1_background_removals.sync_detailed(
        client=client,
        body={"image": image},
        idempotency_key="catalog-item-184-v1",
    )

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