Skip to main content

The error object

Every error has the same shape: It appears in two places:
  • An error response wraps it with the request ID, which is also in the x-request-id header:
  • A failed generation carries it in its error field, with status: "failed":
Branch on code, never on message. code is a stable contract; message is for humans and may change at any time. New type and code values may be added in future, so handle unknown ones with a default, using retryable to decide whether to try again.

Error codes

What each code means and what to do: See Authentication and rate limits for the limits behind 429.

Retrying

retryable tells you whether the same request can succeed later. For 429, wait for the Retry-After header. For 500 and 503, retry with exponential backoff. For a failed generation, retrying means submitting a new generation with the same model and input; a generation never leaves failed.
There are no idempotency keys yet. If a POST /generations request times out on your side, you cannot tell whether the generation was created. Before submitting again, check GET /generations for a generation you just created, or accept that you may occasionally create a duplicate.

Content rejected

content_rejected means content moderation blocked the generation. stage says what was rejected:
  • input: your prompt or an input asset.
  • output: what the model produced.
A rejected generation is not charged. When the rejection comes after submission, the generation ends failed with cost.amount "0.00" and its estimate is released back to your balance. Retrying the same input will be rejected again, so change it first.

Failed generations are free

A generation that fails, for any reason, costs nothing: cost.amount is "0.00" and the estimate held at submission returns to your balance. See Billing.