Skip to main content

REST Endpoint Limits

CategoryRate LimitScope
Trading (orders, cancel)10 req/secper API key
Order queries5 req/minper API key
Portfolio/Balances2 req/minper API key
List instruments1 req/minper IP
Single instrument1 req/5secper IP
API key management1-5 req/minper user

WebSocket Limits

LimitMVP Value
Connections1 per API key
Subscriptions10 instruments
Reconnect cooldown5 seconds

Rate Limit Headers

All REST responses include rate limit headers:
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 7
X-RateLimit-Reset: 1673625600
HeaderDescription
X-RateLimit-LimitMaximum requests allowed in the time window
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUnix timestamp when the limit resets

Rate Limit Exceeded

When you exceed a rate limit, you’ll receive a 429 Too Many Requests response:
{
  "error": "rate_limit_exceeded",
  "message": "Rate limit exceeded. Try again in 5 seconds.",
  "retry_after": 5
}

Best Practices

Use Rate Limit Headers

Check remaining requests before making calls:
response = requests.get(url, headers=headers)

remaining = int(response.headers['X-RateLimit-Remaining'])
if remaining < 2:
    reset_time = int(response.headers['X-RateLimit-Reset'])
    sleep_time = reset_time - time.time()
    time.sleep(sleep_time)

Implement Exponential Backoff

def make_request_with_backoff(url, max_retries=5):
    for attempt in range(max_retries):
        response = requests.get(url)
        if response.status_code != 429:
            return response

        retry_after = int(response.headers.get('Retry-After', 2 ** attempt))
        time.sleep(retry_after)

    raise Exception("Max retries exceeded")

Batch Operations

Instead of polling individual orders:
# Bad - 100 requests
for order_id in order_ids:
    get_order(order_id)

# Good - 1 request
get_open_orders()  # Returns all at once

Use WebSocket for Real-Time Data

# Bad - Polling every second (60 req/min - exceeds limit!)
while True:
    get_instrument_price(instrument_id)
    time.sleep(1)

# Good - WebSocket subscription (1 connection)
ws.subscribe(instrument_id)  # Real-time updates

Cache Static Data

# Cache instruments (they don't change frequently)
instruments = get_instruments()  # 1 req/min limit
cache_instruments(instruments, ttl=300)  # Cache for 5 minutes

Requesting Higher Limits

If you have a legitimate use case requiring higher limits:
  1. Demonstrate usage - Trade actively for 30+ days
  2. Contact support - Email [email protected]
  3. Provide details:
    • Your API key ID
    • Current usage patterns
    • Why you need higher limits
    • Your trading strategy overview
Limits may be increased for established, legitimate users on a case-by-case basis.

Fair Use Policy

Rate limits are in place to:
  • Ensure system stability for all users
  • Prevent abuse and excessive load
  • Maintain fair access to market data
  • Protect against accidental runaway scripts
Repeated violations of rate limits or attempts to circumvent them may result in API key suspension.