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

# How-to: Subscribe to real-time updates

> Open a WebSocket connection to Match and subscribe to market or account channels for live auction and order events.

The Match WebSocket API delivers real-time auction and account events without
polling. You subscribe to the `market` channel for public auction state, the
`account` channel for private order and fill events, or both. Authentication
uses a short-lived, single-use JWT ticket you create immediately before opening
the socket.

## Prerequisites

Before you begin, ensure that you've:

* Obtained a Circle API key with Match access
* Completed onboarding as a burn-side or mint-side participant (or both)

## Steps

### Step 1. Create a connection ticket

Call `POST /v1/match/ws/ticket` to get a single-use JWT. The ticket is
short-lived, so create it immediately before you open the socket.

```bash theme={null}
curl -X POST https://api-sandbox.circle.com/v1/match/ws/ticket \
  -H "Authorization: Bearer $API_KEY"
```

A successful response contains the ticket string:

```json theme={null}
{
  "data": {
    "ticket": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
  }
}
```

<Note>
  Each ticket is single-use and authenticates exactly one WebSocket connection.
  Do not reuse a ticket after it has been used to open a connection.
</Note>

### Step 2. Open the connection

Pass the following two `Sec-WebSocket-Protocol` values in the upgrade request:

* `circle-match.v1`: identifies the protocol version
* `ticket.<jwt>`: your ticket value, prefixed with `ticket.`

The server validates the ticket before completing the upgrade. If the ticket is
missing, expired, or already used, the server rejects the connection with
HTTP 401.

```bash theme={null}
wscat -c "wss://api-sandbox.circle.com/v1/match/ws" \
  --subprotocol "circle-match.v1" \
  --subprotocol "ticket.$TICKET"
```

Replace `$TICKET` with the `ticket` value from the previous step.

### Step 3. Handle the hello frame and subscribe

The server sends a `hello` frame immediately after the connection is
established:

```json theme={null}
{
  "type": "hello",
  "entityId": "550e8400-e29b-41d4-a716-446655440000",
  "serverTime": "2026-09-21T14:00:00.000Z"
}
```

After receiving `hello`, send a `subscribe` message for each channel you want to
receive events from. To subscribe to both channels, send two messages:

```json theme={null}
{ "type": "subscribe", "channel": "market" }
```

```json theme={null}
{ "type": "subscribe", "channel": "account" }
```

The server acknowledges each subscription with a `subscribed` frame:

```json theme={null}
{
  "type": "subscribed",
  "channel": "market"
}
```

The server also sends periodic `keepalive` frames with a `serverTime` field to
confirm the connection is healthy.

If a subscription request is invalid or authorization fails, the server sends an
`error` frame with a `channel` and `error` field.

### Receive events

#### Session frames

| Frame type   | When sent                             | Key fields               |
| ------------ | ------------------------------------- | ------------------------ |
| `hello`      | Immediately on connect                | `entityId`, `serverTime` |
| `keepalive`  | Periodically                          | `serverTime`             |
| `subscribed` | After subscription acknowledged       | `channel`                |
| `error`      | On invalid subscription or auth error | `channel`, `error`       |

#### Market channel events (public)

Any valid ticket holder can subscribe to the `market` channel. On subscribe, the
server delivers a `snapshot` of the current auction state, then streams
incremental events as the auction progresses.

| Event                | When                           | Key fields                                        |
| -------------------- | ------------------------------ | ------------------------------------------------- |
| `snapshot`           | On subscribe                   | Full current auction state                        |
| `auction_opened`     | When a new auction opens       | `auctionId`, `lockAt`, `clearAt`                  |
| `auction_locked`     | When the lock window opens     | `auctionId`                                       |
| `auction_cleared`    | When the auction clears        | `auctionId`, `clearingFeeBps`, `matchedSizeCents` |
| `indicative_updated` | Periodically during open phase | `indicativeFeeBps`, `netImbalanceCents`           |

Key fields present on market events:

* `phase`: current auction phase (`open`, `locked`, `settling`)
* `indicativeFeeBps`: the fee that would clear if the auction settled now
* `matchableSizeCents`: volume that would match at the indicative fee
* `netImbalanceCents`: difference between burn-side and mint-side volume

#### Account channel events (private)

The `account` channel delivers per-entity events for your own orders and fills.
On subscribe, the server delivers an `account_snapshot` with your current open
orders and balance.

| Event                | When                            | Key fields                                   |
| -------------------- | ------------------------------- | -------------------------------------------- |
| `account_snapshot`   | On subscribe                    | Current open orders and balance              |
| `order_received`     | When a new order is accepted    | `orderId`, `status`                          |
| `order_modified`     | When an order fee is modified   | `orderId`, `feeBps`                          |
| `order_canceled`     | When a single order is canceled | `orderId`                                    |
| `order_canceled_all` | When cancel-all is called       | `orderIds`                                   |
| `account_cleared`    | When the auction clears         | `fills`, `forwardOrders`, `feesRebatedCents` |

Key fields on `account_cleared`:

* `fills`: array of per-order fill breakdowns, each with `filledAmount`,
  `unfilledAmount`, `clearingFeeBps`, and `matchedAt`
* `forwardOrders`: array of orders rolled into the next auction
* `feesRebatedCents`: signed integer; positive means a mint-side rebate,
  negative means a burn-side fee paid

### Step 4. Handle reconnection

If the connection drops, follow these steps to restore your subscription:

1. Create a new ticket using `POST /v1/match/ws/ticket`. The previous ticket is
   consumed or expired and cannot be reused.
2. Open a new socket using the new ticket as described in the preceding "Open
   the connection" and "Handle the hello frame and subscribe" sections.
3. Re-send `subscribe` messages for all channels you want to receive.
4. The server delivers a fresh `snapshot` (market) or `account_snapshot`
   (account) for each channel.

<Note>
  The server does not replay events missed during a disconnection. If your
  connection dropped while an auction was clearing and you missed the
  `account_cleared` event, call `GET /v1/match/orders` to reconcile any fills
  that occurred while you were offline.
</Note>
