Errors

JoyToken model-call failures return OpenAI-compatible error objects. message is a readable reason; type is the more stable field for client-side handling.

Error response
1{
2 "error": {
3 "message": "missing api key",
4 "type": "missing_api_key"
5 }
6}

Chat Completions Errors

HTTP statuserror.typeCommon causeRetry?
400invalid_request_errorBody is not valid JSON, body exceeds 8 MiB, or messages is emptyNo
401missing_api_keyNo API key was providedNo
403invalid_api_keyAPI key is invalid or not ACTIVENo
403policy_rejectedPolicy block, IP not allowed, model blacklist, tier not allowed, fixed model mismatchNo
402insufficient_quotaDaily/weekly quota exceeded or current tier wallet balance is insufficientNo; adjust balance or policy first
502routing_errorRouter returned no usable model or routing service errorShort backoff retry
502upstream_errorProvider invocation failed or downstream gRPC error was converted by gatewayShort backoff retry
503upstream_errorDownstream service unavailableYes
504upstream_errorDownstream deadline exceededYes
500stream_errorCurrent response writer does not support streamingNo; usually deployment/proxy issue

The OpenAPI definition keeps 429 for traditional rate-limit compatibility, but the current code path explicitly enforces quota, policy, and wallet precheck. Fixed QPS rate limiting is not a public capability yet.

Models Errors

GET /api/v1/models is exposed by front-gateway and does not require an API key. The most common failure is unavailable backend model service:

503 response
1{
2 "code": 50300,
3 "message": "admin-bff not available"
4}

Debug Fields

When a request fails, record these fields and query the same time window in Console logs / usage:

FieldSource
X-Request-IDRequest header, or gateway-generated internal request ID
model / tierRequest body
HTTP statusResponse status code
error.type / error.messageError response body
X-DAOE-Used-Model / X-DAOE-Used-ProviderSuccessful response headers, used to confirm actual routing
metadata.billingSuccessful response body, used to confirm tokens and credits

Simple Retry Check

retry.ts
1export function shouldRetryJoyTokenError(status: number, type?: string) {
2 if (status === 503 || status === 504) return true;
3 if (status === 502 && (type === "routing_error" || type === "upstream_error")) {
4 return true;
5 }
6 return false;
7}