Errors and Status Codes

How the API reports errors, what each HTTP status means, and when to retry

Every EmpirioLabs API endpoint returns standard HTTP status codes with an OpenAI-compatible error body. This page explains the status codes you may see and how to handle each one.

Error response shape

A failed request returns a JSON body with an error object:

1{
2 "error": {
3 "message": "A human-readable description of what went wrong.",
4 "type": "invalid_request_error",
5 "code": "insufficient_credits",
6 "param": null
7 }
8}

Every response also includes an x-request-id header. Include that value when you contact support so we can locate the exact request.

Status codes

StatusMeaningWhat to do
200 OKThe request succeeded. For async media, a job is returned.Continue. For async jobs, poll the returned job_id.
202 AcceptedAn async job was accepted.Poll GET /v1/jobs/{job_id} until it reaches a terminal state.
400 Bad RequestThe request was malformed or rejected before any work ran: invalid JSON, a missing or invalid parameter, an endpoint the model does not support, or a prompt blocked by the content policy. Not billed.Fix the request and resend. Do not retry unchanged.
401 UnauthorizedThe API key is missing, malformed, or not found.Verify the Authorization: Bearer sk-empiriolabs-... header and that the key exists in your dashboard.
402 Payment RequiredThe account has insufficient credits.Add credits on the dashboard Billing page.
404 Not FoundThe resource does not exist, for example an unknown job_id or model id.Check the id and the endpoint path.
422 Unprocessable EntityThe request was well-formed but could not be fulfilled as sent: a parameter is out of range for the model, or generated media was produced and then blocked by the output content check.Adjust the parameter or prompt. See content moderation below.
429 Too Many RequestsYou exceeded your account rate limit (default 50 requests per minute).Retry with exponential backoff and jitter, and review your request volume.
500, 502, 503, 504A transient server or model-service error.Retry with exponential backoff. If it persists, contact support with the x-request-id.

Content moderation: 400 versus 422

Content-policy rejections return one of two status codes, and the difference is whether any generation actually ran:

  • 400: the prompt was blocked before generation. Nothing was produced, so the request is not billed. Revise the prompt and try again.
  • 422: media was generated and then blocked by the output content check. Because the generation ran, the request is billed at the normal rate for that model.

In both cases the message is generic (“This request violates our content policy and could not be completed. Please revise your prompt and try again.”) and does not name a provider. Revise your input to continue.

Retrying safely

  • Retry 429 and 5xx responses with exponential backoff and jitter.
  • Do not blindly retry 400, 401, 402, or 422. They will keep failing until you change the request, key, balance, or input.
  • Async media jobs are durable. If a poll returns a transient error, keep polling the same job_id instead of resubmitting, so you are not charged twice.

For rate-limit details see Limits and API Keys. For key format and bearer-token setup see Authentication.