> For the complete documentation index, see [llms.txt](https://sm-fund.gitbook.io/sm-fund-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sm-fund.gitbook.io/sm-fund-docs/guides/connection-lifecycle.md).

# Connection lifecycle

Use a single connection owner for your account. It requests Tickets, opens the socket, and decides whether to reconnect. Running independent reconnect loops for the same account causes the clients to replace each other.

## Open or switch a feed

1. Request a fresh [Ticket](/sm-fund-docs/reference/tickets.md) with the desired feed.
2. Use the returned `wss_url`, `feed`, and `subprotocol`, with the Ticket in `Authorization`.
3. Receive new messages automatically. Handle WebSocket ping/pong through your client library.

Switching from Polymarket to raw, or changing API Keys, still uses the same connection allowance. A new valid connection replaces the old socket with `4001 connection replaced`. Invalid or rejected handshakes do not replace the existing socket.

The Ticket's `expires_at` limits when you can establish the connection. It is not a timer that disconnects a healthy Free connection after 60 seconds. A paid connection remains subject to the end of its access period.

## Decide whether to retry

| Result                                  | What to do                                                                                                                             |
| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `4001 connection replaced`              | Stop. Let the new connection own the account. Do not automatically request another Ticket.                                             |
| `4003 access expired`                   | Request a fresh Ticket to obtain current access; an expired Developer subscription falls back to Free.                                 |
| `4003 access revoked`                   | Re-check the account and key. A fresh Ticket may succeed after an entitlement change, but a revoked key or disabled account will fail. |
| `1008 server push only`                 | Remove client text/binary sends before retrying. Protocol ping/pong is allowed.                                                        |
| `1013 client too slow`                  | Reduce work in the receive loop, then reconnect with backoff. Record the data gap.                                                     |
| Server shutdown or a network disconnect | Reconnect with backoff and a fresh Ticket; record the gap.                                                                             |
| Ticket API `401` or `403`               | Stop repeated retries; fix the key or account access.                                                                                  |
| Ticket API `429`                        | Wait at least the response's `Retry-After` seconds.                                                                                    |
| Temporary `503` or network failure      | Retry with backoff.                                                                                                                    |

See [errors and close codes](/sm-fund-docs/reference/errors.md) for the complete reference. A handshake HTTP failure occurs before a WebSocket connection exists, so it is not a WebSocket close code.

Use exponential backoff with jitter, for example 1, 2, 4, 8, then at most 30 seconds plus a small random delay. Honor a longer `Retry-After`. Reset the retry counter after the connection has been stable, rather than immediately on every successful handshake. Never reuse an already-consumed Ticket.

## Keep up with delivery

Keep the socket's receive loop short. Move expensive processing to a bounded application queue, monitor its size, and decide how to handle overload. A slow client may be disconnected independently of other users.

Raw pending data can have a substantially higher message volume than Polymarket fills. Measure received bytes and peak rates with your chosen feed before sizing your storage and processing pipeline. Avoid logging every raw message in production.

The service does not replay missing messages. Record disconnect intervals and reconcile through an independent confirmed-data source when your application needs completeness. Arrival order is not chain order or proof of finality.
