Skip to main content
The core of a market-making loop is one call: replace your entire ladder of two-sided quotes on a market in a single atomic operation. This page covers authentication, posting a ladder, and cancelling. All traffic goes through the OCX API gateway (one HTTPS base URL, referred to below as {API_BASE}). Prices and quantities are JSON strings (fixed-decimal).

Authentication

1

Get a nonce

POST {API_BASE}/auth/nonce
{ "walletAddress": "0x…" }  →  { "nonce": "…" }
2

Sign in with SIWE

Sign the EIP-4361 message (including the nonce) and verify:
POST {API_BASE}/auth/siwe
{ "message": "<SIWE message>", "signature": "0x…" }
This opens a session (cookie / JWT).
3

Mint an API key for automation

POST {API_BASE}/perps/me/api-keys
{ "name": "mm-bot-1", "scope": "trade", "allowedIps": ["203.0.113.7"], "expiresInDays": 90 }
The response includes a plaintext secretshown once only. Store it and send x-api-key: <secret> on every automated request.
The API-key secret is returned exactly once at creation and is never retrievable again. Store it in a secret manager. Pin allowedIps to your egress addresses and set expiresInDays for rotation. Keys carry a scope: use trade for quoting. Key creation and revocation are session-only — a key cannot manage keys.
The bulk-quote, cancel-all, and preview endpoints accept either a session cookie or an API key — the programmatic quoting path is fully API-key enabled.

Preview before you quote (optional)

Dry-run a prospective order to check sizing, fee, and margin with no side effects.
curl -s -X POST "{API_BASE}/perps/orders/preview" \
  -H "x-api-key: $OCX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"marketId":"BTC-PERP","side":"buy","type":"limit","price":"64990","quantity":"0.5"}'
notional
string
Order notional in quote currency.
marginRequired
string
Margin the order would consume.
estFee
string
Estimated fee for this fill.
feeBps
string
Fee in basis points at your tier.
feeRole
string
maker or taker.
user30dVolume
string
Your rolling 30-day volume (drives your tier).
approved
boolean
Whether the order would pass the margin gate.
reason
string
Rejection reason when approved is false.

Post and refresh a ladder

POST {API_BASE}/perps/quotes/bulkAuth: session or API key. Build a symmetric set of bid/ask levels around your fair value and submit them in one call. Set cancelAll: true to make the call an atomic replace: your prior resting quotes on that market are cancelled and the new ladder is placed in one operation. This is the standard way to re-quote each cycle without leaving stale orders behind.
marketId
string
required
The market to quote.
quoteId
string
Tags this quoting cycle so you can group/track/replace the batch.
cancelAll
boolean
When true, cancels your existing quotes on this market before placing the new ladder (atomic replace).
quotes
array
required
The ladder levels. Each entry accepts side (buy|sell), price, quantity, and optional clientOrderId, timeInForce, postOnly, reduceOnly, marginMode.
curl -s -X POST "{API_BASE}/perps/quotes/bulk" \
  -H "x-api-key: $OCX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "marketId": "BTC-PERP",
    "quoteId": "mm-cycle-000123",
    "cancelAll": true,
    "quotes": [
      { "side": "buy",  "price": "64990.0", "quantity": "0.50", "postOnly": true },
      { "side": "sell", "price": "65010.0", "quantity": "0.50", "postOnly": true },
      { "side": "buy",  "price": "64980.0", "quantity": "1.00", "postOnly": true },
      { "side": "sell", "price": "65020.0", "quantity": "1.00", "postOnly": true }
    ]
  }'
Keep postOnly: true on every quote level to guarantee you stay on the maker side — a postOnly order that would cross the book and take liquidity is rejected rather than executed as a taker.

Single-market convenience form

To place just one bid and one ask, use POST {API_BASE}/perps/quotes:
{
  "marketId": "BTC-PERP",
  "bid": { "price": "64990.0", "quantity": "0.5" },
  "ask": { "price": "65010.0", "quantity": "0.5" },
  "postOnly": true,
  "quoteId": "mm-single-1"
}

Cancel

Pull quotes on shutdown, on feed loss, or as a risk kill-switch.
POST {API_BASE}/perps/orders/cancel-allAuth: session or API key.Cancel all your resting orders, optionally scoped by marketId, quoteId, clientOrderId, or marginMode. Omit the body to cancel everything.
curl -s -X POST "{API_BASE}/perps/orders/cancel-all" \
  -H "x-api-key: $OCX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "marketId": "BTC-PERP" }'
The typical re-quote cycle is a single quotes/bulk call with cancelAll: true — you rarely need standalone cancels except as an emergency stop. Wire cancel-all to your dead-man switch (see Best practices).

Options quoting

The options CLOB exposes an equivalent bulk path at POST {API_BASE}/options/quotes/bulk (with POST {API_BASE}/quotes/bulk as an alias), accepting a session or API key. The single-quote form is POST {API_BASE}/options/quotes. The ladder shape and cancelAll replace semantics match the perp path above.