Jobs API v2
Jobs API v2 — durable интерфейс для генерации фото и редактирования. В отличие
от action-based v1, клиент получает UUID job_id, детальную phase, признак
retryable, рекомендуемый интервал следующей проверки и отдельные URL статуса,
отмены и результата.
Base URL: https://api.aidentika.com/api/v2
Все запросы используют Authorization: Bearer ak_....
Когда выбирать v2
- нужна надёжная корреляция по UUID;
- важно различать очередь, provider execution и postprocessing;
- клиент должен корректно переживать retry и временную недоступность Redis;
- нужна durable отмена с проверкой владельца.
Для карточек/инфографики, видео, funnel-сессий, списков проектов и webhooks пока используйте API v1.
Создать генерацию
POST /jobs/generate
Тело использует параметры генерации фото v1. Сейчас v2 создаёт отдельный проект
с source=api_v2 для каждого generate job; project_id и API Inbox grouping к
этому endpoint не применяются.
Такие проекты не попадают в
GET /projectsпо умолчанию: список отдаёт источникиapiиapi_inbox. Чтобы увидеть проекты v2, запрашивайтеGET /projects?source=all, а связку с результатом берите изresultстатуса job (project_id,card_id,action_id).
{
"images": [{"url": "https://example.com/product.jpg"}],
"category_id": "cosmetics",
"concept_id": "cosmetics_catalog",
"product_name": "Крем для лица",
"comment": "Мягкий свет, светлый фон",
"photo_style": "classic",
"aspect_ratio": "3:4",
"resolution": "2K",
"locale": "ru",
"webhook_url": "https://example.com/callback"
}| Поле | Обязательное | Описание |
|---|---|---|
images | да | 1–5 фото через HTTPS URL, base64 или upload_id v1 |
category_id | нет | Определяется автоматически, если не указан |
concept_id | нет | Первый концепт категории, если не указан |
product_name | нет | Определяется автоматически, если не указан |
comment | нет | Пожелания, до 5000 символов |
photo_style | нет | classic или home; по умолчанию classic |
aspect_ratio | нет | 9:16, 4:3, 1:1, 16:9, 3:4 |
resolution | нет | 1K, 2K (по умолчанию), 4K; 4K стоит на 2 искры больше |
locale | нет | ru, en, es |
webhook_url | нет | Ad-hoc HTTPS webhook |
Endpoint поддерживает Idempotency-Key. Повтор с тем же ключом и типом job
возвращает существующий durable job и не создаёт вторую генерацию.
{
"job_id": "6f9ea07b-8f63-4a83-b7c4-4f0c88415187",
"status": "queued",
"type": "generation.execute",
"status_url": "/api/v2/jobs/6f9ea07b-8f63-4a83-b7c4-4f0c88415187",
"cancel_url": "/api/v2/jobs/6f9ea07b-8f63-4a83-b7c4-4f0c88415187/cancel",
"result_url": "/api/v2/jobs/6f9ea07b-8f63-4a83-b7c4-4f0c88415187/result",
"resource_id": 789,
"first_check_after_sec": 20
}resource_id для генерации и редактирования — внутренний action_id; это не
job_id.
Создать редактирование
POST /jobs/edit
Исходный action должен принадлежать тому же аккаунту и иметь статус
completed.
{
"action_id": 789,
"instruction": "Сделай фон светлее",
"webhook_url": "https://example.com/callback"
}| Поле | Обязательное | Описание |
|---|---|---|
action_id | да | Завершённый action из v1/v2 |
instruction | да | Инструкция, до 1000 символов |
webhook_url | нет | Ad-hoc HTTPS webhook |
Endpoint также поддерживает Idempotency-Key.
Получить статус
GET /jobs/:job_id
{
"job_id": "6f9ea07b-8f63-4a83-b7c4-4f0c88415187",
"type": "generation.execute",
"status": "running",
"phase": "provider_running",
"retryable": true,
"error_code": null,
"error_message": null,
"result": null,
"resource_id": 789,
"created_at": "2026-08-12T10:00:00Z",
"started_at": "2026-08-12T10:00:03Z",
"completed_at": null,
"check_again_in_sec": 3
}Статусы
status | Значение |
|---|---|
queued | Job ожидает worker |
claimed / running | Job выполняется |
retry_scheduled | Назначена повторная попытка |
succeeded | Успешно завершён |
failed / dead_letter | Завершён ошибкой |
cancelled | Отменён |
Поле phase точнее описывает текущий этап и может принимать, среди прочих,
queued, routing, provider_reserved, provider_running, finalizing,
postprocessing, completed, failed. Список фаз может расширяться — клиент
не должен падать на неизвестном значении.
Используйте check_again_in_sec для polling. Для терминального job оно равно
null.
При успехе result содержит идентификаторы и свежую подписанную ссылку:
{
"action_id": 789,
"card_id": 456,
"project_id": 123,
"result_url": "https://...",
"result_url_expires_at": "2026-09-11T00:00:00Z"
}Отмена
POST /jobs/:job_id/cancel
{
"job_id": "6f9ea07b-8f63-4a83-b7c4-4f0c88415187",
"status": "cancelled",
"cancelled": true,
"message": "Job cancelled"
}cancelled: false с сообщением Cancel requested означает, что запрос записан,
но выполняющий worker ещё должен остановиться. Продолжайте polling статуса.
Чужой или несуществующий UUID возвращает одинаковый 404 not_found.
Получить результат
GET /jobs/:job_id/result
Для succeeded возвращает 302 Redirect на подписанный asset URL. Используйте
follow redirects (curl -L, requests по умолчанию для GET — явно включите
redirect, если библиотека его отключает).
Если результат не готов:
{
"status": "running",
"message": "Result is not ready yet"
}Полный пример
Python
import time
import requests
base = "https://api.aidentika.com/api/v2"
headers = {"Authorization": "Bearer ak_ваш_ключ"}
created = requests.post(
f"{base}/jobs/generate",
headers={**headers, "Idempotency-Key": "order-42-image-1"},
json={"images": [{"url": "https://example.com/product.jpg"}]},
).json()
job_id = created["job_id"]
time.sleep(created["first_check_after_sec"])
while True:
status = requests.get(f"{base}/jobs/{job_id}", headers=headers).json()
if status["status"] in {"succeeded", "failed", "dead_letter", "cancelled"}:
break
time.sleep(status.get("check_again_in_sec") or 3)
if status["status"] == "succeeded":
result = requests.get(f"{base}/jobs/{job_id}/result", headers=headers)
open("result.webp", "wb").write(result.content)Ошибки используют тот же формат FastAPI, что и v1.