Skip to main content
OwnPay uses a sliding window rate limiter to protect against brute-force attacks, abuse, and accidental API floods. Limits are enforced per IP address for unauthenticated endpoints and per API key for authenticated endpoints.

Rate limit tiers

Login, password reset, and device pairing endpoints use a strict bucket with a smaller limit than the global tier. Failed attempts deplete the bucket faster to deter credential stuffing.

Rate limit headers

Every API response includes headers that tell you your current limit status: Example response headers when you have 12 requests remaining:

429 response format

When you exceed the rate limit, OwnPay returns an HTTP 429 status with a structured error body:
The Retry-After header is also set on the HTTP response:
Build your integration to handle 429 responses gracefully. Wait for the retry_after duration before retrying.
Use exponential backoff with jitter when retrying. Start with the retry_after value, then double the wait on each subsequent 429. Add a small random jitter (0-2 seconds) to prevent thundering herd effects.

Configuration

Rate limits are configured in config/app.php and can be overridden with environment variables:

IP whitelisting and trusted proxies

If your OwnPay installation sits behind a reverse proxy or load balancer, configure the trusted proxies so the rate limiter sees the real client IP instead of the proxy IP.
OwnPay reads the X-Forwarded-For header from trusted proxies only. Untrusted proxy headers are ignored to prevent IP spoofing.
Never set TRUSTED_PROXIES to * in production. This allows any client to spoof their IP address and bypass rate limits entirely.

Last modified on August 25, 2026