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
| Endpoint | Scope | Limit | Window |
|---|
POST /api/orders/place | ip | 1000 | 60s |
POST /api/orders/place | wallet | 1200 | 60s |
POST /api/orders/cancel | wallet | 1200 | 60s |
POST /api/orders/cancel-all | wallet | 60 | 60s |
GET /api/orders/* | wallet | 300 | 60s |
GET /api/markets, /orderbook, /trades, /ohlc | ip | 240–600 | 60s |
GET /api/me/vault, /me/balances, /me/positions, … | wallet | 600 | 60s |
POST /api/vault/split-signature, /merge-signature | wallet | 180 | 60s |
Limits above are testnet defaults. Staging and mainnet may run
tighter or looser values — your onboarding runbook contains the
authoritative table for the environment you are connected to.
Every rate-limited response includes:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1713789600
X-RateLimit-Reset is a Unix epoch in seconds at which the bucket
refills.
- The HTTP header
Retry-After is set to the seconds-until-refill 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.