When creating a Hosted Checkout session via POST /checkout/v1/sessions, you can include the x-idempotency-key header to prevent duplicate charges in case of network errors or client retries.
x-idempotency-key is optional but recommended for any integration that retries session creation requests.
How It Works
If the server receives two requests with the same x-idempotency-key within the protection window, it treats the second as a retry and returns the original session without creating a new charge. After the window expires, a new request with the same key creates a new session.
| Scenario | Result |
|---|
| Same key, within 5 seconds | Returns the same session — no duplicate created |
| Same key, after 5 seconds | Creates a new session |
| Different key | Always creates a new session |
Implementation
Add x-idempotency-key alongside your other headers when calling the session endpoint:
| Header | Value | Required | Description |
|---|
Authorization | Token <API_PUBLIC_KEY> | Yes | Your Public API Key from the Tonder Dashboard |
Content-Type | application/json | Yes | Required for JSON body |
x-idempotency-key | <unique_id> | No | Unique key to guarantee idempotency. Default protection window: 5 seconds |
Generating a Key
Use a combination of your internal order identifier and a timestamp to create a key that is unique per session attempt and human-readable in logs:
x-idempotency-key: {external_id}-{timestamp}
Example:
x-idempotency-key: ORD-2025-A9B8-1739876543
Full Request Example
curl -X POST 'https://api-stage.tonder.io/checkout/v1/sessions' \
-H 'Authorization: Token YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-H 'x-idempotency-key: ORD-2025-A9B8-1739876543' \
-d '{
"customer": {
"first_name": "Juan",
"last_name": "Perez",
"email": "juan.perez@example.com"
},
"amount_total": 25000,
"currency": "MXN",
"line_items": [
{
"name": "Blue T-Shirt",
"quantity": 1,
"unit_price": 25000
}
],
"return_url": "https://your-store.com/checkout/complete",
"external_id": "ORD-2025-A9B8"
}'
When to Reuse vs. Regenerate a Key
Reuse the same key only when retrying the exact same session creation request after a network error or timeout. Generate a new key whenever the request body changes — for example, if the customer updates their cart or switches currency before retrying.
Generating a new key on each retry defeats idempotency protection. Store the key alongside your order record before sending the first request so you can retrieve it on retry.
Next Steps