Быстрый старт¶
Сквозной сценарий: от регистрации до готового фото. Каждый шаг — реальный вызов
/v1. Скопируй и выполни по порядку.
1. Получить токены¶
Регистрация выдаёт сразу пару токенов и приветственные кредиты на баланс.
curl -s -X POST "$BASE_URL/v1/auth/register" \
-H 'Content-Type: application/json' \
-d '{"email":"demo@example.com","password":"s3cret-pass","name":"Demo"}'
{
"access_token": "eyJhbGci...",
"refresh_token": "9f2c...",
"expires_in": 900,
"user": { "id": "…", "email": "demo@example.com", "locale": "ru", "balance": 50 }
}
Сохрани access_token — он идёт в каждый защищённый запрос:
Уже есть аккаунт
Используй POST /v1/auth/login с теми же полями email/password, либо вход
через Google / Apple / VK ID / Яндекс ID — см. Аутентификация.
2. Выбрать эффект¶
Каталог публичный, токен не нужен. У каждого эффекта есть id и cost (в кредитах).
{
"items": [
{ "id": "1a2b3c4d-…", "slug": "anime", "name": "Аниме", "cost": 5,
"preview_url": "https://…/anime.jpg" }
],
"total": 42, "limit": 5, "offset": 0
}
3. Проверить баланс (необязательно)¶
curl -s "$BASE_URL/v1/credits/balance" -H "Authorization: Bearer $TOKEN"
# {"balance": 50, "plan_credits": 0, "plan_expires_at": null}
Если кредитов меньше, чем cost эффекта, шаг 5 вернёт 402 insufficient_credits.
4. Загрузить фото¶
Загрузка двухшаговая: сначала просим подписанную форму (presigned POST), потом льём байты напрямую в хранилище (не через API). Подробности и подводные камни — Загрузка фото.
# 4a. Запросить форму загрузки
curl -s -X POST "$BASE_URL/v1/uploads" \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"content_type":"image/jpeg"}'
{
"upload_id": "b3f1c2a4-…",
"url": "https://…/uploads",
"fields": { "Content-Type": "image/jpeg", "key": "…", "policy": "…", "x-amz-…": "…" },
"expires_in": 600
}
# 4b. Залить файл: multipart-POST на url — все fields как есть, файл полем file ПОСЛЕДНИМ.
curl -s -X POST "<url>" \
-F 'Content-Type=<из fields>' -F 'key=<из fields>' -F 'policy=<из fields>' \
-F 'x-amz-algorithm=<из fields>' -F 'x-amz-credential=<из fields>' \
-F 'x-amz-date=<из fields>' -F 'x-amz-signature=<из fields>' \
-F 'file=@photo.jpg'
export UPLOAD_ID=b3f1c2a4-…
5. Создать генерацию → 202¶
curl -s -X POST "$BASE_URL/v1/generations" \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d "{\"effect_id\":\"$EFFECT_ID\",\"characters\":[[\"$UPLOAD_ID\"]]}"
cost уже зарезервирован с баланса. id — ручка задачи на следующий шаг.
В приложении шли этот запрос с заголовком Idempotency-Key: если ответ не дошёл, повтор
с тем же ключом вернёт ту же генерацию и не спишет кредиты второй раз
(подробнее).
6. Дождаться результата (SSE) и забрать фото¶
Подписываемся на статус — стрим присылает события сам, поллить не нужно:
event: status
data: {"id":"7c9e…","status":"processing","error_code":null}
event: status
data: {"id":"7c9e…","status":"succeeded","error_code":null}
Как только статус стал succeeded — забираем деталь с готовой картинкой:
{
"id": "7c9e…", "status": "succeeded",
"effect": { "id": "1a2b3c4d-…", "name": "Аниме", "slug": "anime" },
"result_url": "https://…/results/…&X-Amz-Signature=…",
"created_at": "2026-06-03T10:00:00Z", "completed_at": "2026-06-03T10:00:08Z"
}
result_url — presigned-ссылка на готовое фото (живёт около часа; если протухла,
просто запроси деталь ещё раз).
Готово
Это весь happy-path. Дальше: как устроен жизненный цикл и realtime, что делать на ошибках и как получать готовность push'ем вместо открытого SSE.