Jobs & polling
The unified async job model: type-prefixed ids, neutral statuses, and one poll endpoint.
Job ids
Every async endpoint returns a job with a type-prefixed id, and every job, regardless of pipeline, is polled at one dispatcher:
vid_videosong_songcode_code buildres_researchPolling requires the read or ai scope (either works), so the key that created a job can always poll it. Research additionally keeps a legacy alias at GET /research/{jobId} that accepts raw or res_-prefixed ids and returns its original response shape; prefer GET /jobs/{id}.
Statuses
Statuses are provider-neutral: queued then processing then complete or failed. The envelope also carries the pipeline's rawStatus for fidelity and an optional progressMessage.
Polling
curl https://www.opencharts.com/api/v1/jobs/vid_6870f3abc \
-H "Authorization: Bearer $OPENCHARTS_API_KEY"Completed jobs carry a result with stable, absolute asset URLs; failed jobs carry an error string. Poll every few seconds with backoff; renders can take minutes.
Results by type
{
"videoUrl": "https://www.opencharts.com/api/canvas-video/...",
"thumbnailUrl": "https://...",
"aspectRatio": "16:9",
"modelTier": "fast",
"durationSeconds": 8
}{
"title": "Neon Skyline",
"songId": "6870f4...",
"versions": [
{
"id": "a",
"audioUrl": "https://...",
"coverImageUrl": "https://...",
"durationSeconds": 172,
"engine": "Theo Symphony"
}
]
}{ "codeProjectId": "6870f5...", "name": "Landing page", "framework": "html" }{
"content": "# Report...",
"sources": [ { "url": "https://...", "title": "..." } ],
"searchCount": 14,
"readCount": 9,
"totalTokens": 48213
}Prefer webhooks
Instead of polling, register a webhook for the matching *.completed / *.failed events and receive a signed delivery the moment a job finishes. See Webhooks.