Skip to main content
Struct enforces rate limits per API key, with caps scoped to your organisation’s plan. This page covers every dimension that’s limited and what to do when you hit one. For plan pricing and credit balances, see Pricing.

REST throughput

REST limits are enforced as both requests-per-second and requests-per-minute. The tighter of the two applies.
PlanRequests/secondRequests/minute
Free5120
Hobby251,000
Startup1255,000
Scale30015,000
EnterpriseCustomCustom
Limits are per API key, tracked with a sliding window. When you exceed a limit, the API returns 429 Too Many Requests with a Retry-After header (seconds) when applicable.
{
  "success": false,
  "data": null,
  "message": "Rate limit exceeded"
}

WebSocket connections

Each organisation has a cap on concurrent open websocket connections across rooms and alerts combined.
PlanConcurrent connections
Free1
Hobby50
Startup250
Scale1,000
EnterpriseUnlimited
A single connection can subscribe to every room and every alert. You rarely need more than a handful of sockets in production: one per logged-in user for alerts, plus a small pool for background streams. When you exceed the cap, new connections are rejected at handshake with close code 4002.

Webhook subscriptions

PlanMax active webhooks
Free10
Hobby5,000
Startup25,000
Scale100,000
EnterpriseUnlimited
Webhook delivery itself is unmetered; you pay per delivered event in credits. See Webhook Pricing.

Filter limits

Every websocket room has a per-subscription filter cap. Across the rooms WebSocket, no single client can hold more than 500 total filter items at once (summed across all rooms on the same connection). If you need to track more than 500 entities, open additional connections (within your plan’s connection cap) or move to a subscription-free room and filter client-side for hot entities only.

Credits

Every REST call and every websocket message is billed in credits. Plans include a monthly credit allowance; overages are billed per credit.
  • REST: typically 1 credit per call, with exceptions documented on Pricing.
  • WebSocket: per-message rate that varies by room. See WebSocket Pricing.
  • Webhooks: 0.1 or 0.2 credits per delivered event. See Webhook Pricing.
  • Alerts WebSocket: same per-event rate as webhooks.
Credits are billed integer-rounded at the end of each period.

What to do when limited

REST

  1. Respect Retry-After when present.
  2. Use exponential backoff with jitter for retries on 429, 5xx, network errors, and timeouts. Cap the backoff at 30 seconds.
  3. Cache aggressively. Markets, events, and trader profiles change slowly and are safe to keep in your own layer for minutes at a time.
  4. Prefer batch endpoints over fan-out (for example, the bulk wallet positions endpoint over N single-wallet calls).
  5. Move polling to websockets when you’re refreshing the same data repeatedly.

WebSocket

  1. Filter at subscribe time, not in your code. Server-side filtering is free; client-side filtering still bills you for the message.
  2. Pool subscriptions on a single connection. The 1-credit connection hold is per-connect, and the same socket can hold many rooms.
  3. Reconnect with backoff, not in a tight loop. Every connect re-incurs the 1-credit hold.
  4. Drop subscriptions you no longer need with unsubscribe_all or leave_room so you stop being billed for incoming messages.
See Best Practices for patterns that keep you well under these limits.
Last modified on May 27, 2026