OpenToken Docs

Errors

How OpenToken reports errors, the status codes you can expect, and how to handle them.

OpenToken returns errors in the OpenAI-compatible envelope. Every failed request — and any error that surfaces after a streaming response has started — uses the same shape, so a single handler covers them all.

{
  "error": {
    "message": "Human-readable explanation of what went wrong.",
    "type": "invalid_request_error",
    "code": "model_not_found"
  }
}

The HTTP status code, the type, and the more specific code together tell you what happened and whether a retry makes sense.

Status codes

StatustypecodeMeaning
400invalid_request_errormodel_not_foundThe request was malformed, or the {provider}/{model} id is not registered.
401authentication_errormissing_auth / invalid_key / expired_keyMissing or invalid API key. DB-issued keys start with sk-optk-; environment/demo keys may use other formats.
402invalid_request_errorinsufficient_creditThe workspace credit balance is exhausted (or no billing account is provisioned). Top up to continue.
429invalid_request_errorspend_limit_exceededA per-key spend limit was reached. (OpenToken has no general request-rate limiter.)
500api_errorAn unexpected error inside the gateway.
503upstream_errorno_supplierThe provider returned an error, or no provider was available to serve the model.
504upstream_errorupstream_timeoutThe upstream provider did not respond within the gateway deadline.

Example: unknown model

OpenToken registers google/* (gemini-2.5-pro, gemini-3-flash, gemini-3.1-pro, gemini-3.1-flash-lite, text-embedding-004) and anthropic/* (claude-opus-4-7, claude-opus-4-6, claude-sonnet-4-6, claude-sonnet-4-5, claude-haiku-4-5). Any unregistered id — including any openai/* id — returns a 400 with model_not_found. See Models for the live list.

{
  "error": {
    "message": "model \"openai/gpt-4o\" not found",
    "type": "invalid_request_error",
    "code": "model_not_found"
  }
}

See Models for the full list of registered ids.

Handling errors

Check the HTTP status first, then branch on code for the cases you want to treat specially.

from openai import OpenAI, APIStatusError

client = OpenAI(base_url="https://api.opentoken.kr/v1", api_key="sk-optk-...")

try:
    resp = client.chat.completions.create(
        model="google/gemini-3-flash",
        messages=[{"role": "user", "content": "Hello"}],
    )
except APIStatusError as e:
    err = e.response.json()["error"]
    print(e.status_code, err["type"], err.get("code"), err["message"])
import OpenAI, { APIError } from "openai";

const client = new OpenAI({
  baseURL: "https://api.opentoken.kr/v1",
  apiKey: process.env.OPENTOKEN_API_KEY,
});

try {
  await client.chat.completions.create({
    model: "google/gemini-3-flash",
    messages: [{ role: "user", content: "Hello" }],
  });
} catch (e) {
  if (e instanceof APIError) {
    console.log(e.status, e.type, e.code, e.message);
  }
}

Errors during streaming

When stream: true, the HTTP status can be 200 before anything goes wrong upstream. An error that occurs mid-stream arrives as a final SSE data event carrying the same { error: { message, type, code } } envelope (with type usually upstream_error and code stream_error or the upstream code). The stream is then terminated with data: [DONE] as usual, so detect the error by inspecting each event's payload for an error field rather than relying on [DONE]. Always handle errors on the event stream, not just on the initial response.

Next steps