# Troubleshooting

Check the HTTP status and content type before decoding the body. Chat errors generally have an `error` object, while media endpoints can also forward upstream error formats.

## Error response shape

This is an illustrative error, not a promise of identical wording for every endpoint:

~~~json
{
  "error": {
    "message": "Invalid API key provided.",
    "type": "authentication_error",
    "code": "invalid_api_key"
  }
}
~~~

Treat `message`, `type`, and `code` as optional when parsing error bodies. Some capacity errors contain only a message and type; an intermediary can also return a non-JSON response.

## Status code guide

| Status | Meaning | First check |
| --- | --- | --- |
| 400 | Invalid input or rejected request | JSON, parameters, context, content-policy message |
| 401 | Missing or invalid credentials | Bearer header and key validity |
| 402 | Insufficient credits | Account and key balances |
| 403 | Access denied | Account/model permissions |
| 404 | Unknown path, model or resource | Base URL, route, exact model ID |
| 429 | Rate, concurrency or capacity limit | Retry-After and active request count |
| 499 in logs | Client-side cancellation | Client deadline, disconnect, Stop action |
| 500 | Internal service failure | Capture safe diagnostics; bounded retry if appropriate |
| 501 | Endpoint not implemented | Use chat completions instead of legacy completions |
| 502 | Routing or upstream failure | Service availability and error timing |
| 503 | Temporarily unavailable | Capacity and bounded backoff |
| 504 | Timeout | Application deadlines and service availability |

## A 404 with an otherwise valid key

Use `https://api.simplellm.eu/v1` as the OpenAI-compatible SDK base URL. Do not append another `/v1` or point inference requests to the dashboard host.

Use `chat.completions.create`, not a client's Responses API or legacy text-completion method. Check the [compatibility page](/docs/compatibility.html) before assuming another OpenAI endpoint exists.

## Empty answer or no visible output

Inspect `choices`, the finish reason, optional reasoning fields, and token usage. A small output budget can be consumed by reasoning. A tool call may intentionally have no ordinary text answer until your application returns a tool result.

For streaming, keep reading through role-only and usage-only events. Do not fail merely because one chunk has no text or no choices.

## Invalid JSON while reading audio

Speech returns audio bytes on success. Transcription can return text formats depending on the requested output. Check Content-Type before calling a JSON parser, and use multipart form data for file uploads.

## A stream fails after HTTP 200

The status was sent before generation finished. Catch read errors, inspect any stream error events, and mark the response incomplete if it ends without a valid completion.

Do not discard delivered output automatically or charge a new request to the user through an invisible retry. See [stream handling](/docs/streaming.html).

## Safe diagnostics for support

Record the timestamp with timezone, endpoint, model ID, HTTP status, time to first output, total elapsed time, and whether any output arrived. Include a request identifier if the response supplies one.

Remove Authorization headers, API keys, personal data, and sensitive prompts or images before sharing diagnostics. Reproduce with a minimal non-sensitive request where possible.

Security findings belong at [security@stageone.solutions](mailto:security@stageone.solutions), following the [reporting policy](/docs/security.html); do not submit automated bulk reports.
