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
FieldTypeDescription
typerequiredstringmusic | sfx | video.
modelrequiredstringA model id for the chosen type.
promptrequiredstringWhat to generate.
durationintegerSeconds. Defaults: music 30, sfx 5, video 5.
formatstringAudio jobs: mp3 (default), etc.
modestringMusic only: DESCRIPTION (default) or LYRICS.
lyricsstringMusic only: required when mode = LYRICS.
categorystringSFX only: optional category hint.
sizestringVideo only: e.g. "1280x720".
resolutionstringVideo 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#

FieldTypeDescription
queuedstatusAccepted, not started yet.
processingstatusGeneration in progress.
completedstatusDone — output.url is available.
failedstatusGeneration failed — see error.
Poll every few seconds. Credits are charged on successful completion, so a failed job doesn't cost credits.