Errors

Error codes, formats, and handling for the Sansa API

Error Format

All Sansa API errors use the same format as OpenAI. If your code already handles OpenAI errors, it works with Sansa unchanged.

{
  "error": {
    "code": "invalid_request",
    "message": "Human-readable description of what went wrong.",
    "request_id": "a3f2c1d0-8b4e-4f9a-b2d1-7c5e3a1f0e9b"
  }
}
FieldTypeDescription
codestringMachine-readable error identifier. See the reference below.
messagestringWhat went wrong and how to fix it.
request_idstringPresent on errors that occur after the request is accepted. Use this when contacting support. Not present on auth errors.

HTTP Status Codes

StatusMeaning
400Bad request — invalid body, unsupported parameter, or value out of range
401Unauthorized — missing or invalid API key
402Payment required — insufficient credits
429Rate limited — too many requests
500Internal error — server error or upstream provider failure

Error Code Reference

invalid_request

HTTP 400. The request body is structurally invalid or a value is out of range.

Common causes:

  • messages is missing or empty
  • A field type is wrong (e.g., content: 123 instead of a string)
  • temperature is not between 0 and 2
  • top_p is not between 0 and 1
  • frequency_penalty or presence_penalty is not between -2 and 2
  • max_tokens or max_completion_tokens is less than 1
  • stop contains more than 4 sequences
  • metadata has more than 16 key-value pairs, a key over 64 characters, or a value over 512 characters
  • response_format.type is "json_schema" but no json_schema object was provided
  • A tool message is missing tool_call_id
  • Malformed JSON body

invalid_call_name

HTTP 400. The metadata["call_name"] value is invalid — either empty/whitespace-only or exceeds 64 characters.

unsupported_parameter

HTTP 400. A parameter was provided that Sansa does not support.

ParameterWhy rejected
audioAudio output is not supported
modalities (with "audio")Only text modality is supported
web_search_optionsWeb search is not supported
n > 1Only one completion per request
functionsDeprecated — use tools
function_callDeprecated — use tool_choice

unauthorized

HTTP 401. The API key is missing, malformed, or invalid.

  • No Authorization header
  • Missing Bearer prefix — must be Authorization: Bearer <api-key>
  • API key is revoked or does not exist

request_id is not present on auth errors.

insufficient_credits

HTTP 402. Your account balance is zero or insufficient for the request.

Add credits from your dashboard.

SDK note: HTTP 402 is not part of OpenAI's standard error set. The OpenAI SDK surfaces it as a generic APIStatusError. Catch it by checking error.status === 402 or the code field.

rate_limit_exceeded

HTTP 429. Your API key has exceeded its rate limit, or the upstream provider returned a rate limit error. Retry with exponential backoff.

upstream_invalid_request

HTTP 500. The request passed Sansa's validation but was rejected by the upstream model. This is rare. If it persists, contact support with the request_id.

provider_unavailable

HTTP 500. The upstream model is temporarily unavailable (connection failure or timeout). Retry with backoff.

provider_error

HTTP 500. The upstream model returned a server-side error. Retry with backoff.

invalid_file_format

HTTP 400. The uploaded audio file has an unsupported format. Supported formats for /v1/audio/transcriptions: mp3, wav, m4a, webm, ogg, flac, opus.

file_too_large

HTTP 400. The uploaded audio file exceeds the maximum allowed size (25 MB).

unsupported_response_format

HTTP 400. The response_format value is not supported by the transcriptions endpoint.

internal_error

HTTP 500. An unexpected error in the Sansa API. Contact support with the request_id.


Errors in Streaming Responses

Pre-stream errors

If validation, auth, or credits fail before streaming begins, the response is a normal JSON error body with the appropriate HTTP status code — not an SSE stream.

HTTP/1.1 400 Bad Request
Content-Type: application/json

{"error":{"code":"invalid_request","message":"..."}}

Mid-stream errors

If an error occurs after streaming has started (HTTP 200 already sent), the error is delivered as an SSE event. The stream always ends with [DONE] after a mid-stream error.

data: {"choices":[{"finish_reason":"error"}],"error":{"code":"provider_error","message":"The upstream model returned an error. Please retry."}}

data: [DONE]

Detect mid-stream errors by checking finish_reason === "error".


Handling Errors

Python

import openai

client = openai.OpenAI(
    api_key="sk-sansa-...",
    base_url="https://api.sansa.dev/v1",
)

try:
    response = client.chat.completions.create(
        model="sansa-auto",
        messages=[{"role": "user", "content": "Hello"}],
    )
except openai.AuthenticationError as e:
    # 401
    print(e.body["error"]["message"])
except openai.BadRequestError as e:
    # 400
    print(e.body["error"]["code"], e.body["error"]["message"])
except openai.RateLimitError as e:
    # 429
    print("Retry after a short delay")
except openai.APIStatusError as e:
    # 402, 500, etc.
    request_id = e.body.get("error", {}).get("request_id")
    print(f"Error {e.status_code}. Request ID: {request_id}")

TypeScript

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "sk-sansa-...",
  baseURL: "https://api.sansa.dev/v1",
});

try {
  const response = await client.chat.completions.create({
    model: "sansa-auto",
    messages: [{ role: "user", content: "Hello" }],
  });
} catch (err) {
  if (err instanceof OpenAI.AuthenticationError) {
    console.error(err.error.message);
  } else if (err instanceof OpenAI.BadRequestError) {
    console.error(err.error.code, err.error.message);
  } else if (err instanceof OpenAI.RateLimitError) {
    console.error("Rate limited — retry with backoff");
  } else if (err instanceof OpenAI.APIError) {
    const requestId = (err.error as any)?.request_id;
    console.error(`Error ${err.status}. Request ID: ${requestId}`);
  }
}

Detecting mid-stream errors

for chunk in stream:
    if chunk.choices and chunk.choices[0].finish_reason == "error":
        break
    # process chunk normally

Retry Strategy

Error codeRetryable?Action
invalid_requestNoFix the request
invalid_call_nameNoFix the call_name value
unsupported_parameterNoRemove the unsupported field
invalid_file_formatNoUse a supported audio format
file_too_largeNoReduce file size below 25 MB
unsupported_response_formatNoUse a supported response format
unauthorizedNoCheck your API key
insufficient_creditsNoAdd credits, then retry
rate_limit_exceededYesExponential backoff
upstream_invalid_requestNoContact support
provider_unavailableYesExponential backoff
provider_errorYesExponential backoff
internal_errorRarelyRetry once; contact support if it persists