Skip to main content
The X-Idempotency-Key header allows you to safely retry requests without risk of duplicate operations. When you include an idempotency key, we guarantee that multiple requests with the same key will execute the operation only once.

How It Works

First Request: We process the operation and cache the complete response (including status code, headers, and body) associated with your idempotency key. Subsequent Requests: If we receive another request with the same key, we return the cached response immediately without re-executing the operation.

Key Requirements

Generate unique keys per operation: Generate a unique identifier for each distinct operation. Never reuse keys across different operations. Immutable request fingerprint: For a request to be considered a valid retry, the following must be identical:
  • Request method (POST, PUT, etc.)
  • Request URL (including path and query parameters)
  • Request body (exact byte-for-byte match)
  • Request headers that affect processing (e.g., Content-Type, Authorization)
Modified requests are rejected: If you send the same idempotency key with different request data, we’ll reject it with 409 Conflict. This prevents accidental misuse where the same key is reused for a different operation.

Response Behavior

ScenarioResponse
First request with keyNormal processing, response cached
Retry with identical requestCached response returned (same status, headers, body)
Concurrent identical requests409 Conflict with idempotency_key_locked (retry after brief delay)
Retry with modified request409 Conflict with idempotency_key_mismatch (do not retry)

Error handling guidance

Concurrent collision (idempotency_key_locked): A temporary condition when another request with the same key is currently processing. Retry the identical request after a brief delay (100-500ms). Request mismatch (idempotency_key_mismatch): The key was previously used with different request parameters. This indicates a programming error—generate a new idempotency key for the new operation.

Expiration

Idempotency keys expire after 24 hours. After expiration, the same key will be treated as a new operation.

Best Practices

  • Generate keys client-side before making the request
  • Store the key with your request context so you can retry with the same key
  • Use idempotency keys for all non-idempotent operations (POST, PATCH)
  • Don’t use predictable patterns (timestamps, sequential IDs)—use cryptographically random values

Example

const idempotencyKey = '550e8400-e29b-41d4-a716-446655440000';
const orderData = {
  customerId: 'cust_123',
  items: [...]
};

// First request
const response = await fetch('https://connect.telnesstech.com/api/v2/orders', {
  method: 'POST',
  headers: {
    'X-Idempotency-Key': idempotencyKey,
    'X-API-Key': process.env.CONNECT_API_KEY,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(orderData)
});

const result = await response.json();
// Response: 201 Created
// {"orderId": "1b11f175-f0e6-4b6c-8c4b-4eee806123a3", "status": "CONFIRMED", ...}

// Retry (network timeout, uncertain state)
// Use the same idempotency key and request data
const retryResponse = await fetch('https://connect.telnesstech.com/api/v2/orders', {
  method: 'POST',
  headers: {
    'X-Idempotency-Key': idempotencyKey, // Same key
    'X-API-Key': process.env.CONNECT_API_KEY,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(orderData) // Same data
});

const retryResult = await retryResponse.json();
// Response: 201 Created (identical to first request)
// {"orderId": "1b11f175-f0e6-4b6c-8c4b-4eee806123a3", "status": "CONFIRMED", ...}
// No duplicate order created
I