B2B platform for digital goods

Idempotency Keys in B2B Order APIs 2026: Deep Dive with UUIDv4

Full guide to idempotency keys for B2B order APIs: UUIDv4 generation, 24h dedup window, retry-safe POST /v1/orders.

Idempotency Keys in B2B Order APIs 2026: Deep Dive with UUIDv4

Idempotency keys are the technique that makes any POST request in a B2B API retry-safe. Without them every network timeout on the client turns into a "did the order create or not?" question β€” and in 30% of cases the answer is "both". This article walks through production patterns borrowed from Stripe and applied to the FoxReload Orders API.

1. Why a single retry creates two orders

A simple sequence: your ERP issues POST /v1/orders with payload {sku: "PSN_TR_50", qty: 1}. FoxReload creates the order and starts delivery, but the TCP response is lost (network blip). Your HTTP client retries after 30s β€” FoxReload sees a new request, creates a second order, debits your balance twice. Result: duplicate.

With an idempotency key this scenario is impossible: the server sees the same key, returns the original response, and the second order is never created.

2. UUIDv4 generation on the client

The key must be globally unique and unpredictable. UUIDv4 is the standard choice:

import { randomUUID } from 'crypto';
import axios from 'axios';

async function createOrder(sku: string, qty: number) {
  const idempotencyKey = randomUUID(); // UUIDv4
  return axios.post('https://api.foxreload.com/v1/orders', {
    sku, qty, currency: 'USD',
  }, {
    headers: {
      'Authorization': `Bearer ${process.env.FOXRELOAD_KEY}`,
      'Idempotency-Key': idempotencyKey,
    },
    timeout: 30000,
  });
}

Persist idempotencyKey in your DB before issuing the request. On retry, read the same key β€” never generate a new one.

3. Server-side dedup window

FoxReload stores each key in Redis with a 24h TTL. Processing logic:

// server-side pseudocode
async function handleCreateOrder(key: string, payload: OrderPayload) {
  const existing = await redis.get(`idem:${key}`);
  if (existing) {
    const stored = JSON.parse(existing);
    if (hash(payload) !== stored.payloadHash) {
      return { status: 422, error: 'idempotency_conflict' };
    }
    return stored.response; // retry β€” return original
  }
  const response = await createOrderInternal(payload);
  await redis.set(`idem:${key}`, JSON.stringify({
    payloadHash: hash(payload),
    response,
  }), 'EX', 86400);
  return response;
}

The race between two simultaneous requests using the same key is resolved with Redis SETNX plus a Postgres advisory lock on idempotency_key.

4. Comparing dedup storage backends

Storage Throughput Latency TTL Cost
Redis (hot) 200k/s <1ms 24h $0.40/M
Postgres UNIQUE 30k/s 5–8ms ∞ $0.10/M
DynamoDB 100k/s 8–12ms 24h $1.25/M
Memcached 500k/s <1ms 24h $0.30/M

FoxReload runs a 6-node Redis cluster sharded by hash(idempotency_key). This delivers <2ms p99 latency on the dedup check.

CTA

Idempotency-Key is supported on every POST/PUT/DELETE endpoint of the FoxReload API. The full reference is available after onboarding β€” request access.

Frequently asked questions

What happens if I send the same Idempotency-Key with a different payload?
FoxReload returns HTTP 422 idempotency_conflict with the original response in the payload. This guards against a client bug where the same key is generated for a different order. On the client side: alert and manual review.
What is the TTL of an idempotency key on FoxReload?
24 hours from first use. After 24h the same key can be reused β€” but you shouldn't; always generate a fresh UUIDv4 per attempt.
Do I need Idempotency-Key on GET requests?
No. GET is idempotent by definition β€” repeating a GET has no side effects. Idempotency-Key is mandatory only on POST /v1/orders, POST /v1/refunds, POST /v1/transfers.
What if FoxReload returns a timeout β€” was the order created or not?
Retry with the same Idempotency-Key. If the original request landed you get the same order_id and status; if not, the order is created. Either way, no duplicate is possible.
Get FoxReload API access

Related articles