Introduction
Idempotency Middleware is a Laravel package that ensures your API endpoints can safely handle repeated requests. When a client sends the same request twice (due to network retries, user double-clicks, etc.), the middleware returns the cached response from the first request instead of processing it again.
Why Idempotency?
Without idempotency, retrying a failed request can cause unintended side effects — duplicate charges, duplicate orders, duplicate emails. This middleware solves that by caching responses keyed by a unique identifier the client provides.
How It Works
- The client sends a request with an
Idempotency-Keyheader containing a UUID v4 - If it's a new key, the request is processed normally and the response is cached
- If the key has been seen before (same body + same endpoint), the cached response is returned with an
Idempotent-Replayedheader - If the key has been seen but the body or endpoint differs, a
400 Bad Requestis returned
Features
- Automatic caching — Responses are cached transparently using Laravel's cache system
- Replay detection — Repeated requests return the original response with an
Idempotent-Replayedheader - Conflict detection — Reusing a key with a different body or endpoint is rejected
- Configurable — Customize headers, expiration time, and which HTTP methods are covered
- Validation excluded — 422 responses are not cached, so validation errors can be retried
Requirements
- PHP 8.4+
- Laravel 12.0 or 13.0
Quick Example
# First request — processed normally
curl -X POST https://api.example.com/orders \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-H "Content-Type: application/json" \
-d '{"product_id": 1, "quantity": 2}'
# Same request again — returns cached response
curl -X POST https://api.example.com/orders \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-H "Content-Type: application/json" \
-d '{"product_id": 1, "quantity": 2}'
# Response includes: Idempotent-Replayed: true