I get 403 when querying ETH but BTC works fine
The free tier only allows BTC (and km:US500 for HIP-3). All other symbols require Build tier or higher. Upgrade at /pricing or start a free 14-day Build trial.
HTTP status, JSON error bodies, and retry rules for client code and automation.
Treat errors as part of the API contract, not as a fallback path.
Every failed request returns a structured JSON body and a request identifier.
Use these buckets first.
| Class | What to do |
|---|---|
| Retry | Use bounded backoff for 429, 500, 502, 503, and transient network failures. |
| Do not retry | Fail fast on 400 and other validation errors until the request is corrected. |
| Check permissions | Use 401 and 403 to verify the API key, account state, or wallet-based access flow. |
| Check plan gate | When the route exists but access is denied, confirm whether the endpoint is gated by plan or depth level. |
Capture the response body and request identifier together.
{ "error": "Invalid API key", "code": 401, "request_id": "req_abc123xyz"}| Code | Name | What it means |
|---|---|---|
400 | Bad Request | Invalid request parameters or malformed request body |
401 | Unauthorized | Missing or invalid API key |
403 | Forbidden | API key lacks permission for this resource or tier limit exceeded |
404 | Not Found | Endpoint or resource does not exist |
429 | Too Many Requests | Rate limit exceeded. Check X-RateLimit-Reset header |
500 | Internal Server Error | Server error. Retry with exponential backoff |
503 | Service Unavailable | Service temporarily unavailable. Retry later |
Read the headers so 429 handling is deterministic.
X-RateLimit-Limit: 50 # Requests per second allowedX-RateLimit-Remaining: 47 # Requests remaining this secondX-RateLimit-Reset: 1704067200 # Unix timestamp when limit resetsX-Credits-Limit: 10000000 # Monthly credit limitX-Credits-Used: 500000 # Credits used this monthX-Credits-Remaining: 9500000 # Credits remaining this monthX-Credits-Reset: 1706745600 # Unix timestamp for credit resetRetry transient failures. Fail fast on auth, permissions, and validation issues.
import timeimport requests
def request_with_retry(url, headers, max_retries=3): for attempt in range(max_retries): response = requests.get(url, headers=headers)
if response.status_code == 200: return response.json()
if response.status_code == 429: # Rate limited - wait and retry reset_time = int(response.headers.get('X-RateLimit-Reset', 0)) wait = max(reset_time - time.time(), 1) time.sleep(wait) elif response.status_code >= 500: # Server error - exponential backoff time.sleep(2 ** attempt) else: # Client error - don't retry response.raise_for_status()
raise Exception("Max retries exceeded")The free tier only allows BTC (and km:US500 for HIP-3). All other symbols require Build tier or higher. Upgrade at /pricing or start a free 14-day Build trial.
HIP-3 orderbook and orderbook history require Pro tier or higher. Other HIP-3 endpoints (trades, candles, funding, OI) work on Build tier. Free tier is limited to km:US500.
Free tier limits each request to a 30-day time window. Split large queries into 30-day chunks with cursor pagination, or upgrade to Build+ for unlimited per-request ranges.
You may be hitting the concurrent query limit (3 for Free, 10 for Build). This limits how many requests can be in-flight at the same time. Wait for pending requests to complete before sending new ones, or reduce parallelism.
The server sends ping frames every 30 seconds. Your client must respond with pong frames (most libraries do this automatically). Connections without a pong response within 60 seconds are terminated. If your library doesn't handle pings, send {"op": "ping"} periodically.
The ticker, all_tickers, l4_diffs, l4_orders, hip3_l4_diffs, and hip3_l4_orders channels are real-time only and cannot be replayed. Use the REST API for historical L4 data.
Hyperliquid candles are available from March 2025 onwards. For earlier price history, use the /prices endpoint or orderbook-derived series instead of candle replay.
Free tier only gets checkpoint-level snapshots. Paid tiers unlock finer L2 granularity, and tick reconstruction is Enterprise-only. The granularity parameter is tier-restricted, not credit-restricted.
Credits and rate limits are separate. Credits reset monthly, but rate limits (requests/second) and concurrent query limits apply continuously. Check the X-RateLimit-Remaining header to distinguish between credit exhaustion and rate limiting.
Fills before March 2025 were backfilled from Hyperliquid's REST API which only returns taker-side data. Maker/taker attribution with both addresses is available from March 2025 onward (S3 source data).
The 0xArchive API never accepts the raw @<index> form in URLs. Use the named dashed pair instead (e.g., /v1/hyperliquid/spot/orderbook/PURR-USDC). The server resolves the wire format (PURR/USDC, @107) internally; @-prefixed identifiers are only useful as documentation references.
Roughly 31% of spot fills carry a zero tx_hash; the remaining ~69% carry a real EVM hash. Treat tx_hash as optional on spot fills. Perp fills are all-zero by design — only spot trades surface the on-chain hash.
Spot fee_token is open-set: USDC, PURR, HYPE, KHYPE, USOL, and others. Validate the token rather than assuming USDC. Perp fills are always USDC-denominated.
Spot candles are arriving soon. In the meantime, build OHLCV client-side from /v1/hyperliquid/spot/trades/{symbol}. Hyperliquid does not publish spot candles upstream, so 0xArchive is rolling its own aggregation.
Hyperliquid does not publish historical spot orderbook data. /v1/hyperliquid/spot/orderbook and /v1/hyperliquid/spot/orderbook/{symbol}/l4* are live-only from 2026-05-05 forward. Spot trades are backfilled to 2025-03-22; older data is unrecoverable from any free public archive.