Skip to main content
npayload is launching soon.
npayloadDocs
Resources

Rate limits

API rate limits by tier with response headers and best practices

npayload enforces rate limits to ensure fair usage and platform stability. Limits are applied per API key at the edge layer.

Rate limit tiers

TierRequests per minuteBurstConcurrent connections
Free60105
Starter6005025
Pro6,000200100
EnterpriseCustomCustomCustom

Response headers

Every API response includes rate limit headers:

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

Rate-limited response

When you exceed the rate limit, the API returns 429 Too Many Requests:

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded. Retry after 30 seconds.",
    "retryAfter": 30
  }
}

Per-endpoint limits

Some endpoints have additional limits:

EndpointLimitNotes
POST /oauth/token30/min per IPPrevents credential stuffing
POST /v1/messages/batch10/minEach batch can contain up to 100 messages
POST /v1/messages/transactional10/minAtomic multi-channel publish

Best practices

  • Use batch publish to send multiple messages in one request instead of many individual calls.
  • Implement exponential backoff when you receive a 429 response. Use the Retry-After header.
  • Cache responses where possible (channel metadata, subscription lists).
  • Monitor your usage via the dashboard to stay within limits.
async function publishWithRetry(channel: string, payload: unknown, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await npayload.messages.publish({ channel, payload });
    } catch (error) {
      if (error instanceof RateLimitError && attempt < maxRetries - 1) {
        const delay = error.retryAfter ?? Math.pow(2, attempt) * 1000;
        await new Promise((resolve) => setTimeout(resolve, delay));
        continue;
      }
      throw error;
    }
  }
}

Next steps

Was this page helpful?

On this page