Skip to content

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).


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"
}
}
FieldTypeNotes
priorityint110, default 5. Higher runs sooner under contention.
tagsstring[]Up to 20 free-form labels, echoed back on read.
metadataobjectFree-form JSON, echoed back on read. Your own correlation data.
webhookUrlstring (URL)Receive task.* events for this task. See Webhook Events.

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
}

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 → 200 with the full terminal descriptor (resources / outputResults populated).
  • times out → 202 with status: "PROCESSING" and a structured pollUrl. The task is not failed — it’s still running; keep polling pollUrl (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
}

PENDING ──► PROCESSING ──► COMPLETED
├──► FAILED
└──► CANCELLED

Terminal states are COMPLETED, FAILED, CANCELLED — stop polling once you hit one. The enum is uppercase and identical across every endpoint and webhook payload.

StateMeaning
PENDINGQueued for processing.
PROCESSINGGeneration in progress (also the sync-timeout state).
COMPLETEDDone — resources and outputResults are populated.
FAILEDGeneration or validation error — errorCode + errorMessage populated; credits refunded.
CANCELLEDCancelled before completion; credits refunded.

Back off with a cap. Polling faster will not make generation complete sooner and can consume your rate-limit budget.

AttemptWait before next
160s
290s
3135s
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));
}
}

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"
}
  • resources is the normalized, cross-module output array ({ type, url, mimeType, ...metadata }). Prefer it when wiring downstream code. type is image / audio / video / text.
  • outputResults carries endpoint-specific details — treat it as informational.
  • creditsCharged may be less than creditsRequired (you’re billed for what was produced); see Credits & Billing.
  • expiresAt is when the CDN assets in resources are 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.


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:

Terminal window
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": "..." }'

  • Default soft timeout: 10 minutes. A task still running past that is marked FAILED with errorCode: "TASK_TIMEOUT" and credits are refunded. (This is distinct from a sync-wait timeout, which returns 202 + PROCESSING and 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.