Reference

Errors

The exact response body for every status, which ones are worth retrying, and how to report one so it can be looked up.

Every error from /v1 has the same shape, which is OpenAI’s:

{
  "error": {
    "message": "Insufficient balance: $0.001230 required, $0.000400 available",
    "type": "insufficient_quota",
    "param": null,
    "code": "INSUFFICIENT_BALANCE",
    "details": {
      "required_micros": 1230,
      "required_usd": 0.00123,
      "available_micros": 400,
      "available_usd": 0.0004
    }
  }
}

message is written to be read by a person. type is OpenAI’s vocabulary, which is what the SDKs branch on. code is ours, stable, and safe to switch on. param names the offending field when there is one. details is additive and only present where there is something useful to add.

Every status

StatustypeWhat it meansRetry?
400invalid_request_errorThe model does not support a parameter you sent, or you combined Idempotency-Key with stream: true. The message names itNo
401authentication_errorKey missing, malformed or revoked. Also carries WWW-AuthenticateNo
402insufficient_quotaNot enough balance. details says how much was needed and how much you hadAfter topping up
403permission_errorThe model exists but its licence forbids commercial use, so nobody can serve it. Pick another from GET /v1/modelsNo
404not_found_errorNo such model. GET /v1/models has the listNo
409invalid_request_errorAn identical Idempotency-Key is still in flight. Wait and retryYes, shortly
422invalid_request_errorThe body failed validation, or an Idempotency-Key was reused with a different body. details has the field errorsNo
429rate_limit_errorOver the limit. Retry-After says whenYes, after waiting
500api_errorOur fault. request_id is in the body; quote itYes, with backoff
502api_errorThe upstream model failed. You are not charged. Usually transientYes, with backoff

Reading one

import openai

try:
    reply = client.chat.completions.create(model="llama-3.1-8b", messages=messages)
except openai.APIStatusError as e:
    print(e.status_code)                     # 402
    print(e.message)                         # "Insufficient balance: $0.001230 required, …"
    print(e.body["error"]["type"])           # "insufficient_quota"
    print(e.response.headers["x-request-id"])
import OpenAI from "openai";

try {
  await client.chat.completions.create({ model: "llama-3.1-8b", messages });
} catch (err) {
  if (err instanceof OpenAI.APIError) {
    console.log(err.status, err.message, err.type, err.headers["x-request-id"]);
  }
}

Report an error

Every response carries x-request-id, and /v1/chat/completions also returns it as dawnstack.request_id in the body. Quote it. See Request ids.

A note on the dashboard surface

/api/v1/* uses a different envelope, {"ok": false, "error": {...}}. That is the dashboard’s own contract, it is not part of the public API, and you should not write against it.