CreativeLab API v2: бейне, сурет және музыка үшін бір эндпоинт

CreativeLab API v2: бейне, сурет және музыка үшін бір эндпоинт

v1-де генерация баптаулары модель идентификаторының ішінде тұратын. Бес секундтық 1080p бейне керек пе — seedance-1-pro-1080P-5s аласың. Дәл сол бес секунд, бірақ 720p керек пе — бұл басқа id, оны әуелі каталогтан табу керек. Рұқсат, ұзақтық және сапа бір-біріне көбейтіліп, каталог өсті, ал интеграция «пайдаланушы баптаулары → id жолы» деген сәйкестік кестесіне айналды.

Біз медиа-API-ді қайта жаздық. v2 — ескі әдістерге арналған жаңа мекенжайлар емес, басқа келісімшарт: параметрлер сұраныс денесіне көшті, бағаны генерацияға дейін білуге болады, ал желілік таймаудтан кейінгі ретрай енді екінші тапсырма құрмайды. v1 сол кілтпен жұмысын жалғастырады, бірақ ол тоқтатылған: жаңа мүмкіндіктер тек v2-де шығады.

Тирлерді іздеудің орнына бір сұраныс

JSON
// v1: баптаулар id ішіне тігілген, өзгертетін ештеңе жоқ
POST https://gptunnel.ru/v1/media/create
{ "model": "seedance-1-pro-1080P-5s", "prompt": "cat", "ar": "16:9" }
JSON
// v2: базалық модель, баптаулар params ішінде
POST https://gptunnel.ru/api/v2/media/tasks
{
  "model": "seedance-1-pro",
  "prompt": "cat",
  "params": { "aspect_ratio": "16:9", "resolution": "1080P", "duration": 5 }
}

Айырмашылық сырттай ғана емес. v1 сұраныстан тек жақтар қатынасын (ar) оқиды, қалғанының бәрі модельдің әдепкі мәндерінен алынады — сондықтан модель істей алатын нәрсенің бір бөлігі v1 арқылы қолжетімсіз. seedance-1-pro-1080P-5s сияқты тирлік id-лер v2 каталогында мүлде пайда болмайды: онда базалық модель мен оның параметрлер тізімі тұрады.

Базалық URL https://gptunnel.ru/v1/media дегеннен https://gptunnel.ru/api/v2/media дегенге ауысады. Кілт те, Authorization тақырыбы да сол күйінде, жаңасын алудың қажеті жоқ.

Параметрлер сұлбасын каталогтың өзі береді

Нақты модель нені қабылдайтынын болжаудың керегі жоқ — ол машинамен оқылатын түрде сипатталған:

bash
curl https://gptunnel.ru/api/v2/media/models \
  -H 'Authorization: YOUR_API_KEY'
JSON
{
  "id": "kling-v3",
  "type": "VIDEO",
  "price": 210,
  "prompt": "required",
  "params": [
    { "key": "resolution", "type": "enum", "default": "1080p",
      "options": [{ "value": "720p" }, { "value": "1080p" }] },
    { "key": "duration", "type": "number", "default": 5,
      "min": 5, "max": 10, "step": 5, "integer": true, "unit": "s" }
  ],
  "inputs": [
    { "key": "image", "kind": "image", "role": "first_frame",
      "required": false, "count": { "min": 0, "max": 1 },
      "formats": ["jpg", "png", "webp"] }
  ]
}

Осы жауап бойынша өз интерфейсіңдегі баптаулар формасын құруға болады: params нені өзің қоя алатыныңды айтады (түрі, рұқсат етілген мәндер, әдепкісі, шектеулері), inputs — модель қандай файлдарды, қай рөлге, нешеуін және қандай форматта қабылдайтынын. prompt өрісі required | optional | none мәндерімен v1-дегі ескі мәселені жабады: онда промпт қажет етпейтін модельдер үшін де міндетті болатын.

Бір нәрсені бөлек есте ұстаған жөн: params ішінде клиенттің өзі қоюға құқылы нәрсе ғана жарияланады. Модельдің бекітілген мәнді параметрлері де болуы мүмкін — олар тапсырма нысанында және баға есебінде көрінеді, бірақ өзгертілмейді.

Баға — есептен шығарудан кейін емес, генерацияға дейін

Баға тек модельге емес, параметрлерге де байланысты: бейненің секундтары, рұқсат, сапа. v1-де каталогта әр id-ге бір баға тұратын, ал нақты комбинацияны есептейтін жер жоқ еді.

POST /api/v2/media/price тапсырма құрудағыдай { model, params } жұбын қабылдайды және ештеңені іске қоспай, есептен шығармай, қорытынды соманы қайтарады:

JSON
{ "code": 0, "model": "kling-v3", "price": 210,
  "params": { "resolution": "1080p", "duration": 5, "aspect_ratio": "16:9" } }

Баға нақты есептен шығарумен бірдей функциямен саналады, сондықтан «бірін санап, екіншісін алу» мұнда мүмкін емес. Екі практикалық салдары бар. Біріншісі: жауаптағы params — қолданылған мәндер, яғни жіберілгені плюс әдепкілер мен модельдің бекітілген параметрлері; жіберген параметрің жауапта жоқ болса, ол бапталмайды дегенді білдіреді. Екіншісі: осы сұраныспен нақты шақыруға дейін сұраныс денесін тексеру ыңғайлы — валидация сол, бірақ ақшасыз. Бір ескерту: промпт немесе кіріс файлдары бойынша да (токендер, мегапикселдер) тарификацияланатын модельдер бағаны сол бөлігінсіз қайтарады.

Ретрай енді ақша тұрмайды

Классикалық сценарий: клиент желілік таймаут алды, сұранысты қайталады, тапсырма екі рет құрылды, ақша екі рет шешілді. Енді тапсырма құруда idempotency_key бар:

JSON
POST /api/v2/media/tasks
{
  "model": "seedance-1-pro",
  "prompt": "cat",
  "params": { "aspect_ratio": "16:9", "resolution": "1080P", "duration": 5 },
  "idempotency_key": "order-1042",
  "webhook_url": "https://your.app/hooks/media"
}

Сол кілтпен қайталау сол тапсырманы қайтарады. Ал сол кілт басқа денемен келсе, жауап үнсіз дубль емес, 409 (code: 23) болады: сервер тек кілтті емес, сұраныстың хешін салыстырады.

Кілт бизнес-операцияға байлануы керек — тапсырыс id-і, хабарлама id-і, кезектегі жол id-і, — әр әрекетте қайта генерацияланбауы тиіс. Әр ретрайға кездейсоқ кілт ешнәрседен қорғамайды.

Үш түрлі жауап пішінінің орнына бір тапсырма нысаны

POST /api/v2/media/tasks кез келген медиа-модель үшін тапсырма құрады, әрі жауап бәрінде бірдей: id, status (queued | running | done | failed), params, price, result. Дәл сол нысанды GET /api/v2/media/tasks/:id қайтарады және дәл сол webhook-қа кетеді. v1-де жауап пішіні модель тұқымдасына байланысты еді: кәдімгі генерацияларда нәтиже url ішінде жол болып келетін, музыкада — өз өріс атаулары бар массив, ал кейбір модельдер мүлде бөлек тармақтарда тұратын.

Көшіру кезіндегі басты тұзақ — result[0] оқу. v2-де result әрқашан массив, әрі онда бір файлдан көп болуы мүмкін: бірнеше шығысы бар модельдер бәрін қайтарады, ал музыкалық модельдер (Suno, Mureka, MiniMax) тректерді береді, әрқайсысының өз url, title, duration, cover_url және lyric өрістері бар.

JavaScript
if (task.status === 'done') {
  for (const item of task.result) save(item.url)
}

Жылдам модельдер үшін қысқа синхронды режим бар: тапсырма құру денесіндегі wait: true дайын болғанша қосылымды ұстап тұрып, соңғы нысанды бірден береді. Күту шамамен 30 секундпен шектелген; үлгермесе — ағымдағы күйдегі тапсырма қайтады, нәтижені әдеттегідей аласың. Алты секундта салынатын сурет үшін поллинг жазудың қажеті жоқ. Бейне үшін wait-қа сүйенудің мәні жоқ — онда webhook немесе сұрау салу. v1-де синхронды режим бөлек /v1/media/generate эндпоинті болатын және дәл бір модельмен жұмыс істейтін.

Қателер: тармақталуға арналған код, дәлдік үшін title

Сәтті болғанда HTTP-статус 200, ал code — нөл; қате болғанда мағыналы статус және денеде машинамен оқылатын code келеді. Кодтар каталогы кеңейді: 20 — модель табылмады, 22 — тапсырма табылмады, 23 — идемпотенттілік қақтығысы, 25 — кіріс файлы қабылданбады, 26 — промпт қабылданбады, 27 — параметрлер комбинациясына қолдау жоқ, 28 — уақытша ақау, қайталаудың мәні бар. v1-мен ортақ кодтар (3, 5, 99, 1001) мағынасын сақтады — бар өңдеушілерді жаңа нөмірлеуге ауыстырудың қажеті жоқ.

Бұрын бас тарту себебі әрдайым дерлік code: 1 болып келетін: каталогта қырықтан асатын себептің бесеуі ғана болды, қалғаны «ішкі қатеге» жиналатын. Енді бас тартудың коды бар, ал қасында — error.title, себептің дәл машиналық идентификаторы: ERR_IMAGE_TOO_LARGE мен ERR_UNSUPPORTED_FILE_FORMAT екеуі де code: 25 береді, бірақ title бойынша ажыратылады. Жаңа себептер кодтар кестесін өзгертпей title ішіне қосылады, сондықтан продта соның бойынша тармақталған сенімдірек. Ішкі қателер trace_id алып жүреді — онымен қолдау қызметі сұранысты бірден табады.

Егер код status: failed кезінде error.code бойынша тармақталса, өңдеушілерді қайта қарап шық: бұрын 1 болып келген бас тартулардың бір бөлігі енді 2528, 1001 немесе 1002 болып келеді.

Кодта нені өзгерту керек

v1-де болғаныv2-де болғаны
POST /v1/media/createPOST /api/v2/media/tasks
GET /v1/media/result?task_id=…GET /api/v2/media/tasks/:id
GET /v1/media/modelsGET /api/v2/media/models
POST /v1/media/generate (бір ғана модель)тапсырма құру денесіндегі wait: true
POST /api/v2/media/price
ar: "16:9"params.aspect_ratio (атауы — модель сұлбасынан)
images: ["https://…"]inputs: { "<role>": ["https://…"] }
callback_urlwebhook_url
жауаптағы urlresult[].url
тапсырма түбіріндегі code/messageerror.code, error.title, error.message
каталогтағы modelrationmoderation

Қатаңдыққа қатысты бөлек түзету. v2-де сұраныс денесі қатаң валидацияланады: жоғарғы деңгейдегі белгісіз өріс code: 3 қатесімен қабылданбайды, ал оның атауы details ішінде тізіледі. Бұл — дәл сол жағдай, онда idempotency_key орнына жазылған idempotencyKey қос есептен шығарудан қорғанысты үнсіз өшіретін, ал v1-ден қалып қойған ar жақтар қатынасын әдепкімен алмастыратын — және бәрі 200 OK жауап беретін. params ішінде ереже жұмсақ: модель білмейтін кілт сұранысты құлатпайды, ол себебімен бірге ignored_params ішінде қайтады. Қате болып қалатыны — модель қабылдайтын параметрдің жарамсыз мәні: шегі 10 болғанда duration: 999 үнсіз ауыстыру емес, 400 береді.

Продта нені есте ұстау керек

  • Нәтиже сілтемелері 48 сағат жасайды. Файл ұзағырақ керек болса — done болғаннан кейін бірден өзіңе жүктеп ал.
  • Webhook «кем дегенде бір рет» жеткізіледі. Сәтсіз болса, шамамен 5, 20, 60 және 180 секундтан кейін қайталаймыз, сондықтан өңдеуші тапсырманың id-і бойынша идемпотентті болуы тиіс. Қолтаңба X-Gptunnel-Signature тақырыбында t=<unix>,v1=<hex> пішімінде тұрады: бұл API-кілт құпия ретінде алынған "<t>.<шикі дене>" жолының HMAC-SHA256 мәні. Мекенжай ашық қолжетімді HTTPS болуы керек.
  • Файлдарды инлайн жіберуге болады. inputs ашық сілтемелерді де, data:-URL-ды да қабылдайды — файлға 20 МБ-қа дейін, бүкіл денеге 50 МБ-қа дейін. Бүлінген файл тапсырма құрылғанға және ақша шешілгенге дейін code: 25 қатесімен қабылданбайды.
  • Автоматты түрде қайталауға тұратын жалғыз код — 28. Қалған 4xx жауаптарын қайталаудың мәні жоқ: жауап өзгермейді.
  • Қызметтен алынған модельдер интеграцияны бұзбайды. Алынуы жарияланған модельде каталогта deprecated_at және deprecation_redirect_to бар. Сол күннен кейін тапсырма аналогта автоматты орындалады, ақша сұралған модель бойынша шешіледі, ал алмастыру туралы Deprecation, Sunset, x-model-requested, x-model-served тақырыптары айтады. Аналог болмаса, құру 410 және code: 21 қайтарады.

Көшуді бөліктеп жасауға болады: v1 мен v2 бір кілтте қатар жұмыс істейді, сондықтан бір сценарийді ауыстырып, метрикаға қарап, әрі қарай жалғастыру дұрыс.

Толық спецификация құжаттамада: CreativeLab API туралы, Модельдер тізімі, Тапсырма құру, Баға есебі, Webhooks және Қателер анықтамалығы.