Skip to main content
You get 100 requests per minute on a sliding window. The limit is per user, shared across every key and every endpoint. Batch read endpoints (e.g. POST /api/v1/traders/batch, POST /api/v1/markets/intel/batch) get a separate budget in item units, also 100 per minute. A 25-item batch reserves 25 item units before it runs. GET /api/v1/usage does not spend primary quota or log into daily usage. It has its own 100 reads/minute per-user guard so checking quota can’t itself blow up usage-count load.

Headers you should read

Every authenticated response carries:
Batch responses additionally carry: Browser clients can read these headers on public REST /api/v1/* responses because the public API exposes them through CORS. The public API also exposes Retry-After, ETag, X-Request-Id, X-Request-Cost, Mcp-Session-Id, and X-Mcp-Error-Code. Remote MCP at /api/v1/mcp still validates Origin against the 0xinsider/localhost allowlist. Do not use credentialed CORS for public API calls; send only the Bearer token header. If you go over either budget, you get a 429 plus a Retry-After header in seconds:

A client that respects the retry

Staying well under the limit

  • Cache. Most of this data updates every 30-120 seconds. Re-fetching every second wastes budget.
  • Paginate, don’t re-list. Use cursors instead of refetching the full leaderboard each loop.
  • Ask for more per request. Bump limit to 100 instead of making 10 calls of limit=10.
  • Batch when you know your IDs. One batch call for 25 traders costs 25 batch-item units but only one regular request.
  • Watch X-RateLimit-Remaining. Below 10, pause polling until the next reset.
  • Use /usage for budget checks. GET /api/v1/usage reads the current primary limiter window without incrementing it. Respect its own 100 reads/minute cap; don’t probe quota with another endpoint.
  • One process owns the polling. Don’t have every container in a fleet poll the same endpoint with the same key.

Conditional GETs

Deterministic read endpoints return an ETag header. Send it back as If-None-Match to get 304 Not Modified with an empty body when nothing changed. Examples include trader and position reads, whale-trade and leaderboard lists, market exploration and intelligence, Sports Edge signals and observations, position timelines, and health responses. Check each endpoint’s OpenAPI response table for authoritative 304 support. Report snapshots aren’t conditional yet because their body includes a request-time generated_at.