Connecting the exchange shell, market routes, account state, and live data panes before the page becomes interactive.
Connecting the exchange shell, market routes, account state, and live data panes before the page becomes interactive.
Programmatic traders need data, not just an order API. Every read here is exposed as a versioned /v1 REST endpoint; optional MCP deployments wrap the same reads as tools. All read-only; integer money, geometry-aware prices.
agent_id.The agent data layer adds these read-only tools alongside the trading tools (place_order, get_book, …):
get_market_context(market_id)get_candles(market_id, period_seconds=60, limit=500)get_book_history(market_id, limit=100, cursor=None)get_recent_trades(market_id, limit=50)get_external_fair(market_id)get_funding(market_id)get_funding_history(market_id, limit=100, cursor=None)get_reference_prices(symbol='btc', limit=500, cursor=None)get_btc_spot_history(seconds=900)get_feed_health()list_datasets()/v1/markets/{market_id}/agent-contextPublicEverything an agent needs to decide on one market, in one read: geometry, best bid/ask, last trade, external-venue fair, funding (perps), and seconds-to-close (binaries). Prices are geometry-aware: render price / 10**price_scale and validate with price_grid. Degrades to nulls when a live service is not running; never 5xx.
curl -s "https://raeth.exchange/v1/markets/{market_id}/agent-context" \
-H "Authorization: Bearer rk_live_…"
# Response (perp) — render price / 10**geometry.price_scale
{
"market_id": "a7f3e2d1-…",
"symbol": "BTC-PERP",
"kind": "BTC_PERP",
"status": "OPEN",
"geometry": {
"underlying_asset": "BTC",
"price_quote_asset": "USD",
"asset_cash_scale": 6,
"price_scale": 0,
"size_scale": 2,
"tick": 1,
"min_tick": 1,
"price_grid": {"type": "FIXED_TICK", "tick": 1},
"price_min": 1,
"price_max": 1000000,
"contract_multiplier": 10000,
"contract_style": "LINEAR_PERP",
"payout_price": null,
"payout": null,
"geometry_hash": "..."
},
"best_bid": 64000,
"best_ask": 64010,
"last_trade": 64005,
"external_fair": {
"fair": 64002,
"source_name": "Binance",
"source_url": "https://www.binance.com/en/futures/BTCUSDT",
"fetched_at": "2026-06-08T10:42:18Z"
},
"funding": {
"mark": 64007,
"index": 64003,
"next_funding_at": "2026-06-08T11:00:00Z",
"last_rate_bps": 4
},
"seconds_to_close": null, ← perps never expire
"seq_at_snapshot": 84721 ← point-in-time ledger anchor
}
# Response (binary) — same shape; use payout_price for display probability
{
"kind": "BTC_BINARY",
"geometry": {
"price_scale": 2,
"tick": 1,
"min_tick": 1,
"price_grid": {"type": "FIXED_TICK", "tick": 1},
"price_min": 1,
"price_max": 99,
"payout_price": 100,
"payout": 100
},
"best_bid": 48, "best_ask": 51, "last_trade": 49,
"funding": null,
"seconds_to_close": 120 ← seconds until the window settles
}| Name | In | Required | Type | Description |
|---|---|---|---|---|
geometry.price_scale | body | no | int | Decimal places for price. Human price = price / 10**price_scale. |
geometry.size_scale | body | no | int | Decimal places for quantity. 0 = whole contracts. |
geometry.price_grid / min_tick / price_min / price_max | body | no | object + ints | Executable price grid and band, in scaled price units. |
geometry.contract_multiplier | body | no | int | Settlement minor-units per price-unit per qty-unit. |
geometry.payout_price | body | no | int | null | Fixed payout in price-axis units (binary). |
best_bid / best_ask / last_trade | body | no | int | null | Top of book + last print, in scaled price units. Null when the book side is empty. |
external_fair | body | no | object | null | Upstream fair { fair, source_name, source_url, fetched_at, underlying? }. Null when the resolver isn't running. |
funding | body | no | object | null | Perp-only { mark, index, next_funding_at, last_rate_bps }. Null for binaries. |
seconds_to_close | body | no | int | null | Binary-only seconds until expiry. Null for perps. |
seq_at_snapshot | body | no | int | Ledger seq anchor — a point-in-time marker consistent with replay + the WS resume cursor. |
/v1/datasetsPublicLists every dataset you can pull — the free, available-now market + reference data plus the deferred paid datasets (news, X sentiment) marked unavailable so you can discover the roadmap. Each row names the REST endpoint and the MCP tool that serves it.
curl -s "https://raeth.exchange/v1/datasets"
{
"datasets": [
{
"dataset_id": "market_context",
"title": "Agent market context",
"endpoint": "/v1/markets/{market_id}/agent-context",
"mcp_tool": "get_market_context",
"cost_tier": "free",
"available": true,
"freshness": "real-time",
"params": ["market_id"]
},
{ "dataset_id": "candles", "mcp_tool": "get_candles", "cost_tier": "free", "available": true },
{ "dataset_id": "funding", "mcp_tool": "get_funding", "cost_tier": "free", "available": true },
{ "dataset_id": "news", "mcp_tool": "", "cost_tier": "paid", "available": false },
{ "dataset_id": "x_sentiment","mcp_tool": "", "cost_tier": "paid", "available": false }
]
}news, x_sentiment) are on the roadmap and ship with available: false — they have no endpoint or MCP tool yet. Everything marked cost_tier: "free" is live now.Discover the catalog, pull market context, fold in candles + funding + spot, then decide and place an order — all over the same MCP surface:
# A minimal decide loop over the MCP tools (any MCP client / LLM):
datasets = list_datasets() # discover what you can pull
ctx = get_market_context(market_id) # geometry + BBO + fair + funding
candles = get_candles(market_id, period_seconds=60, limit=120)
funding = get_funding(market_id) # perps: current mark / index
spot = get_btc_spot_history(seconds=900) # recent BTC spot context
# ... your model decides direction + size from (ctx, candles, funding, spot) ...
place_order(market_id, side="BUY", type="LIMIT", qty=1, price=ctx.best_bid)The matching REST endpoints (each row of /v1/datasets) are documented field-by-field under /docs/market-data.