Skip to main content
Send "async": true with a generation request to get an answer right away instead of waiting for the result. Poll the request’s status_url until its status is COMPLETED, then fetch the result from its response_url. Use async for long generations, or when your client can’t hold a connection open for minutes, such as behind a proxy or a serverless function with a short timeout. Without async, the request waits & returns the result in the same response. These endpoints accept async:

Send the Request

cURL
Response (202)
The request is checked & charged before this response, the same as without async. Errors at this point, such as VALIDATION_ERROR, INSUFFICIENT_CREDITS or INVALID_IMAGE, come back on this request with their usual HTTP status, & any charge for them is refunded. The request_id is also sent as the X-Request-Id header.

Poll the Status

Call GET on the status_url every few seconds until status is COMPLETED. See Get request status.
IN_QUEUE (202)
IN_PROGRESS (202)
COMPLETED (200)
A failed request is COMPLETED too, with an error. Its charge is refunded.
COMPLETED with error (200)
Polling doesn’t count against your concurrency limit.

Fetch the Result

Once the status is COMPLETED, call GET on the response_url. See Get request result. The result is exactly what the request returns without async: the same body with the same HTTP status.
Success (200)
A failed request returns the standard error body with the HTTP status it failed with, such as 400 for CONTENT_POLICY, 500 for GENERATION_FAILED or 504 for GENERATION_TIMEOUT. error.code is the code the request would have returned without async, & the charge is refunded.
Failure (500)
Fetching the result before the status is COMPLETED returns 400 with REQUEST_IN_PROGRESS. The request_id in this error belongs to the GET call itself, not to the request you’re fetching.
Too early (400)
A request that hasn’t finished an hour after you sent it fails with GENERATION_TIMEOUT & is refunded.

Full Example

Good to Know

  • An async request counts against your concurrency limit from the moment you send it until it completes or fails.
  • There are no webhooks. Poll status_url for the status.
  • Both GET endpoints also work for requests sent without async. Their status is always COMPLETED.
  • An unknown request ID, or one from another account, returns 404 with NOT_FOUND. So does the result of a request sent before October 25, 2026, which has no stored result.