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

# Errors & Limits

> Every error code the socket can send, and what to do about each.

## Error frames

Errors arrive as their own frame, carrying a human-readable `message` and a
machine-readable `code`.

```json theme={null}
{"type":"error","message":"api key does not carry the read scope","code":"forbidden_scope"}
```

Match on `code`. The `message` is for humans and may be reworded.

| `code` | Meaning | What to do | Closes socket |
| - | - | - | - |
| `unauthenticated` | Unknown, malformed or revoked credential | Re-read or reissue the credential | Yes, when revoked mid-session |
| `forbidden_scope` | Valid key without the `read` scope | Issue a key with `read` | Yes, when revoked mid-session |
| `connection_limit` | Too many connections for this key | Close an existing socket | No |
| `invalid_message` | Frame did not parse | Fix the frame | No |
| `too_many_targets` | More than 200 targets in one `subscribe` | Split the subscription | No |
| `authenticate_in_progress` | A second `authenticate` arrived while one was in flight | Wait for the pending response, then retry | No |
| `unknown_target` | A `ticker` or `symbol` matched no market — the whole frame is rejected | Check the handle you sent | No |

<Warning>
  Neither `unauthenticated` nor `forbidden_scope` is worth retrying. One needs a
  different credential, the other a different key. Retrying the same token
  produces the same error.
</Warning>

### `unknown_target` leaves you untouched

Because [`subscribe` replaces your whole set](/websockets/subscriptions), a
target that cannot be resolved rejects the entire frame and leaves your existing
subscriptions in place. A partial apply would leave you worse off than doing
nothing.

An unrecognized `eventMarketId` or `marketId` is still accepted silently —
handles are checked against a directory, UUIDs are not.

## Limits

| Limit | Value | On exceeding |
| - | - | - |
| Targets per `subscribe` | 200 | `too_many_targets` |
| Authenticated connections per API key | 5 | `connection_limit` |
| Active API keys per account | 10 | Rejected at issuance |
| Maximum frame size | 1 MB | Socket closed |
| Ping interval | 5 minutes | Socket closed |
| Revocation propagation | 60 seconds | Socket closed |

The connection limit is enforced best-effort rather than transactionally, so
sockets opening simultaneously on one key may briefly exceed it. Treat it as
back-pressure, not a guarantee, and do not design around the exact number.

## Closes

A `connection_limit` error leaves the socket **open** — market data keeps
flowing, and only the `authenticate` was refused.

Credential errors during an `authenticate` attempt also leave the socket open
for anonymous market data, including when a replacement credential fails.

When periodic revalidation detects that an authenticated key was revoked or lost
its `read` scope, the server sends the error frame and then closes. The close ends
your market-data subscriptions along with the private stream, so reconnect and
resubscribe. Market data needs no credential, so an anonymous socket is enough to
keep prices flowing while you sort out the key.

The server does not send a specific close code, so most client libraries report
1005\. See [Connection Keep-Alive](/websockets/keep-alive#reconnecting).

## Suggested handling

<Steps>
  <Step title="Match on code, not message">
    Treat an absent `code` as unknown rather than crashing — the field is
    optional for backwards compatibility with older senders.
  </Step>

  <Step title="Separate fatal from transient">
    `unauthenticated` and `forbidden_scope` need human intervention. The rest
    are programming errors or back-pressure, and are safe to handle in code.
  </Step>

  <Step title="Back off on reconnect">
    Re-authenticating with the same invalid key will fail again. Obtain a working
    credential before retrying; the socket remains available for anonymous market
    data. Back off between reconnect attempts rather than looping.
  </Step>
</Steps>


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