MMTMMT Docs
Basics

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_multiplier

Cost Multipliers

StreamMultiplierMax Points/RequestAggregation
candles1x100,000No
stats1x100,000Yes
oi1x100,000Yes
vd1x100,000Yes
volumes4x20,000Yes
heatmap_sd5x5,000Yes
heatmap_hd10x4,000Yes
stop_heatmap5x5,000No
tp_heatmap5x5,000No
liquidation_heatmap5x5,000No

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
ExchangesMultiplier
11x
21.4x
31.6x
52.0x
103.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 weight

Requesting 1 day of 1-minute heatmap_hd (1 exchange):

base_points = 86400 / 60 = 1440 points
weight = ceil(1440 / 1000) × 10 = 20 weight

Requesting 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 weight

Response Headers

Every response includes rate limit information:

HeaderDescription
X-RateLimit-LimitMaximum weight per minute for your tier
X-RateLimit-RemainingRemaining weight in current window
X-RateLimit-UsedWeight consumed in current window
X-RateLimit-ResetUnix 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

  1. Monitor headers - Track X-RateLimit-Remaining to avoid hitting limits
  2. Batch requests - Request larger time ranges instead of many small requests
  3. Use WebSocket - Real-time data via WebSocket doesn't consume rate limit weight
  4. Cache responses - Historical data doesn't change, cache it locally
  5. Exponential backoff - When rate limited, wait the full retry_after period

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

On this page