Async jobs (video / image / 3d)
Some provider APIs are asynchronous: you create a job, then poll until it reaches a terminal status. The gateway proxies these natively (same paths, same payloads as the provider) and adds tenant safety and accurate billing on top.
Lifecycle
Section titled “Lifecycle”CREATE POST /<provider>/<create-path> → provider returns task_idPOLL GET /<provider>/<poll-path>/{id} → status: running | succeeded | ...CANCEL DELETE /<provider>/<path>/{id} → (where the provider supports it)LIST GET /<provider>/<list-path> → served from the gateway ledgerExample (BytePlus Seedance):
# CREATEcurl https://api.sociaro.com/byteplus/api/v3/contents/generations/tasks \ -H "Authorization: Bearer gw_live_..." \ -H "Content-Type: application/json" \ -d '{"model": "ep-m-...", "content": [{"type":"text","text":"A cat playing piano"}]}'# → {"id": "cgt-...", ...} (the provider's own response shape)
# POLL until terminalcurl https://api.sociaro.com/byteplus/api/v3/contents/generations/tasks/cgt-... \ -H "Authorization: Bearer gw_live_..."The Python SDK drives this loop for you
(client.video.generate(...) / client.video.submit(...)).
What the gateway adds
Section titled “What the gateway adds”- Tenant isolation. Every job is recorded in the gateway’s ledger.
Polling or cancelling a task that belongs to another organization returns
404— the request never reaches the provider. Provider-side LIST is never proxied (it would leak other tenants’ jobs); the gateway serves LIST from its own ledger instead. - Accurate billing. At CREATE time the job is metered with a provisional cost (from your request’s duration/resolution parameters). When the job reaches a terminal state — via your poll, your cancel, or the gateway’s background poller — the cost is finalized exactly once: succeeded jobs get the real final cost, failed/cancelled jobs are zeroed.
- Background finalization (reaper). If you stop polling, the gateway
polls the provider itself and finalizes the job, so your analytics never
show permanently “pending” spend. Jobs that can no longer be finalized are
marked
expired(e.g. after the polling TTL, or when upstream credentials were rotated mid-flight).
Job statuses
Section titled “Job statuses”| Status | Meaning | Billing |
|---|---|---|
pending | Created, not yet terminal | provisional cost |
succeeded | Completed | final cost (replaces provisional) |
failed | Provider reported failure | cost zeroed |
cancelled | Cancelled | cost zeroed |
expired | Gateway could not finalize (expiration_reason: ttl or credential_rotated) | provisional cost stands |
Inspecting your jobs
Section titled “Inspecting your jobs”Use GET /gw/async to list jobs with status,
provisional/final cost and attribution — filterable by status, kind and time
range, with cursor pagination. The same data backs the dashboard’s
Async Jobs page.
In raw usage rows (GET /gw/usage), async
requests appear with parse_status = provisional until finalization, then
ok (succeeded), failed, cancelled, or expired.