ElebneElebneDocs
Reference

Idempotency

How to use the X-Idempotency-Key header to safely retry requests without creating duplicate resources.

Idempotency

The Elebne Developer API supports idempotency keys on all write endpoints, allowing you to safely retry requests without creating duplicate resources.

How it works

  1. Include an X-Idempotency-Key header with a unique string (e.g., a UUID) on your write request.
  2. The API processes the request and caches the response for 24 hours.
  3. If you send the same request with the same idempotency key within 24 hours, the API returns the cached response without re-executing the operation.
curl -X POST https://api.elebne.ai/api/v1/dev/intents \
  -H "Authorization: Bearer sk_test_YOUR_KEY" \
  -H "X-Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
  -H "Content-Type: application/json" \
  -d '{"amount": 50000, "description": "Order #1234"}'

Which endpoints require it

All write endpoints (POST, PATCH, DELETE) require the X-Idempotency-Key header. Requests without it return a 400 error with code IDEMPOTENCY_KEY_REQUIRED.

EndpointRequired
POST /dev/intentsYes
POST /dev/intents/:ref/cancelYes
POST /dev/intents/:ref/refundYes
POST /dev/intents/:ref/simulate-paymentYes
POST /dev/store/productsYes
PUT /dev/store/products/:idYes
DELETE /dev/store/products/:idYes
PATCH /dev/store/products/:id/variants/:vid/stockYes
POST /dev/store/products/import-csvYes
POST /dev/webhooks/endpointsYes
PUT /dev/webhooks/endpoints/:idYes
DELETE /dev/webhooks/endpoints/:idYes
POST /dev/webhooks/endpoints/:id/testYes
GET endpointsNo (read-only)

Key format

Idempotency keys can be any string up to 255 characters. We recommend using UUIDs (v4):

import { randomUUID } from 'crypto';

const idempotencyKey = randomUUID();
// "550e8400-e29b-41d4-a716-446655440000"
import uuid

idempotency_key = str(uuid.uuid4())
# "550e8400-e29b-41d4-a716-446655440000"

TTL and expiration

Idempotency keys expire after 24 hours. After expiration:

  • The same key can be reused with different parameters.
  • The original cached response is no longer returned.

Matching behavior

The API matches on the combination of:

  • API key (your sk_test_ or sk_live_ key)
  • Idempotency key (the X-Idempotency-Key header value)
  • Endpoint (the HTTP method and path)

If you send the same idempotency key to a different endpoint, it is treated as a new request.

Do not reuse keys across different requests

Sending the same idempotency key with different request parameters (e.g., different amounts) within the 24-hour TTL returns the original cached response, not a new one. Always generate a new key for each unique operation.

Retry safety

Idempotency keys make it safe to retry requests on network errors:

async function createIntent(amount, description) {
  const key = randomUUID();

  for (let attempt = 0; attempt < 3; attempt++) {
    try {
      const res = await fetch('https://api.elebne.ai/api/v1/dev/intents', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${apiKey}`,
          'Content-Type': 'application/json',
          'X-Idempotency-Key': key, // Same key for all retries
        },
        body: JSON.stringify({ amount, description }),
      });
      return await res.json();
    } catch (err) {
      if (attempt === 2) throw err;
      await new Promise(r => setTimeout(r, 1000 * (attempt + 1)));
    }
  }
}

The key insight: use the same idempotency key for all retry attempts of the same operation. This ensures at most one payment intent is created, even if your first request succeeded but the response was lost.

Next steps

Was this page helpful?

On this page