# RAETH Exchange > RAETH is a high-frequency prediction market — "Trade fast. Trade often." It is a testnet CLOB (central-limit-order-book) venue whose single live product is a rolling **60-second BTC up/down binary** (the 1-minute window — series `btc-up-down-1m`): a real order book, a fresh round every 60 seconds, two-phase on-close settlement, and RLP house liquidity. Humans-first — a pro terminal anyone can trade by hand — with agents fully supported (SDK, MCP, API). Everything else (BTC perp, BTC parlays, the 5m/1h binary windows, the 60s parimutuel, sports) is dormant roadmap, gated off. Prices are integer instrument units; always read `market.geometry`/`agent-context.geometry` for `price_scale`, grid, band, and payout instead of assuming cents. Money fields are integer cents on normal responses and may become decimal strings once they exceed JavaScript's safe integer range; parse before summing. This file is the agent-pullable index. The full, self-contained reference an agent can operate from end to end is `/llms-full.txt`. No real money is deposited or traded. - REST base URL: `https://raeth.exchange/api/v1` (canonical stable client prefix; bare `/api` aliases still exist for compatibility) - WebSocket: `wss://raeth.exchange/stream` - Auth: `Authorization: Bearer rk_live_…` on every request - Machine-readable spec: `https://raeth.exchange/api/openapi.json` · Swagger UI: `https://raeth.exchange/api/docs` ## Quickstart for agents 1. **Get a key.** Local/dev stacks can mint an account + primary agent + `read+trade` key in one call (grants $10,000 / 1,000,000¢ testnet cash). Production with Google OAuth enabled requires browser OAuth first — passwordless `mcp-signup` for a new email is rejected; use `/auth/google` or an existing password-backed account with `password`. The plaintext `api_key` is returned ONCE — store it. ```bash curl -s -X POST https://raeth.exchange/api/v1/auth/mcp-signup \ -H "Content-Type: application/json" \ -d '{"email":"you@example.com","agent_name":"my-first-bot","password":"existing-account-password"}' # → { "agent_id":"…", "api_key":"rk_live_…", "paper_cash_cents":1000000, … } ``` 2. **Find the market to trade.** The live product is the rolling **BTC 60-second up/down binary**. One read returns the active window's `market_id`, top-of-book, time-to-close, and a `seq_at_snapshot` ledger anchor for at-least-once WS resume: ```bash curl -s "https://raeth.exchange/api/v1/series/btc-up-down-1m/context" \ -H "Authorization: Bearer rk_live_…" # → { "active_window": { "market_id":"…", "best_bid_cents":52, "best_ask_cents":55, … }, "seq_at_snapshot":482910, … } ``` The series re-lists a fresh market every 60 seconds — always read the series context endpoint above for the ACTIVE window and trade `active_window.market_id`. (BTC perp, BTC parlays, the 5m/1h binary windows, and the 60s parimutuel are dormant roadmap, gated off — see "Dormant / roadmap" below. Their REST/MCP surface is documented in `/llms-full.txt` for completeness but is not currently tradeable.) 3. **Read the book** (public; no key required, but a key adds `self_role` on trades): ```bash curl -s "https://raeth.exchange/api/v1/markets/{market_id}/book?depth=20" # → { "bids":[[44,15],…], "asks":[[51,12],…], "seq_at_snapshot":84721 } ← [price_cents, total_qty] ``` 4. **Place an order.** `market_id`, `side` (BUY/SELL), `type` (LIMIT/MARKET), `qty` required; LIMIT requires `price` in the market's scaled price units. `client_order_id` makes retries idempotent. `tif` defaults to GTC (IOC/FOK/POST_ONLY/GTT/GTD also valid). ```bash curl -s -X POST https://raeth.exchange/api/v1/orders \ -H "Authorization: Bearer rk_live_…" -H "Content-Type: application/json" \ -d '{"market_id":"…","side":"BUY","type":"LIMIT","tif":"GTC","price":53,"qty":10,"client_order_id":"my-bot-001"}' # → { "order_id":"…", "status":"NEW", "filled_qty":0, "remaining_qty":10, "fills":[] } ``` 5. **Read positions & account:** ```bash curl -s "https://raeth.exchange/api/v1/account" -H "Authorization: Bearer rk_live_…" # → { "cash_cents":…, "equity_cents":…, "total_pnl_cents":…, "positions":[…] } ``` Position readback is also available at `GET /api/v1/positions`. (The perp-only endpoints — funding at `GET /api/v1/funding/{market_id}/current` and `/history`, `reduce_only` closes, `slippage_cap_bps` MARKET protection — belong to the dormant perp roadmap; the live 60s binary has no leverage, funding, or liquidation, and worst-case loss per contract is bounded.) 6. **Cancel / amend / triggers:** `DELETE /api/v1/orders/{order_id}` (one) · `DELETE /api/v1/orders` (mass; `?market_id=…` to scope) · amend a resting LIMIT with `POST /api/v1/orders/{order_id}/amend` (`{"price":…}` and/or `{"qty":…}`) · atomically apply a SET of your own cancel/amend/place legs to one market all-or-nothing with `POST /api/v1/orders/batch-modify` (`{market_id, legs:[…], client_batch_id?}` — Hyperliquid-style batchModify, cap `EXTERNAL_BATCH_MODIFY_MAX`≈20, idempotent on `client_batch_id`) · for market-making, replace your WHOLE two-sided resting ladder in one call per tick with `POST /api/v1/orders/replace-ladder` (`{market_id, target_levels:[{side,price,qty}], client_batch_id, fail_mode?}` — empty `target_levels` cancels all your resting orders; metered by emitted-work admission, no special lane). Reduce-only TP/SL trigger orders (`POST/GET/DELETE /api/v1/trigger-orders`; `?status=PENDING` for pending) are perp-scoped — see "Dormant / roadmap". 7. **Stream in real time.** Public channels (`book.`, `trades.`, `series.`, `feed.btc`, `markets`, `leaderboard.v1`) need no auth. The `private.` channel (your fills/orders/positions) needs a 60-second single-use ticket from `POST /api/v1/auth/ws-ticket` — mint a FRESH ticket before every (re)connect; never reuse one. After any disconnect, re-subscribe with `since_seq` = the last `seq` you saw. Replay is at-least-once; ignore duplicate/stale seqs you already applied. Each LIVE data frame also carries `channel_seq` (`{channel:{seqId,prevSeqId}}`): chain per channel — if an incoming `prevSeqId` != your last-seen `seqId` for that channel, a live event was missed (refetch that surface). This catches gaps the global `seq` resume can't (e.g. the cross-market `private.account.` channel). If the server sends `{"op":"resync_required","code":"WS_REPLAY_TRUNCATED"}` or `{"op":"resync_required","code":"BROADCAST_QUEUE_OVERFLOW"}`, refetch dependent REST snapshots (`/book`, trades, account/positions/fills) before trusting local state again. **Execution lifecycle without polling:** `private.` delivers every order event — `ORDER_PLACED` (status=NEW/PARTIAL=ack, status=REJECTED=engine-reject with `reject_reason`), `ORDER_REJECTED` (pre-trade reject, top-level `client_order_id` for correlation; `order_id` is null — no engine id minted), and `TRADE_EXECUTED` (per-fill; aggregate by order_id for cumulative filled/avg price). REST order polling is only needed for recovery after a gap. ```json { "op":"subscribe", "channels":["book.","trades.","private."], "since_seq":482910 } ``` 8. **Leaderboard.** `GET /api/v1/leaderboard` returns account standings ranked by `net_pnl_cents` (= `trading_pnl + maker_rebate + lp_rewards − fees`, integer minor units). This is identical to the portfolio net PnL — one ledger view, no separate scoring. Each row has `public_id` (opaque 16-char hex, not the raw UUID) and `display_name` (pseudonymous — never an email local-part). Use `public_id` as the key for `GET /api/v1/leaderboard/account/{public_id}`. `GET /api/v1/season/current/rules` for the season window and fee model. ## Dormant / roadmap (gated off) The only live, tradeable market is the 60-second BTC up/down binary above. The instruments below are built but gated off — their REST/MCP surface still exists and is documented in `/llms-full.txt`, but they are NOT currently tradeable; do not route live orders to them: - **BTC linear perp** — leverage, margin modes, funding (`GET /api/v1/funding/{market_id}/…`), and reduce-only TP/SL trigger orders (`POST/GET/DELETE /api/v1/trigger-orders`; MCP `place_trigger_order`/`list_trigger_orders`/`cancel_trigger_order`). - **BTC parlays** — `POST /api/v1/parlays/quote` → `POST /api/v1/parlays` (2-5 binary legs; direction/correlation-aware quotes that expire after 10s, booked against `rlp-parlay-desk@`); MCP `quote_parlay`/`book_parlay`/`list_parlays`. - **Other binary windows** — the 5m / 1h `btc-up-down-*` series. - **60s BTC parimutuel** and **sports** markets. ## Error envelope & rate limits - Every 4xx/5xx (auth, rate-limit, not-found, validation, …) is the SAME flat envelope `{ "code":"…", "message":"…", "request_id":"…" }` — never nested under a `detail` key. - Some codes add a `details` (plural) key alongside: a leverage-cap `422` carries `"details":{ "requested_leverage":50, "effective_leverage":40 }`; a schema-validation `422` carries the pydantic error list under `details`. A `429` adds top-level `retry_after_s`. - Engine rejections return **HTTP 200** with `status:"REJECTED"` + a machine-readable `reject_reason` (e.g. `POST_ONLY_WOULD_CROSS`, `INSUFFICIENT_MARGIN`, `MARKET_CLOSED`, `PRICE_OUT_OF_RANGE`). - Rate limits per agent: **600 writes/min · 6,000 reads/min**. On `429`, respect `Retry-After` (seconds) and back off exponentially from 1s. ## Reference - [Full agent reference (self-contained markdown)](https://raeth.exchange/llms-full.txt): operate end to end from this one file. - [OpenAPI 3.1 schema](https://raeth.exchange/api/openapi.json): every path, parameter, and schema, always current. - [Docs home](https://raeth.exchange/docs): three separate surfaces — User Guide, For Trading Agents, and API Reference. - [Quickstart (human docs)](https://raeth.exchange/docs/quickstart): signup → key → order → settle. - [Authentication](https://raeth.exchange/docs/authentication): API keys, scopes, Bearer auth, WS tickets, rate limits. - [Market data](https://raeth.exchange/docs/market-data): list markets, order book, trades, candles, series context, BTC spot, BTC spot OHLC candles (`GET /feed/btc-spot/candles`, public, no auth, period_seconds/limit params; sealed candles are immutable and never repaint — each carries a `corrected` boolean that surfaces a late divergence instead of moving the bar). - [Order schema](https://raeth.exchange/docs/reference/orders): canonical place-order request/response, field by field. - [WebSocket](https://raeth.exchange/docs/websocket): connect, ticket auth, subscribe, resume by seq, channel + event reference. - [Agents & SDKs](https://raeth.exchange/docs/agents): MCP tool catalog, Python + TypeScript SDKs, registering a bot. - [Errors & limits](https://raeth.exchange/docs/errors): the reject-reason taxonomy and HTTP error codes. - [Fees & rewards](https://raeth.exchange/docs/fees): zero maker fees, taker formulas with worked examples, maker rebates, and public fee endpoints. - [Settlement & resolution](https://raeth.exchange/docs/settlement): boundary snapshots, the >=open tie rule, voids, perp mark/funding, and parlay resolution. - [Strategy templates](https://raeth.exchange/docs/strategies): launch-supported maker/taker templates runnable as-is. - [Strategy: lead-lag taker](https://raeth.exchange/docs/strategies/lead-lag-taker): IOC into the slower book's stale quotes when the leader moves. - [Strategy: lead-lag maker](https://raeth.exchange/docs/strategies/lead-lag-maker): anchor resting quotes to the faster venue's mid. - [Strategy: grid trading](https://raeth.exchange/docs/strategies/grid-trading): paired-fill ladder with a hard range stop. - [Strategy: short-vol 95c](https://raeth.exchange/docs/strategies/short-vol): sell the late-window lottery tail with an automated bail-out. - [Connect via MCP](https://raeth.exchange/docs/mcp): remote MCP server, OAuth in one click, first tool-calling session. - [Architecture & integrity](https://raeth.exchange/docs/architecture): integer money math, event-sourced ledger, live invariant verification.