Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.fluveo.com/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Network errors, timeouts, and client crashes can leave you unsure whether a request succeeded. Idempotency keys let you safely retry any POST request. If the API has already processed a request with the same key, it returns the cached response instead of executing the operation again.

The Idempotency-Key header

Include an Idempotency-Key header on every POST request. The key is a string of up to 255 characters. UUIDs are recommended.
curl -X POST https://api.leanrails.com/v1/payment_intents \
  -u "sk_test_xxx:" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 019532a1-7e2b-4e6a-b8d0-1c3f5a9e7b2d" \
  -d '{
    "amount": 5000,
    "currency": "usd",
    "payment_method": "pm_card_visa"
  }'
GET and DELETE requests are inherently idempotent and do not require the header.

How caching works

When the API receives a POST request with an Idempotency-Key:
  1. It checks whether a response for that key already exists in the cache.
  2. If yes, it returns the cached response with a 200 status (or the original error status) without re-executing the operation.
  3. If no, it processes the request normally and caches the response.
Cached responses are stored for 24 hours, after which the key can be reused.

Same key, different parameters

If you send a request with the same idempotency key but different request body parameters, the API rejects it with a 422 status:
# First request - succeeds
curl -X POST https://api.leanrails.com/v1/payment_intents \
  -u "sk_test_xxx:" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: my-unique-key-123" \
  -d '{"amount": 5000, "currency": "usd"}'

# Second request with SAME key but DIFFERENT amount - rejected
curl -X POST https://api.leanrails.com/v1/payment_intents \
  -u "sk_test_xxx:" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: my-unique-key-123" \
  -d '{"amount": 9999, "currency": "usd"}'
Error response (422):
{
  "error": {
    "type": "invalid_request_error",
    "code": "idempotency_key_reuse",
    "message": "This idempotency key has already been used with different request parameters.",
    "param": null,
    "doc_url": "https://docs.leanrails.com/errors/idempotency_key_reuse"
  }
}

Best practices for generating keys

UUIDs provide sufficient entropy to avoid collisions and are supported natively in most languages.
# bash / zsh
uuidgen
For some operations, it makes sense to derive the key from a business identifier to ensure a specific operation only happens once.
# Ensure a specific order is only charged once
# Use: "charge-order-12345" as the Idempotency-Key value
Persist the idempotency key alongside the operation in your database before making the API call. If your process crashes, you can retry with the same key.

Retry strategy with idempotency

A safe retry approach using idempotency keys:
# Generate the key once, reuse on retries
IDEMPOTENCY_KEY=$(uuidgen)

# First attempt
curl -X POST https://api.leanrails.com/v1/payment_intents \
  -u "sk_test_xxx:" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -d '{"amount": 5000, "currency": "usd", "payment_method": "pm_card_visa"}'

# If it failed due to network error or 5xx, retry with the SAME key
curl -X POST https://api.leanrails.com/v1/payment_intents \
  -u "sk_test_xxx:" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -d '{"amount": 5000, "currency": "usd", "payment_method": "pm_card_visa"}'

Key constraints

PropertyValue
Maximum length255 characters
Cache duration24 hours
Required onAll POST requests
Reuse with different paramsRejected with 422