On this page
Orderbook Snapshot Across Providers
This recipe shows how to pull a single live orderbook snapshot from each of
the four providers using only curl + jq. It demonstrates the { native, meta } envelope and highlights the per-provider shape differences you'll
deal with until Normalized responses.
Prerequisites
- Artery API running locally on
:3500 - An API key with the
readscope
bashTOKEN=$(curl -sS -X POST https://api.artery.questflow.ai/keys \
-H "Content-Type: application/json" \
-d '{"name":"snapshot-recipe","userId":"u-1","scopes":["read"]}' \
| jq -r .plaintext)
echo "Token: $TOKEN"The script
bash#!/usr/bin/env bash
set -euo pipefail
API=https://api.artery.questflow.ai
TOKEN=${TOKEN:?set TOKEN env var}
# 1) Pick a Polymarket market
MARKET=$(curl -sS "$API/v1/polymarket/markets?active=true&limit=1" \
-H "Authorization: Bearer $TOKEN" | jq -r '.native[0].condition_id')
TOKEN_ID=$(curl -sS "$API/v1/polymarket/markets/$MARKET" \
-H "Authorization: Bearer $TOKEN" | jq -r '.native.tokens[0].token_id')
echo "─── Polymarket ────────────────────────────────────────"
curl -sS "$API/v1/polymarket/clob/book?token_id=$TOKEN_ID" \
-H "Authorization: Bearer $TOKEN" | jq '{bids: .native.bids[0:3], asks: .native.asks[0:3], meta}'
# 2) Kalshi — pick the first open market
KALSHI_TICKER=$(curl -sS "$API/v1/kalshi/markets?status=open&limit=1" \
-H "Authorization: Bearer $TOKEN" | jq -r '.native.markets[0].ticker')
echo "─── Kalshi ────────────────────────────────────────────"
curl -sS "$API/v1/kalshi/markets/$KALSHI_TICKER/orderbook" \
-H "Authorization: Bearer $TOKEN" \
| jq '{yes: .native.orderbook.yes[0:3], no: .native.orderbook.no[0:3], meta}'
# 3) Hyperliquid main perp
echo "─── Hyperliquid (BTC perp) ────────────────────────────"
curl -sS "$API/v1/hyperliquid/info/l2-book?coin=BTC" \
-H "Authorization: Bearer $TOKEN" \
| jq '{bids: .native.levels[0][0:3], asks: .native.levels[1][0:3], meta}'
# 4) Hyperliquid HIP-4 outcome
HIP4_ASSET=$(curl -sS "$API/v1/hyperliquid/hip4/outcome-meta" \
-H "Authorization: Bearer $TOKEN" | jq -r '.native.outcomes[0].yesAssetId')
echo "─── Hyperliquid HIP-4 (asset $HIP4_ASSET) ─────────────"
curl -sS "$API/v1/hyperliquid/info/l2-book?coin=$HIP4_ASSET" \
-H "Authorization: Bearer $TOKEN" \
| jq '{bids: .native.levels[0][0:3], asks: .native.levels[1][0:3], meta}'Save as snapshot.sh, chmod +x, and run.
Sample output
─── Polymarket ────────────────────────────────────────
{
"bids": [
{ "price": "0.62", "size": "1234.5" },
{ "price": "0.61", "size": " 980.2" },
{ "price": "0.60", "size": "1500.0" }
],
"asks": [
{ "price": "0.63", "size": " 800.0" },
{ "price": "0.64", "size": "1200.0" },
{ "price": "0.65", "size": " 50.0" }
],
"meta": { "provider": "polymarket", "fetchedAt": "2026-05-08T12:00:00.000Z", "source": "live" }
}
─── Kalshi ────────────────────────────────────────────
{
"yes": [ [62, 100], [61, 200] ],
"no": [ [38, 150], [37, 220] ],
"meta": { "provider": "kalshi", ... }
}
─── Hyperliquid (BTC perp) ────────────────────────────
{
"bids": [
{ "px": "67500.0", "sz": "1.234", "n": 5 }
],
...
}
Shape differences to notice
Tip
This is exactly the kind of divergence the native vs normalized
concept discusses. Same logical concept (an orderbook), four
different shapes. A single normalized layer would hide useful upstream fields like Kalshi's
two-sided arbitrage or Hyperliquid's n (order count per level).
| Concept | Polymarket | Kalshi | Hyperliquid |
|---|---|---|---|
| Price field | price (string, dollar-denom) | array index 0 (int, cents) | px (string, units) |
| Size field | size (string) | array index 1 (int, contracts) | sz (string) |
| Bid/ask separation | bids / asks arrays | yes / no (sums to $1) | levels[0] / levels[1] |
| Order count per level | not exposed | not exposed | n |
Streaming continuation
Once you're happy with the snapshot shape, the streaming quickstart
shows how to subscribe to live deltas across the same providers via
/v1/stream WebSocket.
See also
- Cross-platform arbitrage — using these snapshots to find spreads
- Adapter contract — the envelope shape
Edit this page on GitHubLast updated