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

# Troubleshooting

> The widget's error contract, and telling a session-expired screen apart from a session-not-found one.

### Error contract

Every error response from the widget's API carries a `code` and a `detail`:

```json theme={null}
{
  "code": 40001,
  "detail": "Authentication credentials were not provided."
}
```

`detail` is a plain string, with one exception: when the request itself failed validation, `detail` is an object keyed by the field that failed instead — one array of messages per field, the same shape you'd get from any field-level validation error.

```json theme={null}
{
  "code": 20000,
  "detail": {
    "requested_operations": {
      "0": ["\"no-existe\" is not a valid choice."]
    }
  }
}
```

`20000` is the only code that carries this shape today — every other code below always answers with a single string message.

| Code              | Meaning                                                                                                                |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `20000`           | Validation error — something in the request is malformed. `detail` is an object keyed by field, not a string.          |
| `20002`           | Not found.                                                                                                             |
| `40000`           | Authentication failed — invalid credentials on [`POST /auth`](/crypto-as-a-service/widget/get-started/authentication). |
| `40001`           | Not authenticated — no session token was provided.                                                                     |
| `40002`           | Permission denied — the session doesn't have this operation enabled.                                                   |
| `40003`           | Session not found or expired.                                                                                          |
| `40004`           | Throttled — too many requests.                                                                                         |
| `50000` and above | An internal or upstream error. Retry the request.                                                                      |

### Session expired vs. session not found

A user's session can fail in two different ways, and the widget's screen tells them apart:

| Situation                    | What it means                                          | What to do                                                                                                                         |
| ---------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| **Token invalid or expired** | The JWT itself failed validation.                      | Mint a new token via `POST /auth` and re-embed the widget.                                                                         |
| **Session not found**        | The token is valid, but the session behind it is gone. | Same fix — mint a new token — but the user had already started interacting, so this can surface mid-flow rather than only on load. |
