Async jobs
Longer-running generations — music, sound effects, and video — use an asynchronous create-then-poll pattern. You get a job immediately and poll it until it's done.
These surfaces don't map to a synchronous OpenAI endpoint, so they live under
/v1/jobs (the Replicate/fal style).Create a job#
POST/v1/jobs
| Field | Type | Description |
|---|---|---|
typerequired | string | music | sfx | video. |
modelrequired | string | A model id for the chosen type. |
promptrequired | string | What to generate. |
duration | integer | Seconds. Defaults: music 30, sfx 5, video 5. |
format | string | Audio jobs: mp3 (default), etc. |
mode | string | Music only: DESCRIPTION (default) or LYRICS. |
lyrics | string | Music only: required when mode = LYRICS. |
category | string | SFX only: optional category hint. |
size | string | Video only: e.g. "1280x720". |
resolution | string | Video only: e.g. "720p". |
bash
curl https://api.studio.whalli.com/v1/jobs \
-H "Authorization: Bearer $WHALLI_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "type": "music", "model": "suno-v5", "prompt": "Upbeat lo-fi beat" }'The job is created immediately:
json
{
"id": "job_music_abc123",
"object": "job",
"type": "music",
"status": "queued",
"output": null,
"error": null,
"created": 1782000000
}Poll a job#
GET/v1/jobs/{id}
Poll until status is completed or failed. The job id encodes its type, so you only need the id.
bash
curl https://api.studio.whalli.com/v1/jobs/job_music_abc123 \
-H "Authorization: Bearer $WHALLI_API_KEY"json
{
"id": "job_music_abc123",
"object": "job",
"type": "music",
"status": "completed",
"output": { "url": "https://.../track.mp3" },
"error": null
}Status values#
| Field | Type | Description |
|---|---|---|
queued | status | Accepted, not started yet. |
processing | status | Generation in progress. |
completed | status | Done — output.url is available. |
failed | status | Generation failed — see error. |
Poll every few seconds. Credits are charged on successful completion, so a failed job doesn't cost credits.