Skip to main content

Error response format

Errors return a JSON body with an error object and an appropriate HTTP status:
{
  "error": {
    "message": "Invalid API key provided",
    "type": "authentication_error",
    "code": null,
    "param": null
  }
}
The type field is the machine-readable discriminator. Common values:
typeWhen
authentication_errorMissing or invalid API key (401).
invalid_request_errorMalformed body or an unsupported parameter (400).
model_not_foundThe model id is not available (400).
upstream_errorThe upstream provider is unavailable (502).

Status codes

StatusMeaning
400Bad request (invalid parameters or unknown model)
401Unauthorized (missing or invalid API key)
403Forbidden (for example, insufficient credits)
429Rate limit exceeded
500Server error
502Upstream provider unavailable
503Service temporarily unavailable

Handle errors with the SDK

OpenAI client libraries map these statuses to typed exceptions:
Python
import os, time
from openai import OpenAI, AuthenticationError, RateLimitError, APIError

client = OpenAI(base_url="https://api.redpill.ai/v1", api_key=os.environ["API_KEY"])

try:
    resp = client.chat.completions.create(
        model="openai/gpt-5",
        messages=[{"role": "user", "content": "Hello"}],
    )
except AuthenticationError:
    print("Invalid API key")
except RateLimitError:
    print("Rate limited; back off and retry")
except APIError as e:
    print(f"API error {e.status_code}: {e.message}")
JavaScript
try {
  const resp = await client.chat.completions.create({
    model: "openai/gpt-5",
    messages: [{ role: "user", content: "Hello" }],
  });
} catch (error) {
  if (error.status === 401) console.error("Invalid API key");
  else if (error.status === 429) console.error("Rate limited");
  else console.error("API error:", error.message);
}

Retry transient errors

Retry 429 and 5xx responses with exponential backoff. Do not retry 400 or 401: they will fail again until you fix the request or the key.
import time
from openai import RateLimitError, APIError

def with_retry(call, max_retries=3):
    for attempt in range(max_retries):
        try:
            return call()
        except (RateLimitError, APIError) as e:
            status = getattr(e, "status_code", 500)
            if status in (429, 500, 502, 503) and attempt < max_retries - 1:
                time.sleep(2 ** attempt)
            else:
                raise

Common cases

Check the key in the dashboard, confirm the Bearer prefix, and check for stray whitespace.
The model id is not available. List valid ids with GET /v1/models. Note that model ids are prefixed, for example openai/gpt-5.
Some models reject a parameter. For example, newer OpenAI models (GPT-5, o3, o4) require max_completion_tokens instead of max_tokens. Check the model’s supported_parameters in /v1/models.
Back off and retry with exponential backoff, and reduce your request rate.
The upstream provider failed to respond. Retry, or try another model.

Best practices

  • Branch on the HTTP status and the error.type, not on the message text.
  • Retry only transient errors (429, 5xx) with backoff.
  • Keep keys in environment variables and never log them.