Documentation Index
Fetch the complete documentation index at: https://docs.adipredictstreet.com/llms.txt
Use this file to discover all available pages before exploring further.
Rate limits are enforced at the core-api edge. Every authenticated
request passes through two independent buckets:
ip — per source IP (behind the ingress; respects
X-Forwarded-For set by the trusted load balancer). Cheap edge
defence that applies to anonymous and authenticated traffic alike.
wallet — per your key’s associatedWallet (single_wallet
partners) or per the X-User-Wallet header value (multi_wallet
partners). Prevents a single wallet identity from exceeding the
platform’s per-user ceiling regardless of how the calls are
distributed across your keys.
Both must pass; a single rejection returns 429 and sets
Retry-After to the tightest bucket’s reset delta. Response headers
(X-RateLimit-Limit, -Remaining, -Reset) expose the tightest
applicable bucket.
A per-partner organisation-wide bucket lives on the partner record
(rateLimitPerMin) but is not currently enforced at the request
boundary. If you need a partner-wide ceiling, operations can lower
your per-wallet cap as a stop-gap — contact your integration
manager.
Limits
Trading and write paths use per-second wallet windows (anti-burst);
read paths use per-minute windows. The two scopes (ip and wallet)
are independent — each request must pass every applicable bucket.
Trading (writes)
| Endpoint | Scope | Limit | Window |
|---|
POST /api/orders/place | ip | 1000 | 60s |
POST /api/orders/place | wallet | 20 | 1s |
POST /api/orders/cancel | wallet | 20 | 1s |
POST /api/orders/cancel-all | wallet | 1 | 1s |
POST /api/vault/split-signature, /merge-signature, /convert-signature | wallet | 3 | 1s |
POST /api/vault/* (umbrella) | ip | 100 | 60s |
Order reads
| Endpoint | Scope | Limit | Window |
|---|
GET /api/orders/open | wallet | 300 | 60s |
GET /api/orders/history | wallet | 300 | 60s |
GET /api/orders/{id} | wallet | 300 | 60s |
GET /api/orders/{id}/fills | wallet | 300 | 60s |
Market data
| Endpoint | Scope | Limit | Window |
|---|
GET /api/markets, /api/markets/:slug, /api/markets/:symbol/orderbook | ip | 600 | 60s |
GET /api/markets/:symbol/trades | ip | 240 | 60s |
GET /api/markets/:symbol/price-history | ip | 240 | 60s |
GET /api/markets/:symbol/traders | ip | 120 | 60s |
GET /api/markets/:symbol/ohlc (deprecated) | ip | 120 | 60s |
Portfolio (/me/*)
| Endpoint | Scope | Limit | Window |
|---|
GET /api/me/vault, /me/balances, /me/positions, /me/portfolio, /me/fee-tier, /me/trades, /me/fees, /me/auto-redeem | wallet | 600 | 60s |
GET /api/me/deposit-limits | wallet | 120 | 60s |
POST /api/me/vault/emergency | wallet | 120 | 60s |
GET /api/me/withdrawals, /me/withdrawals/{id}, /me/withdrawals/deposit-sources | wallet | 60 | 60s |
GET /api/me/withdrawals/fee | wallet | 30 | 60s |
POST /api/me/withdrawals/{id}/cancel | wallet | 10 | 60s |
POST /api/withdrawals/request | ip | 60 | 60s |
Discovery
| Endpoint | Scope | Limit | Window |
|---|
GET /api/leaderboard | ip | 600 | 60s |
GET /api/leaderboard?search=… | ip | 120 | 60s |
GET /api/search, /api/search/* | ip | 60 | 60s |
Limits above are production defaults. Staging and mainnet may run
tighter or looser values — your onboarding runbook contains the
authoritative table for the environment you are connected to.
Counter behaviour
Buckets are fixed-window with a Redis-backed counter that re-applies
its TTL on every access where the key has lost it (Redis maxmemory
eviction races, manual PERSIST, replica-failover key loss, snapshot
reload). Earlier deploys had a class of stuck-counter behaviour where
a key without a TTL kept incrementing without ever expiring; clients
saw X-RateLimit-Remaining flat-line at 0 and Retry-After never
counting down. That class is fixed — every request you make now
either decrements Remaining or surfaces a real countdown to refill.
ip buckets key on the real client IP, not the immediate TCP
peer. We honour X-Forwarded-For from the trusted ingress hop, so
partners behind shared edges (Cloudflare, corporate egress proxies)
no longer collide on a single bucket. If your traffic transits an
extra proxy hop your onboarding manager hasn’t seen, raise it
during integration so we can adjust the trusted-hop count.
Every rate-limited response includes:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 60
X-RateLimit-Reset is delta-seconds until the bucket refills
— i.e. the value 60 means “wait 60 seconds and the limit
resets”. This deliberately matches Retry-After semantics; both
are seconds-until-refill, not Unix epoch.
- The HTTP header
Retry-After is set to the same delta-seconds on
every 429.
- On
429 Too Many Requests, the response body uses the standard
error envelope:
{
"status": "error",
"error": {
"code": "rate_limited",
"message": "place-order budget exhausted",
"trace_id": "..."
}
}
Read the seconds-to-wait from the Retry-After header — it is
not duplicated inside the body.
Retry guidance
- On
429: wait Retry-After (header value, in seconds) before
retrying. Do not retry sooner — the bucket has not refilled.
- Backoff on 5xx: exponential backoff with jitter, starting at
200ms, capped at 10s. Maximum 3 attempts for idempotent calls
(GET, DELETE). Do not retry non-idempotent writes (
POST /orders,
POST /withdrawals/request) automatically — they accept a
clientOrderId / nonce for deduplication if your design requires
retries.
- Circuit-break on persistent 5xx: if your error rate exceeds
50% over 30 seconds, stop sending new requests for 60 seconds.
Higher limits
Partners with justified high-throughput needs (market makers, volume
traders) can request bespoke limits at onboarding:
wallet-scoped ceilings can be lifted 10–50× on the place / cancel
endpoints.
ip-scoped limits are lifted on a per-whitelisted-IP basis.
- Platform-wide ceilings cannot be exceeded; they protect the shared
matcher.
Contact partners@predictstreet.com
with your expected peak throughput profile.