Getting Started

Sign up at ratelimitr.com, verify your email, and you'll get a tenant ID and can create your first API key from the dashboard.

Every request uses your API key in the x-api-key header — all rate limits are scoped to your account.

Rate Limit Check

POST https://api.ratelimitr.com/v1/check

Headers

http
x-api-key: rl_key_abc123def456
Content-Type: application/json

Request Body

FieldTypeRequiredDescription
identifierstringyesUnique ID for the entity you're rate-limiting (user ID, IP address, session token, etc.)
tenantIdstringyesYour tenant ID from the dashboard
endpointstringnoThe endpoint being accessed (e.g., /api/users) — logged for analytics
methodstringnoHTTP method — logged for analytics
strategystringnoOverride strategy: fixed_window, token_bucket, leaky_bucket, or sliding_window. Defaults to your plan's strategy
weightintegernoCost of this request (default: 1). Set to 5 for expensive operations

Responses

200 — Allowed

json
{
  "allowed": true,
  "remaining": 42,
  "resetAt": 1718000000,
  "limit": 100,
  "strategy": "token_bucket"
}

429 — Rate Limited

json
{
  "allowed": false,
  "remaining": 0,
  "resetAt": 1718000060,
  "limit": 100,
  "strategy": "token_bucket",
  "retryAfter": 45
}

Examples

cURL

bash
curl -X POST https://api.ratelimitr.com/v1/check \
  -H "x-api-key: rl_key_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "identifier": "user:123",
    "tenantId": "tenant_abc",
    "endpoint": "/api/resource"
  }'

JavaScript (with retry-with-backoff)

javascript
async function checkWithRetry(identifier, tenantId) {
  let attempt = 0;
  const maxRetries = 3;

  while (attempt < maxRetries) {
    const res = await fetch('https://api.ratelimitr.com/v1/check', {
      method: 'POST',
      headers: {
        'x-api-key': 'rl_key_abc123def456',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ identifier, tenantId })
    });

    if (res.status === 429) {
      const { retryAfter } = await res.json();
      const delay = (retryAfter || Math.pow(2, attempt)) * 1000;
      console.log(`Rate limited. Retrying in ${delay}ms...`);
      await new Promise(resolve => setTimeout(resolve, delay));
      attempt++;
    } else {
      return await res.json();
    }
  }
  throw new Error('Max retries exceeded');
}

Python

python
import requests

response = requests.post(
    'https://api.ratelimitr.com/v1/check',
    headers={
        'x-api-key': 'rl_key_abc123def456',
        'Content-Type': 'application/json'
    },
    json={
        'identifier': 'user:123',
        'tenantId': 'tenant_abc',
        'endpoint': '/api/resource'
    }
)

print(response.json())

WebSocket Live Stream

wss://api.ratelimitr.com/ws

Connect, authenticate with your API key, then subscribe to real-time channels.

Connection Flow

On connect, server responds:

json
{ "type": "connected", "availableChannels": ["events", "metrics", "alerts", "blocks"] }

Authenticate:

json
{ "type": "authenticate", "apiKey": "rl_key_abc123def456" }

Response:

json
{ "type": "authenticated", "timestamp": 1718000000 }

Subscribe to channels:

json
{ "type": "subscribe", "channels": ["events", "metrics"] }

Response:

json
{ "type": "subscribed", "channels": ["events", "metrics"], "timestamp": 1718000000 }

Unsubscribe:

json
{ "type": "unsubscribe", "channels": ["events"] }

Ping / Pong (keepalive):

json
{ "type": "ping" }  →  { "type": "pong", "timestamp": 1718000000 }

Channels

Real-time events come through on subscribed channels:

events channel — every rate limit decision:

json
{
  "type": "block",
  "data": {
    "identifier": "user:123",
    "endpoint": "/api/resource",
    "strategy": "token_bucket",
    "remaining": 0
  },
  "timestamp": 1718000000
}

metrics channel — every 5 seconds:

json
{
  "type": "metrics",
  "data": {
    "connectedClients": 12,
    "usedMemory": "2.5M",
    "totalCommandsProcessed": 104200,
    "instantaneousOpsPerSec": 340,
    "uptime": 7
  },
  "timestamp": 1718000000
}

JavaScript Example

javascript
const ws = new WebSocket('wss://api.ratelimitr.com/ws');

ws.onopen = () => {
  console.log('Connected to RateLimitr');
};

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  
  if (msg.type === 'connected') {
    ws.send(JSON.stringify({ 
      type: 'authenticate', 
      apiKey: 'rl_key_abc123def456' 
    }));
  } 
  else if (msg.type === 'authenticated') {
    ws.send(JSON.stringify({ 
      type: 'subscribe', 
      channels: ['events', 'metrics'] 
    }));
  } 
  else if (msg.type === 'subscribed') {
    console.log('Subscribed to:', msg.channels);
  } 
  else {
    console.log('Incoming event:', msg);
  }
};

Rate Limiting Strategies

StrategyPlansBehavior
fixed_windowFree, Pro, EnterpriseCounts requests in a fixed time window (e.g., 1000 per minute). Resets at the boundary. Simple and predictable.
token_bucketPro, EnterpriseTokens refill at a steady rate. Allows bursts up to bucket capacity. Smooths traffic over time.
leaky_bucketPro, EnterpriseProcesses requests at a constant rate. Excess is queued and processed as capacity frees up.
sliding_windowEnterpriseEvaluates request count over a rolling time window using data from the previous window. No traffic spikes at boundaries.

Strategy resolution order: ① request body's strategy field, ② per-key override (set in dashboard), ③ your plan's default strategy.

API Keys

Create and manage keys from the dashboard at /dashboard/api-keys. Each key can have:

  • Scopes: read, write, admin
  • Rate limit override: Custom limits per key (requests/second, burst, window, strategy)
  • Per-endpoint limits: Different limits for different routes
  • Expiration: Auto-revoke after a set date

Keys can also be managed programmatically:

MethodPathDescription
POST/api-keys/keysCreate key: { name, scopes?, rateLimitOverride?, expiresAt? }
GET/api-keys/keysList keys: ?limit&offset&status&search
PATCH/api-keys/keys/:keyIdUpdate key
DELETE/api-keys/keys/:keyIdRevoke key

Rate Limit Headers

Every response from the check endpoint includes:

HeaderDescription
X-RateLimit-LimitMax requests in the current window
X-RateLimit-RemainingRequests remaining in this window
X-RateLimit-ResetUnix timestamp when the window resets
Retry-AfterSeconds to wait (only on 429 responses)

Error Codes

CodeMeaning
400Invalid request — check your body fields
401Bad or missing API key — check your x-api-key header
429Rate limit exceeded — use Retry-After to back off