Integration
Rate Limits
Understand API rate limit tiers, response headers, endpoint-specific limits, and best practices for handling throttled requests.
Overview
PaymentHooks enforces rate limits on all API endpoints to ensure platform stability, prevent abuse, and guarantee fair resource allocation across all tenants. Rate limits are applied per API key and vary by subscription plan. When a limit is exceeded, the API responds with HTTP 429 Too Many Requests and includes headers that indicate when you can retry.
Rate limit tiers by plan
Each subscription plan has distinct rate limit thresholds. Limits are evaluated across three rolling windows: per minute, per hour, and per day.
| Plan | Requests / min | Requests / hr | Requests / day |
|---|---|---|---|
| Starter | 60 | 1,000 | 10,000 |
| Growth | 120 | 5,000 | 50,000 |
| Business | 300 | 15,000 | 100,000 |
| Enterprise | 1,000 | 50,000 | 500,000 |
Rate limit headers
Every API response includes rate limit headers so your integration can track consumption in real time and pre-emptively throttle before hitting the limit.
| Header | Description |
|---|---|
| X-RateLimit-Limit | Maximum number of requests allowed in the current time window. |
| X-RateLimit-Remaining | Number of requests remaining in the current time window. |
| X-RateLimit-Reset | Unix timestamp (seconds) indicating when the current window resets. |
| Retry-After | Seconds to wait before retrying. Present only on 429 responses. |
429 response format
When a rate limit is exceeded, the API returns an HTTP 429 status with the standard error envelope. The Retry-After header indicates the number of seconds to wait before retrying.
{"data": null,"error": {"code": "RATE_LIMIT_EXCEEDED","message": "API rate limit exceeded. Retry after 42 seconds."}}
Endpoint-specific limits
Certain security-sensitive and resource-intensive endpoints enforce stricter limits independent of your plan tier. These limits are scoped per IP address or per session.
| Endpoint | Limit | Window | Scope |
|---|---|---|---|
| Login | 5 attempts | 15 minutes | Per IP |
| MFA verification | 5 attempts | 5 minutes | Per IP |
| Webhook simulate | 20 requests | 1 minute | Per session |
| Log submission | 60 requests | 1 minute | Per IP |
Best practices
Follow these recommendations to minimise the chance of hitting rate limits and to handle throttled responses gracefully.
- Implement exponential backoff. When retrying after a 429, increase the delay exponentially (e.g. 1s, 2s, 4s, 8s) with jitter to avoid thundering herd effects.
- Cache responses where possible. Store frequently requested data locally to reduce redundant API calls. Use ETag and If-None-Match headers for conditional requests.
- Use webhooks instead of polling. Subscribe to webhook events for real-time notifications rather than polling endpoints at fixed intervals.
- Read the Retry-After header before retrying. The Retry-After header provides the exact number of seconds to wait. Always honour this value rather than using a fixed delay.
- SDK handles rate limits automatically. The PaymentHooks SDK automatically retries on 429 responses up to 3 times, respecting the Retry-After delay between attempts.
SDK rate limit handling
The official PaymentHooks SDK handles rate limit responses transparently. When the API returns a 429, the SDK reads the Retry-After header and automatically retries the request up to three times with the appropriate delay.
import PaymentHooks from '@paymenthooks/sdk';const ph = new PaymentHooks('phk_live_...');// SDK automatically retries on 429 with Retry-After delayconst payment = await ph.payments.create({ ... });