Error Codes

All errors return a consistent JSON envelope matching the OpenAI error schema. Every response — success or failure — includes an X-Request-Id header. Quote it in any support email and we can pull the full trace.

Error format

{
  "error": {
    "type": "invalid_request_error",
    "message": "Human-readable description of the error",
    "code": "machine_readable_code",
    "param": "field_name"
  }
}

Status code map

StatusClassWhen you see itRetry?
400invalid_request_errorRequest body or parameters failed validation.No — fix the request.
401authentication_errorMissing, invalid, or revoked credentials.No — refresh credentials.
402quota_exceededCredit balance or a spend cap is exhausted.No — top up or raise the cap.
403permission_deniedAuthenticated, but not allowed (suspended org, model not enabled, IP blocked, etc.).No — fix the policy or pick another model.
404not_foundResource doesn't exist or isn't visible to you.No.
409conflictIdempotency or uniqueness collision (e.g. coupon already used).No — resolve the conflict.
422invalid_request_errorJSON parsed but fields are invalid.No — fix the request.
429rate_limit_errorPer-key RPM ceiling hit. Honour the Retry-After header.Yes, after the window.
499(informational)Client closed the connection mid-stream. Billed for tokens produced up to the disconnect.n/a
500internal_errorUnhandled server-side fault.Yes, with backoff.
503service_unavailableThe model is temporarily unavailable.Yes, after 30–60 s.

400 — validation errors

CodeWhen
model_not_foundModel name not in your catalog. Check GET /v1/models.
model_not_supported_on_endpointModel exists but doesn't support this endpoint (e.g. embeddings model on /v1/chat/completions).
invalid_roleA message has a role other than system, user, assistant, or tool.
missing_contentA message is missing required content.
max_tokens_exceededmax_tokens exceeds the model's context window.
empty_inputEmbeddings request with an empty input.
input_too_largeEmbeddings input exceeds the model's per-call token budget.
invalid_requestGeneric validation error. Check the param field.

401 — authentication errors

CodeMeaningFix
missing_auth_headerNo Authorization header.Add Authorization: Bearer sk-... (or a dashboard session token).
invalid_api_keyAPI key not recognised.Use a valid key from the dashboard.
invalid_api_key_formatToken doesn't start with sk-.Check you didn't paste a placeholder.
key_revokedThe key was revoked.Create a new key.
key_expiredThe key passed its expiry date.Create a new key or extend the expiry.
invalid_token_typeWrong token type for this endpoint.Use the access token from login, or an API key for API calls.
token_revokedSession was ended (logout or revoke).Log in again.
user_not_found / user_disabledAccount no longer active.Contact your org owner or support.
not_a_memberYou don't belong to the selected organisation.Pick a different org in the dashboard.

402 — spending limits

402 means you need to act on billing before more traffic is accepted (unlike 429, which is temporary).

CodeWhere it firesResolution
quota_exceededOrg credit balance is zero on a priced model.Top up credits or use a model with free quota.
insufficient_balanceThis request would exceed your remaining balance.Top up, lower max_tokens, or shorten the prompt.
spending_cap_reachedPer-key monthly spend cap hit.Raise the cap on the key or use a different key.
project_spend_cap_exceededPer-project monthly cap hit.Raise the cap under Projects → Limits.

Example response:

{
  "error": {
    "type": "quota_exceeded",
    "message": "Project monthly spend cap of 500.00 EGP exceeded.",
    "code": "project_spend_cap_exceeded"
  }
}

403 — policy / permission denied

CodeMeaning
org_suspendedThe organisation has been suspended. Contact support.
email_not_verifiedDashboard/playground use before email verification is complete.
permission_deniedYour role doesn't allow this action.
ip_not_allowedRequest came from an IP not on the key's allow-list.
key_scope_insufficientThe key doesn't have permission for this endpoint.
model_not_availableModel isn't on your plan or org allow-list.
model_sunsetModel has been retired. See the changelog.
model_not_enabled_for_projectModel isn't enabled for this project.
project_not_in_orgSelected project doesn't belong to the active organisation.

429 — rate limits

CodeMeaningFix
rate_limit_exceededPer-key RPM ceiling exceeded.Honour Retry-After. See Rate Limits.

500 / 503 — server errors

CodeMeaningFix
internal_errorGeneric server fault.Retry with backoff; send X-Request-Id to support if persistent.
service_unavailableService temporarily down.Retry in 30–60 s.
no_healthy_backendsModel temporarily unavailable.Retry, check status.sovereigneg.com, or switch models.
engine_unavailableModel starting up or overloaded.Retry once.

Handling errors in Python

from openai import (
    APIError,
    AuthenticationError,
    BadRequestError,
    PermissionDeniedError,
    RateLimitError,
)
 
try:
    response = client.chat.completions.create(
        model="...",  # live id from GET /v1/models
        messages=[{"role": "user", "content": "Hello"}],
    )
except AuthenticationError as e:
    print(f"Auth failed: {e.message}")
except PermissionDeniedError as e:
    print(f"Forbidden: {e.message}")
except BadRequestError as e:
    print(f"Bad request: {e.message}")
except RateLimitError as e:
    retry_after = e.response.headers.get("Retry-After", "60")
    print(f"Rate limited; retry after {retry_after}s")
except APIError as e:
    if e.status_code == 402:
        print(f"Billing block: {e.message}")
    else:
        print(f"API error ({e.status_code}): {e.message}")

Handling errors in Node.js

try {
  const response = await client.chat.completions.create({/* ... */});
} catch (error) {
  if (error instanceof OpenAI.AuthenticationError) {
    console.error(`Auth: ${error.message}`);
  } else if (error instanceof OpenAI.PermissionDeniedError) {
    console.error(`Forbidden: ${error.message}`);
  } else if (error instanceof OpenAI.BadRequestError) {
    console.error(`Validation: ${error.message}`);
  } else if (error instanceof OpenAI.RateLimitError) {
    console.error('Rate limited');
  } else if (error.status === 402) {
    console.error(`Billing block: ${error.message}`);
  } else if (error instanceof OpenAI.InternalServerError) {
    console.error('Server error — retry');
  }
}

Getting help