Skip to main content
Generation is asynchronous. You submit a job, receive an id immediately, then poll until the job reaches a terminal state.

Lifecycle

A job moves through these statuses:
succeeded, failed, and timeout are terminal — stop polling once you see one. On succeeded, the result is available on the status response (an images array for image jobs, a video_url for video jobs, an audio_url for music and sound-effect jobs).

Create, then poll

Image, video, and audio jobs are all created at per-model endpoints (POST /v1/images/{model-name}, POST /v1/videos/{model-name}, POST /v1/audios/{model-name}), then polled at the matching status endpoint.
Job ids are opaque — treat them as strings and poll each at its own type’s status endpoint (/v1/images/{id}, /v1/videos/{id}, or /v1/audios/{id}). A reasonable polling interval is every few seconds — images and sound effects typically finish in seconds, music and video in a few minutes.

Errors

Errors share one envelope so you can branch on type and code (the exception is content moderation blocks, which use a flatter shape — see below):

Content moderation blocks

When a prompt or input image is blocked by content moderation, the request fails with 400 and a response carrying a stable restriction_reason you can branch on. The block is about the request’s content, not your account or key — reword the prompt or change the input media and retry: