Skip to content

OmnAPI 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": { "orderId": "ord_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 returned taskId until it reaches a terminal state:

{
"taskId": "task_01H...",
"status": "PENDING",
"creditsRequired": 8
}

Most integrations should use the product endpoints because they give clearer request fields. POST /api/v1/tasks is available when you want to submit by model path directly:

{
"model": "producer/lyria-3-preview/generate-image",
"inputParameters": {
"prompt": "synthwave album cover, neon palms"
},
"priority": 5,
"metadata": {
"orderId": "ord_123"
}
}

Generic task creation keeps task config fields flat at the top level: priority, tags, metadata, and webhookUrl. Do not send a top-level config wrapper on /api/v1/tasks; module endpoints use config because their own generation fields already occupy the top level.

Where a short blocking call is useful, use POST /api/v1/tasks/sync with the same body shape as POST /api/v1/tasks. A sync call waits up to the server-side 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
}

EndpointUse when
GET /api/v1/tasksList recent tasks for your account or key. Use query filters from the API Reference for status/date pagination.
GET /api/v1/tasks/{taskId}Read one task descriptor. This is the canonical poll endpoint.
POST /api/v1/tasks/{taskId}/cancelRequest cancellation for an active task when the API key has cancel scope. Pre-submit work can be cancelled immediately; post-submit work requires explicit Provider confirmation.
GET /api/v1/tasks/{taskId}/streamSubscribe to server-sent task status events instead of polling. Still handle reconnects and terminal-state reads.

The task list returns a customer-safe pricing summary with the quote version and final billed components (key, label, and credits). It does not expose internal pricing limits, pricing-rule configuration, or provider/model availability flags. Use creditsRequired and creditsCharged for the task totals, and the pricing.components array when you need the itemized final amount.

Cancellation is bounded by the Provider submission fence:

  • Before the Provider request starts, a successful 200 response atomically marks the task CANCELLED, refunds its exact reserved units, and removes the inactive queue job.
  • After submission starts, OmnAPI cancels and refunds only when the Provider explicitly confirms remote cancellation.
  • If submission outcome is unknown, the Provider does not support confirmed cancellation, or cancellation times out/fails, the API returns 409 CONFLICT. The task remains active, is not refunded, and must continue to be polled. Direct Suno, Producer, and MV tasks currently follow this rule after submission.

Treat only 200 with success: true as a settled cancellation. On 409, read details.cancellationReason for the diagnostic reason and continue polling the original task. This prevents an already accepted Provider job from completing for free after a local-only cancellation.

For webhook delivery, prefer Webhook Events on production backends. SSE is useful for user-facing dashboards and short-lived interactive sessions. Because the stream endpoint requires x-api-key, browser clients should use fetch streaming or a backend proxy rather than native EventSource, which cannot set custom headers.


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; eligible credits refunded unless partial output was billable.
CANCELLEDCancelled before completion; eligible 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",
"inputParameters": { "prompt": "..." },
"creditsRequired": 8,
"creditsCharged": 8,
"refunded": false,
"retryable": false,
"warningCodes": [],
"resources": [
{
"id": "res_01H...",
"type": "image",
"url": "https://cdn.omnapi.com/...",
"contentType": "image/png"
}
],
"outputResults": { /* endpoint-specific, informational */ },
"errorCode": null,
"errorMessage": null,
"createdAt": "2026-05-23T10:00:00Z",
"updatedAt": "2026-05-23T10:00:18Z"
}
  • resources is the normalized, cross-module output array ({ id, type, url, contentType, ...metadata }). Prefer it when wiring downstream code. type is image / audio / video / text.
  • outputResults carries endpoint-specific details — treat it as informational.
  • inputParameters can echo request inputs for debugging and audit trails; avoid sending secrets or sensitive personal data in task requests.
  • creditsRequired is deducted when the task is created.
  • creditsCharged is the final billed amount after completion, failure, cancellation, or partial output handling; see Credits & Billing.
  • refunded is the final refund signal; retryable is the service’s terminal retry recommendation.
  • Signed resources may include urlExpiresAt, retainedUntil, and assetStatus. Refresh the task to renew a URL and copy durable assets before retainedUntil. urlExpiresAt will never be later than retainedUntil.
  • Provider-account ids, tokens, viewer controls, and raw provider job ids are not part of the public task contract.

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.