Error handling

This guide covers the error response format of the 诺玛AI, common error scenarios, and recommended handling strategies.

Error response format#

All error responses follow a unified JSON format:

Code
{
  "error": {
    "code": "invalid_api_key",
    "message": "The provided API Key is invalid. Check it and retry.",
    "type": "authentication_error"
  }
}

HTTP status codes#

Status code

Type

Description

Retry?

`400`

`invalid_request_error`

Invalid request parameters

❌ Fix parameters and retry

`401`

`authentication_error`

API Key invalid or missing

❌ Check your API Key

`403`

`permission_error`

Insufficient permissions

❌ Check account permissions

`404`

`not_found_error`

Model or resource not found

❌ Check the model ID

`429`

`rate_limit_error`

Rate limit triggered

✅ Wait and retry

`500`

`internal_error`

Internal server error

✅ Retry later

`502`

`upstream_error`

Upstream Models provider error

✅ Switch models or retry

`503`

`service_unavailable`

Service temporarily unavailable

✅ Retry later

Common errors and solutions#

401 — Invalid API Key

Code
{"error": {"code": "invalid_api_key", "message": "The API key provided is invalid."}}

Solutions:

  • Check that the API Key was copied correctly (including the `sk-` prefix)
  • Confirm the Key has not expired or been disabled
  • Check that the environment variable is loaded correctly

429 — Rate limit

Solutions:

  • Check the `x-ratelimit-reset-requests` response header
  • Implement exponential backoff retries
  • If you need a higher quota, contact support to request an adjustment

502 — Upstream error

Solutions:

  • Use fallback to automatically switch to an alternate Models
  • Retry later
  • Check the model provider's status page

Retry strategy#

We recommend using an **exponential backoff** strategy:

Code
import time
import random
from openai import OpenAI, APIError, RateLimitError, APIConnectionError
 
client = OpenAI(
    base_url="https://as.apinoma.com/v1",
    api_key="<your APINOMA_API_KEY>"
)
 
def chat_with_retry(max_retries=5, **kwargs):
    """Retry wrapper with exponential backoff"""
    for attempt in range(max_retries):
        try:
            return client.chat.completions.create(**kwargs)
 
        except RateLimitError:
            # 429: wait and retry
            wait = (2 ** attempt) + random.uniform(0, 1)
            print(f"Rate limited; waiting {wait:.1f}s...")
            time.sleep(wait)
 
        except APIConnectionError:
            # Network error: wait briefly and retry
            wait = 2 ** attempt
            print(f"Connection error; waiting {wait}s...")
            time.sleep(wait)
 
        except APIError as e:
            if e.status_code and e.status_code >= 500:
                # 5xx: server error, retry
                wait = 2 ** attempt
                time.sleep(wait)
            else:
                # 4xx: client error, do not retry
                raise
 
    raise Exception(f"Retry {max_retries} attempts failed")
 
# Usage
response = chat_with_retry(
    model="openai/gpt-4o",
    messages=[{"role": "user", "content": "Hello"}]
)

Timeout settings#

We recommend setting a reasonable timeout for your API calls:

Code
# Python OpenAI SDK
client = OpenAI(
    base_url="https://as.apinoma.com/v1",
    api_key="<your APINOMA_API_KEY>",
    timeout=60.0,  # 60 second timeout
    max_retries=3  # SDK built-in retries
)

For streaming requests, we recommend a longer timeout (120-300 seconds), since the model may take longer to generate the full content.

Best practices#

  • Distinguish retryable from non-retryable errors — 4xx usually requires changing the request, while 5xx can be retried
  • Use exponential backoff — avoid retrying too frequently when rate-limited
  • Set a maximum retry count — prevent infinite retries
  • Log errors — to make troubleshooting easier
  • Configure fallback — use 诺玛AI's `provider.fallback` parameter to switch models automatically
  • Monitor your error rate — watch error trends in the console

Last updated on June 23, 2026