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

# Error codes

> Every error code the chat SDK reports, what the visitor sees and what to do

The widget and inline panel handle these codes for you and show the visitor a message. With the [headless client](/website-chat/headless), read them from `state.error` (and from a failed message's status): each error has a stable `code`, a `message`, a `retryable` flag, `retryAfterSeconds` and `retryAt` (epoch milliseconds) for waits, and, for an origin rejection, the rejected `origin`. `ChatErrorCode` is exported from the core entry.

**Retried** means the SDK retries by itself; you do not need to.

| Code | When | What the visitor sees | Retried | What to do |
| - | - | - | - | - |
| `public_chat_disabled` | Anonymous usage is off for the agent | No launcher on page load; an open panel shows "This chat is no longer available" | No, terminal | Switch on [Anonymous usage](/website-chat/dashboard-settings#anonymous-usage) and save |
| `origin_not_allowed` | The page's origin is not in the allowed websites | "This chat is not enabled for this website." | No | Add the exact origin to [Allowed websites](/website-chat/dashboard-settings#allowed-websites) |
| `agent_inactive`, `agent_archived`, `agent_not_found` | The agent is stopped, archived or the ID is wrong | "This chat is unavailable." | No | Start the agent, or check the `agent_…` ID in your snippet |
| `rate_limited` (messages) | More than 20 messages a minute in a conversation, or 60 an hour from one IP for the agent | A countdown; the message is sent automatically afterwards | Yes, up to three times, then shown as not sent with **Retry** | Usually nothing. Shared office IPs share the hourly limit. See [Limits](/website-chat/security#limits) |
| `rate_limited` (requests) | Too many new conversations or stream tokens from one IP, or history loads for one conversation | "Too many requests. Please try again in a few minutes." with **Try again**; the message is shown as not sent | No | Wait and try again. Custom clients should honour `Retry-After` |
| `daily_limit_reached` | The agent reached its daily cap of anonymous conversations; only a new conversation's first message is refused | "This chat is busy right now. Please try again later." | No; the composer re-enables after up to 5 minutes | Raise [Conversations per day](/website-chat/dashboard-settings#conversations-per-day), and check the usage counter for unexpected traffic |
| `session_limit_reached` | The conversation reached the agent's per-conversation message limit | "This conversation has reached its message limit. Start a new chat to continue." and a **New chat** button | No | Raise or turn off [Messages per conversation](/website-chat/dashboard-settings#messages-per-conversation). SDK 0.1.2 does not know this code and shows a Retry that fails again |
| `session_not_found`, `session_closed` | The conversation ended or is no longer available | "Conversation ended" | No | Start a new chat. In server mode, handle `getToken({ newSession: true })` |
| `invalid_customer_id` | A server-mode customer ID uses the reserved visitor format (`web:…`) | Chat does not connect | No | Use your own customer ID. See [Logged-in users](/website-chat/server-mode#identity-and-rotation) |
| `token_failed` | Your `getToken()` threw or returned an invalid response (logged-in chats) | The error message, with **Try again** | Yes | Check your token endpoint and that it returns `token`, `wsUrl` and `expiresAt` |
| `invalid_token` | The stream token was rejected. The SDK asks for a fresh one once | Chat does not connect | Once, with a new token | Check that your backend mints the token for the same session and agent, and does not cache old tokens |
| `network`, `session_unavailable`, `stream_unavailable` | A network or service request failed | "Reconnecting…" or "You are offline" | Yes | Usually nothing; the SDK reconnects |
| `interaction_not_pending`, `interaction_suspended`, `invalid_interaction` | A button, card or date answer arrived when it could no longer be accepted (for example while a team member is connected) | The choice is not accepted and stays on screen | No | Nothing; the visitor can type instead |
| `unknown` | The response had no recognised code | A generic failure | No | Check the browser console and network log |

The SDK also returns `{ ok: false, reason }` from `send()` without an error code; see [Methods and outcomes](/website-chat/headless#methods-and-outcomes).


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