Rate Limit Table

All limits are per IP address and reset on a rolling window basis.
Endpoint GroupLimitWindow
/api/v1/* (collect, disburse, transactions, balance)100 reqper minute
/api/v1/checkout (card payments)30 reqper minute
POST /api/v2/public/checkout/:slug/pay10 reqper minute
GET /api/v2/public/checkout/:slug30 reqper minute
POST /dashboard/transfers20 reqper minute
POST /auth/user/login5 reqper minute
POST /auth/user/signup3 reqper minute

Test-Mode Request Limits

In addition to per-IP limits, projects using test API keys have a daily quota of test requests to prevent quota abuse. This limit resets at midnight UTC. The current usage is visible in your project settings and in the test_requests_today field of the project response.

Rate Limit Response

When a limit is exceeded you receive 429 Too Many Requests:
{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Too many requests. Slow down and try again in a moment."
  }
}

Best Practices

Instead of polling /api/v1/transactions/:ref in a tight loop, configure a callback_url and wait for a webhook notification. This eliminates unnecessary requests and avoids rate limit issues.
The /api/v1/wallet/balance endpoint returns the current balance. Cache this value for a few seconds on your server rather than fetching it on every page load.
If you receive a 429, wait before retrying. Use exponential backoff: 1s → 2s → 4s → 8s with jitter.

Headers in Response

Rate limit information is included in response headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1705309860