Skip to content

Rate Limiting

API requests are rate limited per route. Limits apply per IP (for unauthenticated auth routes) or per user (for authenticated routes). The window is 1 minute; over-limit requests receive 429 Too Many Requests.

How it works

  • Key by IP: Used for GET /m/:key (image serve), POST /auth/register, and POST /auth/login. Same IP is limited across all users.
  • Key by user: Used for all other limited routes. The identifier is the authenticated user (JWT or API key). Each user has their own counter per route.
  • Window: Fixed 1-minute window. Counters reset at the start of each new window.
  • No limit: /ping, /d/:key, /reference/*, and webhooks are not rate limited.

Endpoint limits

EndpointTypeLimit (req/min)
GET /ping
GET /m/:keyIP400
GET /d/:key
GET /reference/*
POST /auth/registerIP10
POST /auth/loginIP15
POST /auth/api-keysuserId10
GET /auth/api-keysuserId30
DELETE /auth/api-keys/:iduserId10
POST /filesuserId30
POST /files/bulk-deleteuserId20
GET /filesuserId60
GET /files/:iduserId120
DELETE /files/:iduserId60
GET /settingsuserId60
PATCH /settingsuserId20
GET /profileuserId60
GET /usageuserId60
GET /logsuserId60

Type: IP = limit by client IP; userId = limit by authenticated user; = not limited.

429 response

When the limit is exceeded:

  • Status: 429 Too Many Requests
  • Body: { "error": "Too many requests" }
  • Header: Retry-After: <seconds> (seconds until the current window ends, typically 60)

Handling: Back off and retry after the given seconds.

javascript
const retryAfter = res.headers.get('Retry-After')
await new Promise(r => setTimeout(r, parseInt(retryAfter || '60') * 1000))
// Retry request

Image resize concurrency (503)

GET /m/:key requests that need resize or format (query params width, height, or format) are limited by concurrent processing capacity. At most 10 such operations run at once.

  • When no slot is available: Response is 503 with Retry-After: 5 and body { "error": "Server busy; try again shortly" }
  • Passthrough requests (no resize/format) do not use a slot and are not affected

Retry after the Retry-After seconds when you receive 503.