Rate Limits
Artery applies quotas to the organization, not to an individual API key or source IP. The authenticated key identifies an organization, the route selects a usage SKU, and the organization's active subscription plan supplies that SKU's per-minute and per-day limits.
textAPI key → organization → subscription plan → route SKU → effective quotaThis keeps every key in an organization on the same commercial entitlement. Rotating or creating another key does not create a fresh quota pool.
Plan-based quotas
The public plans are free, pro, and enterprise. Common REST SKUs include:
| SKU | What it covers |
|---|---|
api.request | General authenticated REST calls |
markets.read | Market-data polling endpoints |
portfolio.read | Cross-provider portfolio reads |
pnl.read | Fill, PnL, statistics, and activity reads |
Each plan may set a per-minute limit, a per-day limit, both, or neither. A
configured value of -1 means unlimited. An organization-level subscription
override can replace individual SKU windows for a custom contract.
rateLimitTier is a deprecated API-key compatibility field. It is ignored when resolving quota;
omit it when creating a key. Changing or rotating a key does not change the organization's plan.
See Rate Limits & Quotas for the current plan table.
Response headers
Metered authenticated responses carry the effective quota state:
httpX-Quota-Sku: markets.read
X-Quota-Limit: 100000
X-Quota-Remaining: 99999
X-Quota-Reset: 1780822653X-Quota-Reset is a Unix timestamp in seconds for the reported window. An
unlimited effective window reports unlimited for X-Quota-Limit and
X-Quota-Remaining.
429 handling
When a minute or day window is exhausted, Artery returns
code: quota_exceeded:
httpHTTP/1.1 429 Too Many Requests
Retry-After: 60
X-Quota-Sku: markets.read
X-Quota-Limit: 600
X-Quota-Remaining: 0
X-Quota-Reset: 1780822653
{
"error": {
"code": "quota_exceeded",
"message": "Quota exceeded for SKU 'markets.read' (minute window: 600)",
"requestId": "req_..."
}
}Use Retry-After or X-Quota-Reset to schedule a retry. Do not parse the
human-readable message to determine the error type or SKU.
Upstream limits
Artery's organization quota is independent of provider limits. Even while the
organization has quota remaining, an upstream can throttle Artery. Those
errors surface as upstream_rate_limited (HTTP 429 with provider set):
| Provider | Limit | Notes |
|---|---|---|
| Polymarket | ~600 req/min/IP | Cloudflare-level; aggressive |
| Kalshi | Token-bucket; 10 tokens/req | No Retry-After — Artery backs off automatically |
| Hyperliquid | 1200 req/min/IP for /info; 100 orders/sec/wallet | Trade-side is per master wallet |
Artery retries upstream_rate_limited on GET calls automatically
(see error handling).
WebSocket usage
Delivered stream messages consume the organization's ws.message quota. The
gateway also tracks subscriptions per connection. Hitting the 1,000-subscription
connection cap returns:
json{ "type": "error", "error": "max 1000 subs/conn" }See also
- Error handling — full envelope + request id
- Authentication — API keys and scopes
- Rate Limits & Quotas — plan and SKU values