Errors

Errors follow the format of the endpoint you called, so the OpenAI and Anthropic SDKs can read them. The HTTP status decides whether SDKs retry automatically.

Format

OpenAI (/v1/chat/completions, /v1/responses, /v1/models, images, and video):

402
{
  "error": {
    "message": "Insufficient balance for this request. Top up your balance and try again.",
    "type": "insufficient_balance",
    "param": null,
    "code": "insufficient_balance"
  }
}

Anthropic (/v1/messages):

402
{
  "type": "error",
  "error": {
    "type": "insufficient_balance",
    "message": "Insufficient balance for this request. Top up your balance and try again."
  }
}

Error codes

HTTPcodeMeaningRetry?
400invalid_jsonThe body is not valid JSON.No
400invalid_requestA wrong parameter; param names it. For example max_tokens above the model limit, n other than 1, or empty messages.No, fix it first
401invalid_api_keyThe key is missing, malformed, revoked, or expired.No
402insufficient_balanceThe balance is too low for this request's hold.No, top up or lower max_tokens
403account_suspendedThe account is suspended.No, contact support
403key_spend_limit_exceededThe key reached its spend limit.No
403model_not_allowedThe key may not use this model.No
404model_not_foundThe model does not exist or is unavailable.No, check /v1/models
404not_foundUnknown path.No
405method_not_allowedWrong HTTP method.No
413request_too_largeThe body is over the limit (8 MiB by default; 64 KiB for images and video).No
415unsupported_media_typeContent-Type is not application/json.No
429rate_limit_exceededA per-minute limit (key, account, or IP) was exceeded.Yes, after Retry-After
429too_many_concurrent_requestsThe account's concurrent request queue is full.Yes, after Retry-After
500internal_errorInternal error.Yes, with a delay
502upstream_errorThe model provider returned an error. Not billed.Yes
503overloadedTemporarily at capacity.Yes, after Retry-After
503model_unavailableThe model is temporarily unavailable.Yes, or use another model
504upstream_timeoutThe model provider took too long. Not billed.Yes

Conditions that retrying cannot fix (no balance, key spend limit) deliberately do not use 429, so SDKs do not retry in vain. Requests you cancel yourself are recorded as 499 client_closed_request in the dashboard.

Retry strategy

The OpenAI and Anthropic SDKs retry 408, 409, 429, and 5xx automatically. In your own client, use exponential backoff with jitter, honor Retry-After, and cap the number of attempts.

import os
import openai
from openai import OpenAI

client = OpenAI(base_url="https://api.markas.ai.id/v1", api_key=os.environ["MARKASAI_API_KEY"], max_retries=3)

try:
    resp = client.chat.completions.create(
        model="MODEL_ID",
        messages=[{"role": "user", "content": "Halo"}],
        max_tokens=100,
    )
except openai.APIStatusError as e:
    body = e.body if isinstance(e.body, dict) else {}
    print(e.status_code, body.get("code"), e.response.headers.get("x-request-id"))
import OpenAI from "openai";

const client = new OpenAI({ baseURL: "https://api.markas.ai.id/v1", apiKey: process.env.MARKASAI_API_KEY, maxRetries: 3 });

try {
  await client.chat.completions.create({
    model: "MODEL_ID",
    messages: [{ role: "user", content: "Halo" }],
    max_tokens: 100,
  });
} catch (err) {
  if (err instanceof OpenAI.APIError) {
    console.log(err.status, err.code, err.headers?.["x-request-id"]);
  } else {
    throw err;
  }
}