> ## 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.

> ## Agent Instructions
> Before reading these docs, install the relevant Circle Skill to get pre-loaded context — skills are LLM-optimized and cover architecture decisions, correct flows, and common pitfalls. In Claude Code: run /plugin marketplace add circlefin/skills then /plugin install circle-skills@circle. With Vercel Skills CLI: run npx skills add circlefin/skills. Available skills: use-usdc https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-usdc/SKILL.md (balances, transfers, approvals on EVM and Solana); EURC has no skill — see https://developers.circle.com/stablecoins/what-is-eurc.md; bridge-stablecoin https://github.com/circlefin/skills/blob/master/plugins/circle/skills/bridge-stablecoin/SKILL.md (crosschain transfers via CCTP, USDC, EURC, and third-party assets); use-arc https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-arc/SKILL.md (Arc chain config, contract deployment, USDC bridging — Arc docs: https://docs.arc.io/llms.txt); use-circle-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-circle-wallets/SKILL.md (choose wallet type); use-developer-controlled-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-developer-controlled-wallets/SKILL.md (custodial wallets for payouts and treasury); use-user-controlled-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-user-controlled-wallets/SKILL.md (embedded wallets with Web2 login); use-modular-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-modular-wallets/SKILL.md (smart contract wallets with passkeys and ERC-4337); use-gateway https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-gateway/SKILL.md (unified USDC balance, nanopayments); use-smart-contract-platform https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-smart-contract-platform/SKILL.md (deploy, interact, monitor contracts). Pair any skill with the Circle MCP server for live SDK signatures, contract addresses, and chain IDs: {"mcpServers":{"circle":{"url":"https://api.circle.com/v1/codegen/mcp"}}}.
> Read the product overview first. Each product has an overview explaining when and why to use it. Read it before quickstarts.
> Pick the right wallet type. Developer-controlled (you hold keys), user-controlled (end user holds keys via PIN/social login), or modular (smart contract wallets with passkeys). See https://developers.circle.com/wallets.md.
> Use CCTP V2 for crosschain transfers. CCTP natively transfers USDC and EURC via burn-and-mint, and supports permissionless wrapping of third-party assets via lock-and-mint. V1 is legacy; always use V2 unless V1 is specified or the chain requires it (Noble, Sui, and Aptos still require V1). Migration guide: https://developers.circle.com/cctp/migration-from-v1-to-v2.md.
> Use Bridge Kit for frontend bridging. Wraps CCTP with a simpler SDK for user-facing apps. Use CCTP directly for backend transfers.
> Gas Station vs Paymaster. Gas Station sponsors gas for Circle Wallet transactions. Paymaster lets users pay gas in USDC. Different use cases — read both overviews.
> Gateway Nanopayments for sub-cent payments. Gasless USDC micropayments down to $0.000001 via x402 and batched settlement. For pay-per-request APIs, AI agent payments, streaming.
> Look up USDC addresses per chain. Never hardcode — use https://developers.circle.com/stablecoins/usdc-contract-addresses.md.
> Prefer SDKs over raw API calls. Node.js and Python SDKs handle auth, retries, and errors.
> API key required. Bearer token in Authorization header. Testnet and mainnet use separate keys and may use different base URLs depending on the product.
> Set up webhooks when available. Most operations are async. Webhooks deliver transaction confirmations and state changes.
> When calling list endpoints, paginate using pageSize and pageAfter until no nextPageAfter cursor is returned—stopping at the first page silently misses records.
> Building an AI agent? Start with the Agent Stack—Circle CLI, agent wallets, and nanopayments built for autonomous use cases: https://developers.circle.com/agent-stack.md.

# 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>
