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

# Quoting binary options

> The market-maker pipe: leased sessions, atomic ladders, server-side expiry and an ordered event stream

Designated market makers quote binary options through a dedicated API at `https://auth.ocx.global/binary/mm`. Access is by an **API key issued by OCX**, sent on every request as `x-api-key`. The key is bound to a market-making account whose binary cash is pre-funded; quoting does not use your wallet. Quota: 1,200 requests a minute per key.

> [!NOTE]
>
> Quotes are **Up** prices in cents, 1–99. A **bid** buys Up; an **ask** sells Up, which is the same as buying Down at `100 − price`. Reference prices are integer **ticks with 3 decimals** (7751.375 → `7751375`). Times are epoch milliseconds.

## Session and lease

**1. Open**

`POST /session` `{ "lease_ms": 2000 }` → `{ session_id, lease_ms, max_quote_ttl_ms: 5000, server_ms }`. `lease_ms` is 500–10,000.

**2. Keep it alive**

`POST /heartbeat` `{ "session_id" }` within every lease. An accepted quote also counts as a heartbeat.

**3. Lose it, lose your quotes**

If nothing arrives within the lease, OCX cancels **every** quote on the account (`cancelled`, reason `lease`) and the session is dead: open a new one. A service restart also closes all sessions.

**4. Close**

`POST /session/close` `{ "session_id" }` cancels your quotes and ends the session.

## Quote

`POST /quote` replaces your whole ladder on one window.

**request\_id** `string` *required*

Unique per request. A retry with the same id returns the original receipt with `"replay": true`; the same id with another window or sequence is refused (`409`).

**session\_id** `string` *required*

A live session.

**cid** `string` *required*

The window, e.g. `SPX-15M-20261029-0930`. It must be `open` and before its cutoff.

**quote\_seq** `number` *required*

Positive, and strictly greater than the last accepted for this session and window (`409 STALE_QUOTE_SEQ`).

**valid\_until\_ms** `number` *required*

Server-side expiry, in the future and at most 5,000 ms ahead.

**bids / asks** `array` *required*

`[{ "price_cents", "quantity" }]`, at most 5 levels a side, best first, distinct, not crossed. Empty arrays pull the ladder.

```bash cURL theme={null}
curl -s -X POST https://auth.ocx.global/binary/mm/quote \
  -H "x-api-key: $KEY" -H "Content-Type: application/json" -d '{
  "request_id": "q-000123", "session_id": "…", "cid": "SPX-15M-20261029-0930",
  "quote_seq": 7, "valid_until_ms": 1793266400000,
  "bids": [{ "price_cents": 48, "quantity": 50 }, { "price_cents": 47, "quantity": 100 }],
  "asks": [{ "price_cents": 52, "quantity": 50 }] }'
```

```json Receipt theme={null}
{ "event_seq": 4812, "request_id": "q-000123", "cid": "SPX-15M-20261029-0930", "quote_seq": 7 }
```

**Guarantees**

* **Atomic.** The previous ladder comes off and the new one goes on in one transaction. A refused quote leaves the previous ladder untouched.
* **Fills before the receipt.** A ladder that crosses resting orders trades immediately. Those fills, and everything before them, are in the event stream at or below the receipt's `event_seq`.
* **Server-side expiry.** At `valid_until_ms` the levels stop trading and are removed (`cancelled`, reason `expired`), even if your process is gone.
* **Cancel on disconnect.** Through the lease, above.
* Your fills are tagged with the `quote_seq` of the ladder they came from.

`POST /cancel` `{ "cid"? }` pulls one window, or every window.

## Event stream

`GET /events?after={event_seq}&limit=500` → `{ events: [{ event_seq, server_ms, event: { type, … } }], watermark }`. Poll with `after` = the last `watermark`. `event_seq` order is commit order, without gaps.

| `type` | Fields |
| - | - |
| `listed` | `market: { product, future_id, cid, start_ms, cutoff_ms, expiry_ms }` |
| `activated` | `cid`, `strike_ticks` |
| `quote_accepted` | `request_id`, `session_id`, `cid`, `quote_seq`, `valid_until_ms`, `crossed_quantity` |
| `fill` | `exec_id`, `cid`, `order_id`, `quote_seq`, `maker`, `taker`, `mm_side` (`buy`/`sell` Up), `price_cents` (Up), `quantity`, `liquidity` |
| `cancelled` | `cid`, `quote_seq`, `reason` (`replaced`, `expired`, `lease`, `cutoff`, `cancel`, `session_closed`), `orders` |
| `settled` | `cid`, `outcome` (`up`/`down`/`void`), `value_ticks`, `up_payout_cents` (100, 0 or 50) |

`listed`, `activated` and `settled` are public to every key; the rest are your account's.

## Reference, windows, snapshot

| Endpoint | Returns |
| - | - |
| `GET /reference` | Per product: `product`, `future_id`, `ticks`, `bid_ticks`, `ask_ticks`, `sample_ms`, `source_ms`, `session_open`. Refreshed every second, also when the price is unchanged. |
| `GET /markets` | Unsettled windows: `cid`, `product`, `future_id`, `status` (`listed`/`open`/`closed`), `start_ms`, `cutoff_ms`, `expiry_ms`, `strike_ticks`. |
| `GET /snapshot` | `watermark`, `server_ms`, `account: { cash_cents, positions: { cid: { up, down, quantity } } }`, and your resting `quotes`. After a reconnect: read the snapshot, then the stream from its `watermark`. |

## Errors

`{ "message" }` with `400` (invalid request), `401` (unknown key), `403` (account not set up for quoting), `409` (window not open, stale `quote_seq`, session expired, `request_id` reused) or `429` (quota).


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