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

  1. The client sends a request with an Idempotency-Key header containing a UUID v4
  2. If it's a new key, the request is processed normally and the response is cached
  3. If the key has been seen before (same body + same endpoint), the cached response is returned with an Idempotent-Replayed header
  4. If the key has been seen but the body or endpoint differs, a 400 Bad Request is returned

Features

  • Automatic caching — Responses are cached transparently using Laravel's cache system
  • Replay detection — Repeated requests return the original response with an Idempotent-Replayed header
  • 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