Pro & API
Same book, same fee formula, same all-in numbers as the ticket. Over REST and a gapless WebSocket, with the request shapes your bots already speak.
Sign timestamp + METHOD + path with your Ed25519 key, without the query string. Timestamps must be within ±30 seconds. Exact duplicates (key, timestamp, signature and body hash) are refused as replays, so two different orders in the same millisecond both go through.
The WebSocket accepts the same signature as query parameters, so browsers can connect, and takes cancel_on_disconnect=true if you want your quotes pulled when the socket drops.
import crypto from "node:crypto";
const path = "/trade-api/v2/portfolio/events/orders";
const ts = String(Date.now()); // ms, within ±30 s
const sig = crypto
.sign(null, Buffer.from(ts + "POST" + path), key) // Ed25519, no query string
.toString("base64");
await fetch(BASE + path, {
method: "POST",
headers: {
"ONSIDE-ACCESS-KEY": keyId,
"ONSIDE-ACCESS-TIMESTAMP": ts,
"ONSIDE-ACCESS-SIGNATURE": sig,
"content-type": "application/json",
},
body: JSON.stringify({
ticker: "ONS-FED-26DEC-CUT",
side: "bid", // buy YES; "ask" = buy NO
count: "25.00", // *_fp: 2 dp
price: "0.7900", // *_dollars: 4 dp
time_in_force: "good_till_canceled",
post_only: true,
}),
});Already signing for another venue with the same scheme? Point your client at Onsides; the signature is identical.
Subscribe once, get the full book as a snapshot, then every change as a delta. Every message carries sid and a gapless seq: if you see a gap, resubscribe and you get a fresh snapshot. Snapshot plus deltas always equals the REST book.
→ {"id":1,"cmd":"subscribe",
"params":{"channels":["orderbook_delta","trade","ticker"],
"market_ticker":"ONS-FED-26DEC-CUT"}}
← {"type":"orderbook_snapshot","sid":1,"seq":1,
"msg":{"yes_dollars_fp":[["0.7900","53.00"],…],"no_dollars_fp":[…]}}
← {"type":"orderbook_delta","sid":1,"seq":2,
"msg":{"price_dollars":"0.8000","delta_fp":"-10.00","side":"yes"}}
← {"type":"trade","sid":2,"seq":1,
"msg":{"yes_price_dollars":"0.8000","count_fp":"10.00","taker_book_side":"ask"}}Taking liquidity costs the published formula, 7% × C × P × (1 − P), rounded up to $0.0001 per order. Resting liquidity that gets taken pays the market’s maker rate, which is zero on every listed market today. Check any size with fee_preview before you send it; the engine uses the same code.
Base path /trade-api/v2. JSON in, JSON out.
| Method | Path | What it does |
|---|---|---|
| GET | /markets | List markets with inside prices, volume, open interest |
| GET | /markets/{t}/orderbook | Full bid ladders for YES and NO |
| GET | /markets/{t}/fee_preview | Walk the book: avg price, fee, slippage, all-in |
| POST | /portfolio/events/orders | Place: GTC, IOC, FOK; post-only, reduce-only, STP |
| POST | /portfolio/events/orders/{id}/amend | Cancel-replace price or size |
| POST | /portfolio/events/orders/{id}/decrease | Reduce size, keep queue priority |
| DELETE | /portfolio/events/orders | Mass cancel, optionally by ticker |
| POST | /portfolio/order_groups/create | Contract limits across a group of orders |
| GET | /portfolio/fills | Every fill with its fee, to $0.0001 |
This is a simulated exchange. Keys, balances and fills are for testing and carry no cash value.