Attaching the middleware
Rules apply only to routes that run the dynamic.throttle middleware, and installing the package attaches it nowhere (ADR-0020). Add it to your route groups in bootstrap/app.php:
php
->withMiddleware(function (Middleware $middleware) {
$middleware->appendToGroup('api', 'dynamic.throttle');
})Or list the groups in the middleware.auto_attach config key, such as ['api']. A route outside those groups is never limited.
- After authentication. The middleware runs after Laravel's authentication middleware,
authandauth.basic, even in a group that lists it first, so user rules see the user. If users log in through middleware that Laravel cannot recognize, such as a JWT package's or your own API key check, list it inmiddleware.after, by alias or class. Until you do, user rules count those users as guests. - Excluded paths. No rule ever applies to the paths in the
exceptconfig key, not even a*rule. By default, they are Horizon, Telescope, Pulse, Nova, Livewire 3 and 4,broadcasting/auth,sanctum/csrf-cookieandup. Remove an entry to limit its path. - Responses. A limited request gets Laravel's own 429 (
ThrottleRequestsException), rendered by your exception handler, withRetry-After,X-RateLimit-Reset,X-RateLimit-LimitandX-RateLimit-Remaining: 0. A rule'sresponse_overridereplaces the body with its JSON, sent as JSON to every client, browsers included. An allowed request getsX-RateLimit-LimitandX-RateLimit-Remainingfrom its most restrictive enforcing rule. Dry-run rules never set headers. - Laravel's
throttleon the same route. Both limit the request, and whichever runs last writes theX-RateLimit-*headers. Pick one per route. - Failures. If the counters, the manifest, a config value or one of your scope resolvers fails, the request goes through, and the error is reported to your exception handler. A rule can answer 503 instead: see When something fails.