> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sideren.io/llms.txt
> Use this file to discover all available pages before exploring further.

# When something isn't working.

> The failures people actually hit, in the order they hit them — what each one means and the one thing to change. Then how to reach us, and what to include so the first reply is the useful one.

## Start here

Three commands answer most of it before you read any further:

```sh theme={null}
npx sideren status              # what your tools are actually configured with
npx sideren test                # does the key reach the gateway at all
curl -s https://api.sideren.io/v1/models | head   # is the gateway answering
```

## Authentication

<AccordionGroup>
  <Accordion title="401 — every request rejected">
    The key is missing, malformed, or in the wrong header for the dialect you're calling.
    Anthropic-style endpoints take `x-api-key`; OpenAI-style endpoints take
    `Authorization: Bearer`. `/v1/messages` accepts either. Keys start with `sdn_`.
    See [Authentication](/authentication).
  </Accordion>

  <Accordion title="Claude Code ignores the gateway and talks to Anthropic">
    You are still logged in to Claude Code's own account, which takes precedence over the
    environment variables. Run `/logout` first, then re-run `npx sideren`. Check
    `ANTHROPIC_BASE_URL` is the bare origin — `https://api.sideren.io`, with **no** `/v1`;
    the Anthropic SDK appends the path itself.
  </Accordion>

  <Accordion title="Claude on Windows rejects my sdn_ key">
    Sideren keys intentionally start with `sdn_`; they are not Anthropic `sk-ant-` credentials.
    Configure **Claude Code** with `npx sideren setup --tool claude-code --key sdn_your_key`, or set
    `ANTHROPIC_BASE_URL=https://api.sideren.io` and put the key in `ANTHROPIC_AUTH_TOKEN` from
    PowerShell. Do not paste it into the consumer Claude desktop app's Anthropic key/sign-in field;
    that app does not configure a custom gateway. See [Claude Code](/guides/claude-code).
  </Accordion>

  <Accordion title="Codex can't find a key / missing SIDEREN_API_KEY">
    Codex Desktop does not inherit User environment variables. Re-run
    `npx sideren setup --tool codex --key sdn_your_key` so the key is stored as
    `experimental_bearer_token` in `~/.codex/config.toml`. See [Codex CLI](/guides/codex).
  </Accordion>
</AccordionGroup>

## Models

<AccordionGroup>
  <Accordion title="404 — no such model">
    The id did not resolve. Check it against `GET /v1/models`. Unknown ids fail closed
    rather than silently becoming something else, and the compatibility handles for foreign
    SDK names are a finite list — an invented id is a `404` by design. See
    [Model routing](/guides/model-routing).
  </Accordion>

  <Accordion title="The model in the catalog page isn't in GET /v1/models">
    It is a **preview** id. The [Models](/models) page marks these in its Availability
    column: the name is accepted, but no dedicated placement is routed for it yet, so a
    request for it is served by a comparable available model. Pin a **Live** id for
    anything whose exact behavior you depend on.
  </Accordion>

  <Accordion title="400 on a request with an image">
    That model does not accept image input. It is a short list — check
    `capabilities.vision` on the [catalog entry](/api/models-endpoint). See
    [Vision](/guides/vision).
  </Accordion>

  <Accordion title="422 — the model can't guarantee what you asked for">
    The request declared a hard requirement (a forced `tool_choice`, a strict
    `response_format`, a reasoning effort level) that no placement of that model can honour
    exactly. Switch to a model whose `supported_parameters` includes it, or drop the
    requirement.
  </Accordion>
</AccordionGroup>

## Output

<AccordionGroup>
  <Accordion title="Empty response, or an answer that stops mid-sentence">
    `finish_reason: "length"` — you hit `max_tokens`. On a reasoning model, hidden
    reasoning is charged against the same ceiling and can consume all of it, leaving
    nothing for the answer. Raise the budget; 4,000+ is a safe floor on reasoning models.
    See [Reasoning](/guides/reasoning).
  </Accordion>

  <Accordion title="Unexpected thinking blocks break my client">
    Reasoning is hidden unless the request opts in. If you are seeing it, something in your
    stack is sending `thinking`, `reasoning_effort` or `reasoning` — often an SDK default.
    Remove it.
  </Accordion>

  <Accordion title="The stream just stops">
    A stream that cannot finish ends with a protocol-shaped error event, never a silent
    truncation — so check for one before assuming the model ran out of things to say. Your
    agent may already have acted on tool calls from that turn, so decide in your client
    whether to send it again. See [Streaming](/guides/streaming).
  </Accordion>

  <Accordion title="A different model answered than the one I named">
    The catalog's `delivery` field says which ids are pinned and which are compatibility
    handles: `optimized` ids are served by whichever comparable model the gateway picks
    today, `exact` ids keep their own placement. The response always echoes the id you
    sent. Pin a `delivery: "exact"` id for anything whose exact behavior you depend on.
    See [Model routing](/guides/model-routing).
  </Accordion>
</AccordionGroup>

## Limits and cost

<AccordionGroup>
  <Accordion title="429 with a short retry-after">
    A rate limit — your plan's request window or concurrency. Honor `retry-after` exactly
    and pace off the `x-ratelimit-*` headers instead of discovering the limit by hitting
    it. Parallel agent fleets usually hit **concurrency** first. See [Plans & limits](/plans).
  </Accordion>

  <Accordion title="402 allowance_exhausted">
    Past 100% of your plan's monthly credits, new requests **stop**: they return
    `402 allowance_exhausted`. The message says how much of the month you have used, when your
    credits renew and which plan has more, and the error object carries the same facts as
    fields (`limit`, `used_percent`, `resets_at`, `upgrade_url`). In-flight requests finish:
    nothing is cut off mid-stream, and your subscription is never billed extra for it. A `402`
    carries no `retry-after`, because waiting a few seconds doesn't clear it.

    Two ways to keep going:

    * **Use purchased credit in PAYG mode.** Add credit on the
      [billing page](https://www.sideren.io/dashboard/billing), then turn on PAYG mode for your
      key or send the `x-sideren-payment-mode: payg` header. The setup helper's
      `npx sideren setup --payment-mode payg` stamps it into the agents it configures.
    * **Upgrade.** The higher plan's credits apply right away. Downgrades take effect at
      renewal.

    Free works the same way when its 200 credits are used: requests return
    `402 credit_used_up`. Free credits don't renew, so only purchased credit or a subscription
    clears it.
  </Accordion>

  <Accordion title="400 plan_upgrade_required">
    The model isn't in your plan. The message names the plan that includes it and, on Free,
    the models you can use. Upgrade, pick a model your plan includes
    ([Plans & limits](/plans#model-access-by-plan)), or send the request in PAYG mode on
    purchased credit. Retrying won't help.
  </Accordion>

  <Accordion title="402 credit_used_up with no retry-after">
    Free's 200 credits are used. There is no renewal date to wait for, so there is no
    `retry-after`. Subscribe, or add credit and turn on PAYG mode for your key. Don't retry
    it in a loop. (Before 2026-10-17 this code was `credits_exhausted`.)
  </Accordion>

  <Accordion title="402 paid_credit_required">
    The request ran in PAYG mode (the key's PAYG setting or the
    `x-sideren-payment-mode: payg` header) and there is no purchased credit left. Only a
    top-up clears it; or turn PAYG mode off to use your plan's credits.
  </Accordion>

  <Accordion title="Requests are slower than expected under load">
    When capacity is tight, a request waits for a slot rather than being refused. It shows
    up as latency, not an error — so give client timeouts headroom. Paid plans are admitted
    first; Free requests may wait longer under heavy load. See [Reliability](/reliability).
  </Accordion>

  <Accordion title="Usage is burning faster than expected">
    Each request uses credits for the model that served it, so larger models and long
    outputs use credits faster. The [usage page](https://www.sideren.io/dashboard/usage)
    shows what every request used, and `x-sideren-monthly-used-percent` on every response
    shows how much of the month is gone. Two levers: move the hot path to a lighter model,
    and keep the prompt prefix stable so repeated context is served from the cache
    ([Prompt caching](/guides/prompt-caching)).
  </Accordion>
</AccordionGroup>

## Getting help

<Card title="support@sideren.io" href="mailto:support@sideren.io" horizontal>
  The fastest route for anything not answered above.
</Card>

Include these and the first reply can usually be the answer rather than a question:

* **What you sent** — endpoint, model id, and the request body with secrets removed.
* **What came back** — the status code and the full `error.message`.
* **When** — a rough timestamp with timezone, so the trace can be found.
* **The `sideren-model` response header**, if you have it — it names what actually served the
  request.

Never send your API key. If you think one has leaked, revoke it in the dashboard first and
tell us second.

Found a security issue? Report it to
[security@sideren.io](mailto:security@sideren.io) rather than the support address.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.