# WebSockets

The WebSocket API provides continuous market-data events through CuteMarkets authentication, plan controls, and connection limits. WebSocket access is available only on Expert (€99/mo yearly or €119/mo monthly) or Commercial (€399/mo yearly or €469/mo monthly) plans.

## Endpoint

```text
wss://api.cutemarkets.com/v1/ws/{market}/
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `market` | string | Yes | `options` or `stocks`. |

Local development:

```text
ws://localhost:8000/v1/ws/options/
```

## Authentication

API clients should pass a product-scoped bearer API key during the WebSocket handshake:

```bash
npx wscat \
  -c "wss://api.cutemarkets.com/v1/ws/options/" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Browser clients cannot set custom WebSocket headers, so `api_key` is also accepted as a query parameter:

```js
const ws = new WebSocket(
  `wss://api.cutemarkets.com/v1/ws/stocks/?api_key=${encodeURIComponent('YOUR_API_KEY')}`,
);
```

Prefer the `Authorization` header outside browser-only integrations because query strings can be captured in logs.

## Protocol

CuteMarkets authenticates the stream automatically. After the socket opens, send subscribe and unsubscribe messages; no extra login message is required.

Subscribe to option trades:

```json
{"action":"subscribe","params":"T.O:SPY260515C00500000"}
```

Subscribe to stock minute aggregates:

```json
{"action":"subscribe","params":"AM.AAPL"}
```

Unsubscribe:

```json
{"action":"unsubscribe","params":"AM.AAPL"}
```

Stream messages are forwarded without schema changes. Status messages and event arrays use the market-data stream shape.

## Connection limit

Only one WebSocket connection is allowed per CuteMarkets user across all API keys and markets. If the same user opens a second connection, the second connection is rejected with close code `4409`.

The lock is stored in Redis with a short TTL and refreshed while the socket is alive. If a process dies without a clean disconnect, the stale lock expires automatically.

## Plan behavior

| Plan | WebSocket access | Stream source |
| --- | --- | --- |
| Free | Not available | — |
| Developer | Not available | — |
| Expert (€99/mo yearly or €119/mo monthly) | Available | Live stream |
| Commercial (€399/mo yearly or €469/mo monthly) | Available | Live stream |

For `stocks`, use a Stocks API key and the stock product tier is used. For `options`, use an Options API key and the options tier is used. Connections without Expert or Commercial access are rejected before any market-data stream is opened.

## Close codes

| Code | Meaning |
| --- | --- |
| `4401` | Missing or invalid API key, product mismatch, unsupported market, stream access is not configured, or the account is not on Expert/Commercial. |
| `4409` | This user already has an active WebSocket connection. |
| `1011` | Stream gateway error after the connection was accepted. |

## Example client

```js
import WebSocket from 'ws';

const ws = new WebSocket('wss://api.cutemarkets.com/v1/ws/options/', {
  headers: {
    Authorization: 'Bearer YOUR_API_KEY',
  },
});

ws.on('open', () => {
  ws.send(JSON.stringify({
    action: 'subscribe',
    params: 'T.O:SPY260515C00500000',
  }));
});

ws.on('message', (data) => {
  console.log(JSON.parse(data.toString()));
});
```

## Related docs

- [Authentication](/docs/authentication)
- [Rate Limits & Plans](/docs/rate-limits)
- [Trades](/docs/trades)
- [Quotes](/docs/quotes)
