Rate Limits

Per-merchant fixed-window rate limits, response headers, and how to handle 429 responses.

halfin enforces per-merchant fixed-window rate limits. Limits are keyed by merchant account (API key environment), not by IP address.

Limits

OperationLimitWindow
Create Invoice60 requestsper minute
Create Payout20 requestsper minute
Read endpoints (GET list/get)300 requestsper minute
Global per-IP backstop1000 requestsper minute

The global per-IP backstop applies as a secondary safeguard across all endpoints.

Rate limit headers

Every response includes the current counter state:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 54
X-RateLimit-Reset: 1751234567
HeaderDescription
X-RateLimit-LimitMaximum requests allowed in the window
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp (seconds) when the window resets

429 response

When the limit is exceeded, the API returns 429 Too Many Requests with error code rate_limit_exceeded:

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "rate limit exceeded, try again later"
  },
  "meta": { "request_id": "req_0000000000000001" }
}

There is no Retry-After header. Use X-RateLimit-Reset to determine when the window resets.

Best practices

  • Use webhooks rather than polling to receive payment status updates.
  • Cache /v1/rates and /v1/currencies responses — they change infrequently.
  • Back off on 429 using X-RateLimit-Reset to calculate wait time.
  • Batch operations server-side rather than making one call per user action.