Rate Limits
Weight-based rate limiting, cost multipliers, and best practices for managing API usage.
API requests are rate-limited using a weight-based token bucket algorithm. Your tier determines your limits—check the /api/v1/markets endpoint or your account dashboard for your specific quotas.
How It Works
Each request consumes "weight" from your bucket based on the data type, time range, and number of exchanges. The bucket refills continuously at weight_per_min / 60 tokens per second.
Weight Calculation
Request weight depends on the data type, time range, and number of exchanges:
base_points = (to - from) / tf_seconds
base_weight = ceil(base_points / 1000) × cost_multiplier
weight = base_weight × exchange_multiplierCost Multipliers
| Stream | Multiplier | Max Points/Request | Aggregation |
|---|---|---|---|
| candles | 1x | 100,000 | No |
| stats | 1x | 100,000 | Yes |
| oi | 1x | 100,000 | Yes |
| vd | 1x | 100,000 | Yes |
| volumes | 4x | 20,000 | Yes |
| heatmap_sd | 5x | 5,000 | Yes |
| heatmap_hd | 10x | 4,000 | Yes |
| stop_heatmap | 5x | 5,000 | No |
| tp_heatmap | 5x | 5,000 | No |
| liquidation_heatmap | 5x | 5,000 | No |
flat_heatmap_sd and flat_heatmap_hd share the same limits as heatmap_sd and heatmap_hd respectively. stop_heatmap, tp_heatmap, and liquidation_heatmap use the same limits as heatmap_sd but do not support aggregation.
Streams with aggregation support can combine data from multiple exchanges in a single request. Candles and custom heatmaps (stop_heatmap, tp_heatmap, liquidation_heatmap) must be requested per-exchange.
Exchange Multiplier for Aggregated Requests
When requesting data aggregated across multiple exchanges, each exchange adds 20% to the base cost:
exchange_multiplier = 1 + 0.2 × num_exchanges| Exchanges | Multiplier |
|---|---|
| 1 | 1x |
| 2 | 1.4x |
| 3 | 1.6x |
| 5 | 2.0x |
| 10 | 3.0x |
Single-exchange requests have no aggregation overhead.
Examples
Requesting 1 day of 1-minute candles (single exchange):
base_points = 86400 / 60 = 1440 points
weight = ceil(1440 / 1000) × 1 = 2 weightRequesting 1 day of 1-minute heatmap_hd (1 exchange):
base_points = 86400 / 60 = 1440 points
weight = ceil(1440 / 1000) × 10 = 20 weightRequesting 1 day of 1-minute heatmap_hd (aggregated across 3 exchanges):
base_points = 86400 / 60 = 1440 points
base_weight = ceil(1440 / 1000) × 10 = 20
exchange_multiplier = 1 + 0.2 × 3 = 1.6
weight = 20 × 1.6 = 32 weightResponse Headers
Every response includes rate limit information:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum weight per minute for your tier |
X-RateLimit-Remaining | Remaining weight in current window |
X-RateLimit-Used | Weight consumed in current window |
X-RateLimit-Reset | Unix timestamp when bucket fully refills |
Rate Limited Response
When rate limited, the API returns HTTP 429:
{
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded",
"details": {
"retry_after": 45
}
}
}The Retry-After header is also set with seconds until you can retry. Note that retry_after is guaranteed to be at least 1 second.
Checking Usage
Use the /api/v1/usage endpoint to check your current rate limit status without consuming any weight:
curl "https://eu-central-1.mmt.gg/api/v1/usage" -H "X-API-Key: your-api-key"Response:
{
"limit": 10000,
"remaining": 8500,
"used": 1500,
"reset": 1704067260,
"window_seconds": 60
}limit, remaining, and used are dynamic values returned for your current key and plan.
This endpoint has zero cost and can be called as frequently as needed.
Best Practices
- Monitor headers - Track
X-RateLimit-Remainingto avoid hitting limits - Batch requests - Request larger time ranges instead of many small requests
- Use WebSocket - Real-time data via WebSocket doesn't consume rate limit weight
- Cache responses - Historical data doesn't change, cache it locally
- Exponential backoff - When rate limited, wait the full
retry_afterperiod
Request Timeout
All requests have a 30-second timeout. Large requests for high-resolution data may timeout before completion. If this happens:
- Reduce the time range
- Use a larger timeframe
- Request fewer exchanges at once