The Task Model
Every generation on OmnAPI — image, lyrics, music, music video — is a task.
Whatever endpoint you call, you get back the same task descriptor, poll the
same GET /api/v1/tasks/{taskId}, read the same status enum, and consume the
same resources[]. Learn it once here; each module guide
(Producer, Suno, MV) then
only documents its own inputs and outputs.
Authentication is the same everywhere: the x-api-key header (see
Authentication).
The request config
Section titled “The request config”Every task-creating endpoint accepts an optional, identical config object for
cross-cutting task settings. It is the same shape on every endpoint — never
module-specific:
{ "config": { "priority": 5, "tags": ["alpha", "experiment-7"], "metadata": { "userId": "u_123", "source": "my-app" }, "webhookUrl": "https://yourapp.com/callbacks/omnapi" }}| Field | Type | Notes |
|---|---|---|
priority | int | 1–10, default 5. Higher runs sooner under contention. |
tags | string[] | Up to 20 free-form labels, echoed back on read. |
metadata | object | Free-form JSON, echoed back on read. Your own correlation data. |
webhookUrl | string (URL) | Receive task.* events for this task. See Webhook Events. |
Running a task: async (default) vs sync
Section titled “Running a task: async (default) vs sync”Async (the default)
Section titled “Async (the default)”Module create endpoints (e.g. POST /api/v1/producer/generate/image,
POST /api/v1/suno/songs, POST /api/v1/mv) return immediately with a
descriptor in a non-terminal state — poll the taskId until it’s terminal:
{ "taskId": "task_01H...", "status": "PENDING", "creditsRequired": 8}Sync (block for the result)
Section titled “Sync (block for the result)”Where a short blocking call is useful, an endpoint offers a synchronous
variant — the generic POST /api/v1/tasks/sync, or a purpose-built one like
POST /api/v1/lyrics/generate. A sync call waits up to a timeout and then:
- completes in time →
200with the full terminal descriptor (resources/outputResultspopulated). - times out →
202withstatus: "PROCESSING"and a structuredpollUrl. The task is not failed — it’s still running; keep pollingpollUrl(which is/api/v1/tasks/{taskId}).
// 202 Accepted — the wait timed out, the task is still running{ "taskId": "task_01H...", "status": "PROCESSING", "pollUrl": "/api/v1/tasks/task_01H...", "creditsRequired": 12}Status lifecycle
Section titled “Status lifecycle”PENDING ──► PROCESSING ──► COMPLETED │ ├──► FAILED │ └──► CANCELLEDTerminal states are COMPLETED, FAILED, CANCELLED — stop
polling once you hit one. The enum is uppercase and identical across every
endpoint and webhook payload.
| State | Meaning |
|---|---|
PENDING | Queued for processing. |
PROCESSING | Generation in progress (also the sync-timeout state). |
COMPLETED | Done — resources and outputResults are populated. |
FAILED | Generation or validation error — errorCode + errorMessage populated; credits refunded. |
CANCELLED | Cancelled before completion; credits refunded. |
Polling
Section titled “Polling”Back off with a cap. Polling faster will not make generation complete sooner and can consume your rate-limit budget.
| Attempt | Wait before next |
|---|---|
| 1 | 60s |
| 2 | 90s |
| 3 | 135s |
| 4+ | 180s (capped) |
async function pollTask(taskId: string, apiKey: string) { const waits = [60, 90, 135, 180]; // seconds for (let i = 0; ; i++) { const r = await fetch(`https://api.omnapi.com/api/v1/tasks/${taskId}`, { headers: { "x-api-key": apiKey }, }); const task = await r.json(); if (["COMPLETED", "FAILED", "CANCELLED"].includes(task.status)) return task; const wait = waits[Math.min(i, waits.length - 1)]; await new Promise((res) => setTimeout(res, wait * 1000)); }}Task descriptor & resources
Section titled “Task descriptor & resources”GET /api/v1/tasks/{taskId} returns the canonical descriptor:
{ "taskId": "task_01H...", "status": "COMPLETED", "model": "producer/lyria-3-preview/generate-image", "inputParameters": { "prompt": "..." }, "creditsRequired": 8, "creditsCharged": 8, "resources": [ { "type": "image", "url": "https://cdn.omnapi.com/...", "mimeType": "image/png" } ], "outputResults": { /* endpoint-specific, informational */ }, "errorCode": null, "errorMessage": null, "createdAt": "2026-05-23T10:00:00Z", "updatedAt": "2026-05-23T10:00:18Z", "expiresAt": "2026-06-23T10:00:18Z"}resourcesis the normalized, cross-module output array ({ type, url, mimeType, ...metadata }). Prefer it when wiring downstream code.typeisimage/audio/video/text.outputResultscarries endpoint-specific details — treat it as informational.creditsChargedmay be less thancreditsRequired(you’re billed for what was produced); see Credits & Billing.expiresAtis when the CDN assets inresourcesare garbage-collected — copy them to your own storage before then.
For the exhaustive field shapes of every public request and response, use the Interactive API Reference.
Idempotency
Section titled “Idempotency”Any paid create endpoint accepts an Idempotency-Key header. Reusing the
same key for the same request (within the retention window) replays the
original response instead of creating — and charging for — a second task. Send
a fresh UUID per logical operation, and reuse it when you retry after a network
timeout:
curl -X POST https://api.omnapi.com/api/v1/producer/generate/image \ -H "x-api-key: sk_live_..." \ -H "Idempotency-Key: 7d3a1f2e-..." \ -H "Content-Type: application/json" \ -d '{ "prompt": "..." }'Timeouts
Section titled “Timeouts”- Default soft timeout: 10 minutes. A task still running past that is marked
FAILEDwitherrorCode: "TASK_TIMEOUT"and credits are refunded. (This is distinct from a sync-wait timeout, which returns202+PROCESSINGand does not fail the task.) - Typical wall-clock latencies: image 10–30s · lyrics 5–15s · music compose 60–120s · music modify 30–90s · MV studio 3–10min.
See also
Section titled “See also”- Webhook Events — push delivery of
task.*(and per-stage) events instead of polling. - Errors — the error envelope + the full code reference.
- Credits & Billing — pricing, reservation vs settlement, refunds.
- Rate Limits — current per-IP limits +
Retry-After. - Interactive API Reference — OpenAPI-generated field shapes.