Async Task Guide
Applies to **non-immediate** endpoints such as video generation, Suno music, Kling, etc.
Applies to non-immediate endpoints such as video generation, Suno music, Kling, etc.
Standard flow
1. Submit the task (POST) -> get task_id / task_batch_id 2. Poll for status (GET) -> status: pending / processing / succeed / failed 3. On a terminal state, read the result URL or artifact listjsonState machine (conceptual)
| State | Meaning |
|---|---|
| pending / processing | In progress, keep polling |
| succeed / success | Done, read the result fields |
| failed / error | Failed, check message / error |
Field names vary per platform; follow that endpoint's OpenAPI response schema in the portal.
Polling advice
- Interval: 3-10 seconds (do not hammer faster than 1 second)
- Timeout: set an overall timeout on your side (e.g. 10-30 minutes)
- Idempotency: the same
task_idcan be queried repeatedly; do not resubmit the same task unless the docs allow it
Open format vs Legacy format
Some platforms have two response shapes:
| Type | Example task ID field |
|---|---|
| Open | taskBatchId |
| Legacy | task_id inside data |
The doc metadata marks the "applicable protocol"; do not mix polling paths.
Platform topics
| Platform | Doc |
|---|---|
| VEO / unified video | VEO API reference |
| Suno | Suno API reference |
| Kling | Kling API reference |
Common errors
Collected from the getting-started guide, HTTP status codes, platform Quick Starts / OpenAPI x-error-playbook, and common async polling issues. Business failures may still return HTTP 200 with the error in JSON message / error / fail_reason — do not rely on the status code alone.
| Symptom | Likely cause | What to do |
|---|---|---|
invalid character '<' looking for beginning of value (or body starts with <) | Wrong Base URL / path; HTML login or marketing page returned | Confirm gateway host and platform prefix (e.g. /suno/..., /kling/v1/..., /v1/video/...); response must be JSON |
| 401 | Invalid/expired API Key, or missing Authorization | Use Bearer sk-...; check token status in the console |
| 403 | No permission, model limits on the token, wrong group, IP not allow-listed | Check token models / group / allow_ips |
400 / invalid_request | Missing params, wrong types, invalid JSON | Match the endpoint OpenAPI required / enum / examples |
404 / task_not_exist | Wrong path, or task_id missing / not owned by this Key | Verify path; use the ID from submit; do not mix ID fields |
| 429 | Rate limited | Back off; lower concurrency and poll interval (3–10s recommended) |
| 408 / client timeout | Submit or poll HTTP timeout too short | Raise timeout for submit; generation is async — do not wait for the final video in one request |
| 502 / 503 / 504 | Gateway or upstream unavailable / timed out | Exponential backoff; reduce concurrency or switch models at peak |
| HTTP 200 with error in body | Business failure encoded in JSON | Parse success / code / message / error; HTTP 200 ≠ generation success |
Model not found / no channel (channel_not_found) | Typo in model name, or no channel for current group/token | Match console “supported models” and token group; switch group/model if needed |
| Insufficient quota / balance | Pre-consume failed | Top up or raise token quota, then resubmit |
enum literal_error | Request-body enum (e.g. Suno mv) not in upstream allow-list | Cross-check OpenAPI enum / x-error-playbook and channel-tested values |
| Open / Legacy field mix-up | Wrong task ID field or poll path | Open often uses taskBatchId; Legacy often data.task_id; submit and poll must use the same protocol |
task_id vs clip_id mix-up (e.g. Suno) | Polled with a clip ID, or continued with a task ID | Poll with submit task_id; continue/extend with clip_id from fetch results |
| Submit OK but stuck in pending / processing | Upstream queue, channel congestion, or channel fault | Keep polling at the recommended interval; set a business timeout (e.g. 10–30 min); if stuck, contact ops with the task ID |
Task timed out (fail_reason mentions timed out, etc.) | Exceeded platform task timeout (often tens of minutes) | Read fail_reason; failed terminal state usually refunds the pre-consumed quota; avoid hammering the same failed job |
Terminal failed / error | Upstream generation failure, invalid params, moderation, etc. | Read message / error / fail_reason; adjust prompt/assets and retry |
| Reference image / asset URL expired | Temporary image-host URL expired; upstream fetch failed | Use a stable public URL, or re-host per the image host guide |
| Image-to-X / multimodal failure | Image too large, wrong MIME, unsupported format | Compress/convert per endpoint limits before submit |
| Poll path 404 or empty status | Submit and poll paths are not a matching pair (e.g. Kling task types) | Use the portal OpenAPI for that operation; pair submit + poll paths |
| Duplicate submit of the same job | Client timeout + blind retry → extra charge / extra tasks | Prefer reusing an existing task_id; resubmit only when docs allow |
For platform-specific playbooks see each OpenAPI x-error-playbook, plus HTTP status codes.
