Every REST endpoint registered underDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/Ahondev/portfolio-v2/llms.txt
Use this file to discover all available pages before exploring further.
/api/v1/ is automatically protected by a lightweight rate-limiting layer provided by RateLimitServiceProvider. Because the framework is designed to run behind Cloudflare, the rate limiter is written to extract the real client IP from Cloudflare’s forwarded headers before it builds the per-IP counter key — preventing the 429 responses from being triggered by a single proxy address shared across thousands of real users.
How Rate Limiting Works
RateLimitServiceProvider::boot() hooks into WordPress’s rest_pre_dispatch filter (priority 10). This filter runs before the REST router dispatches to any controller, making it the earliest possible interception point for every API request.
IP Resolution Order
The IP is resolved by falling through three headers in order of preference:HTTP_CF_CONNECTING_IP
Cloudflare sets this header to the original visitor’s IP on every proxied request. It is the most reliable source when Cloudflare is in front of your server.
HTTP_X_FORWARDED_FOR
Standard forwarding header used by most load-balancers and reverse proxies. Used as a fallback when
CF-Connecting-IP is absent (e.g. direct traffic, other CDNs).Rate Limit Parameters
| Parameter | Value |
|---|---|
| Max requests | 100 per window |
| Window duration | 60 seconds |
| Key granularity | Per IP address + route (not global) |
| Storage backend | WordPress transients |
| HTTP status on limit | 429 Too Many Requests |
ip + route, a client that exceeds the limit on POST /api/v1/ssg/all is not blocked from accessing GET /api/v1/contact — each route has its own independent counter.
429 Response Shape
When the limit is exceeded the filter short-circuits the REST dispatch and returns this structure directly:Because
rest_pre_dispatch returns a value instead of null, WordPress skips controller dispatch entirely and sends this response immediately. No controller code runs after a 429.Customising the Limit
The rate limiter is implemented entirely insideRateLimitServiceProvider::boot(). To change the threshold or window, extend the provider and override boot():
Related Pages
Caching
Rate-limit counters live alongside other transients — learn how the flush button affects both systems.
SSG REST API
The SSG endpoints (
/api/v1/ssg/*) are subject to the same rate-limiting rules as all other REST routes.