Reference
Errors
Errors are always JSON, with a single top-level error object containing a human-readable message. 429 responses also include a rate_limit sub-object.
Status codes
| Status | Meaning |
|---|---|
400 | Bad request — invalid JSON body, missing/unknown model, missing prompt, bad bucket, or unfetchable image input. |
401 | Missing or invalid Bearer token. |
403 | API key suspended. |
429 | Free quota exhausted and no usable bring-your-own-key fallback. Includes a rate_limit with next_available_at. |
500 | Server-side issue. Safe to retry after a short backoff. |
502 | Upstream model returned no image or an unparseable response. Safe to retry. |
Error shape
{
"error": {
"message": "'prompt' is required"
}
}For rate-limit errors:
{
"error": {
"message": "Daily free image limit reached (20/24h). Add your own OpenAI API key in the dashboard to continue, or try again later.",
"rate_limit": {
"limit": 20,
"used": 20,
"remaining": 0,
"next_available_at": 1778920200
}
}
}Handling errors
const res = await fetch(url, options);
const json = await res.json();
if (!res.ok) {
if (res.status === 429) {
const wait = json.error.rate_limit.next_available_at * 1000 - Date.now();
console.warn(`Rate limited. Next slot in ${Math.ceil(wait / 60000)} min.`);
}
throw new Error(json.error?.message ?? `HTTP ${res.status}`);
}