The Fig Markets API implements rate limiting to ensure fair usage and protect our services. Rate limits apply to both the REST API and the WebSocket API.
All REST endpoints have equal weighting and share the same rate limit, and so do all WebSocket methods.
- Rate Limit: 1000 requests per minute
- Time Window: a fixed 1 minute window, which starts with the first request counted in it; the counter resets when the window ends
REST requests are counted per client IP address, so every API key calling from the same IP address shares one limit.
Every HTTP response includes rate limit information in the headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 950
X-RateLimit-Reset: 1640995200- X-RateLimit-Limit: Maximum requests allowed in the time window
- X-RateLimit-Remaining: Number of requests remaining in the current window
- X-RateLimit-Reset: Unix timestamp, in seconds, when the current window ends
When you exceed the rate limit, you'll receive a 429 Too Many Requests response:
{
"code": 429,
"message": "rate limit exceeded",
"limit": 1000,
"reset": 1640995200,
"window": "1m0s"
}A request refused with 429 can be retried after X-RateLimit-Reset. Sign the retry afresh: a signature older than 60 seconds is refused, and so is one that has already been accepted (see Signing Requests). In the examples below, sendSignedRequest / send_signed_request stands for your own function that signs and sends the request, such as makeRequest in the signing guide.
// JavaScript/Node.js example
async function makeApiRequest(sendSignedRequest) {
const response = await sendSignedRequest();
const limit = response.headers.get('X-RateLimit-Limit');
const remaining = response.headers.get('X-RateLimit-Remaining');
const reset = Number(response.headers.get('X-RateLimit-Reset'));
console.log(`Rate limit: ${remaining}/${limit} requests remaining`);
if (response.status === 429) {
// Wait until the window ends, then sign and send the request again
const waitTime = (reset * 1000) - Date.now();
if (waitTime > 0) {
await new Promise(resolve => setTimeout(resolve, waitTime));
}
return makeApiRequest(sendSignedRequest);
}
return response;
}# Python example
import time
def make_api_request(send_signed_request):
response = send_signed_request()
limit = response.headers.get('X-RateLimit-Limit')
remaining = response.headers.get('X-RateLimit-Remaining')
reset = int(response.headers.get('X-RateLimit-Reset'))
print(f"Rate limit: {remaining}/{limit} requests remaining")
if response.status_code == 429:
# Wait until the window ends, then sign and send the request again
wait_time = reset - time.time()
if wait_time > 0:
time.sleep(wait_time)
return make_api_request(send_signed_request)
return responseEvery WebSocket message counts towards the limit except auth, auth/refresh and heartbeat. Messages are counted per authenticated user once the connection has authenticated, and per client IP address before that.
auth and auth/refresh have their own limit of 120 messages a minute per client IP address (see WebSocket Authentication).
When you exceed the WebSocket rate limit, you'll receive a JSON-RPC error response:
{
"jsonrpc": "2.0",
"id": "your_request_id",
"error": {
"code": -32006,
"message": "Rate limit exceeded",
"data": {
"limit": 1000,
"window": "1m0s",
"reset": 1640995200
}
}
}