AICredits logo
API

Error Handling

AICredits error codes, formats, and retry guidance. HTTP 400–503 reference table with retry matrix and exponential backoff examples.

Use this page with an AI assistant

Opens a new chat with this docs URL and the correct AICredits base URLs.

AICredits returns errors in an OpenAI-compatible format. Here's how to handle them.

Error Format

All errors are returned as JSON with this structure:

Error Response
{
  "error": {
    "message": "Human-readable description of the error",
    "type": "error_type",
    "code": 400
  }
}

Messages API (/v1/messages). Errors on this endpoint use Anthropic's error format so the Anthropic SDKs and Claude Code can parse them: {"type": "error", "error": {"type": "authentication_error", "message": "..."}, "request_id": "..."}. The HTTP status codes are the same, and the type values follow Anthropic's names (for example billing_error for 402 and permission_error for 403).

Error Codes

StatusTypeDescription
400invalid_request_errorMalformed request body, missing required fields, validation failure
401authentication_errorInvalid, missing, expired, or deactivated API key, or a disabled account
402insufficient_quotaWallet balance too low or API key budget exceeded
403forbiddenThe key is valid but not allowed to do this (for example, a management key missing the required scope)
413request_too_largeRequest body exceeds 10MB limit
429rate_limit_errorRPM limit or concurrency limit exceeded
500internal_server_errorUnexpected server error; safe to retry with exponential backoff
502upstream_errorAll providers in the fallback chain failed
503service_unavailableNo providers configured for the requested model
504gateway_timeoutProvider response timed out; retry-able

402 vs 401 vs 403: A 402 means you have insufficient funds (add credits). A 401 means the key or account can't be used (invalid, expired, or disabled: check your key settings or contact support). A 403 means the key is valid but lacks permission for that action.

Retry Strategy

Not all errors should be retried. Here's a guide:

StatusRetry?Action
400NoFix the request payload
401NoCheck/rotate your API key
402NoAdd credits to your wallet
429YesExponential backoff with jitter
500YesRetry with exponential backoff
502YesRetry after short delay (provider issue)
503NoUse a different model
504YesRetry after short delay (timeout)

Example implementation with exponential backoff:

import time
import random
from openai import OpenAI, APIError, RateLimitError

client = OpenAI(
    base_url="https://api.aicredits.in/v1",
    api_key="sk-your-key-here",
)

RETRYABLE_CODES = {429, 500, 502, 504}

def make_request(messages, max_retries=5):
    for attempt in range(max_retries):
        try:
            return client.chat.completions.create(
                model="openai/gpt-4o-mini",
                messages=messages,
            )
        except APIError as e:
            if e.status_code not in RETRYABLE_CODES:
                raise  # Don't retry non-retryable errors
            if attempt == max_retries - 1:
                raise  # Exhausted retries
            wait = (2 ** attempt) + random.uniform(0, 1)
            print(f"Error {e.status_code}. Retrying in {wait:.1f}s...")
            time.sleep(wait)
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.aicredits.in/v1",
  apiKey: "sk-your-key-here",
});

const RETRYABLE_CODES = new Set([429, 500, 502, 504]);

async function makeRequest(
  messages: OpenAI.ChatCompletionMessageParam[],
  maxRetries = 5,
) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await client.chat.completions.create({
        model: "openai/gpt-4o-mini",
        messages,
      });
    } catch (error: any) {
      const status = error?.status;
      if (!RETRYABLE_CODES.has(status) || attempt === maxRetries - 1) {
        throw error;
      }
      const wait = 2 ** attempt + Math.random();
      console.log(`Error ${status}. Retrying in ${wait.toFixed(1)}s...`);
      await new Promise((r) => setTimeout(r, wait * 1000));
    }
  }
}

Guardrails Errors

When guardrails are enabled, requests may be rejected for policy violations:

  • Blocked keywords: The request contains prohibited terms. Returns 400.
  • PII masking: When enabled, personally identifiable information is automatically masked before being sent to the LLM provider. No error is returned — the request proceeds with masked content.
Guardrails Error
{
  "error": {
    "message": "Request blocked: contains prohibited content",
    "type": "invalid_request_error",
    "code": 400
  }
}

On this page