Idempotency
Idempotency means making the same API call twice produces exactly the same outcome as making it once. For actions that create something in the real world — an outbound phone call, an SMS, a broadcast campaign — that guarantee is essential: networks time out, servers restart, and retry logic is unavoidable. Idempotency keys let you retry safely without the risk of duplicate actions or double charges.
Consider a voice broadcast campaign that dials 10,000 numbers. Your server sends the request, the EnableX API processes it — then your server's HTTP connection drops before it receives the response. You don't know whether the broadcast started or not. If you retry the request without an idempotency key, EnableX treats it as a new broadcast and dials all 10,000 numbers a second time.
The same risk exists at any scale:
- An SMS send times out — the customer receives the message twice.
- An outbound call request fails mid-flight — the recipient's phone rings twice from your system.
- A WhatsApp message retry during a brief network blip — the user sees a duplicate notification.
Attaching an Idempotency-Key header eliminates every one of these scenarios.
EnableX records the response from the first successful execution and returns that same response
on every subsequent request that carries the same key — without re-executing the action.
The mechanism is straightforward:
-
You send a POST request with an
Idempotency-Keyheader. The key is a unique string you generate — typically a UUID v4 — that you associate with this specific operation on your side. - EnableX executes the request and caches the response. The response body and HTTP status code are stored against your key for 24 hours.
-
Any retry with the same key returns the cached response.
The action is not re-executed. The response you receive is byte-for-byte identical to the
original — including the
job_id,voice_id, orbroadcast_idthat was assigned to the original operation. - After 24 hours the key expires. A request with an expired key is treated as a new operation and executed from scratch.
Add the Idempotency-Key header to any eligible POST request. The value should be
a UUID v4 string that you generate once, store on your side, and reuse on every retry of the
same logical operation.
POST https://api.enablex.io/voice/v1/call
Authorization: Basic <base64(APP_ID:APP_KEY)>
Content-Type: application/json
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
{
"name": "Support Call",
"owner_ref": "ref001",
"from": "+6512345678",
"to": ["+919876543210"],
"webhook": {
"url": "https://your-server.com/voice/webhook"
}
}
If this request times out or your connection drops, generate no new key — retry with the
same Idempotency-Key value. EnableX returns the original
response, and only one call is placed.
Idempotency keys are recommended on every POST endpoint that initiates a real-world action. The risk level reflects what happens if that action fires twice.
| API | Endpoint | Risk Without a Key |
|---|---|---|
| Voice | POST /voice/v1/call |
Recipient's phone rings twice from your system |
| Voice Broadcast | POST /voice/v1/broadcast |
Entire recipient list is dialled a second time — critical for campaigns |
| SMS | POST /sms/v1/messages/ |
Customer receives duplicate SMS messages |
POST /whatsapp/v1/messages |
User receives duplicate WhatsApp messages | |
| RCS (session) | POST /rcs/v1/messages |
Duplicate RCS message delivered |
| RCS (template) | POST /rcs/v1/messages/templates |
Duplicate templated RCS message delivered |
| Unified Messaging | POST /messaging/v1/send |
Cascade send fires across all configured channels twice |
Key Format
EnableX accepts any string up to 255 characters as an idempotency key. In practice, use a UUID v4: it is random, globally unique, and requires no coordination across your systems.
// Node.js — built-in crypto module (Node 14.17+)
const { randomUUID } = require('crypto');
const idempotencyKey = randomUUID();
// → "550e8400-e29b-41d4-a716-446655440000"
# Python — standard library
import uuid
idempotency_key = str(uuid.uuid4())
# → "550e8400-e29b-41d4-a716-446655440000"
Key Rules
- One key per logical operation. Generate the key once per operation, store it, and reuse it only for retries of that same operation. Do not share keys across different operations or different API endpoints.
- A different payload still returns the first response. If you send the same key with a different request body, EnableX ignores the new body and returns the cached response. Generate a new key whenever the intent of the operation changes.
- Keys are scoped to your APP ID. The same key string used by two different APP IDs does not cause a conflict.
| Scenario | What EnableX Does |
|---|---|
| First request with a new key | Executes the request normally and caches the response. |
| Retry with the same key (within 24 h) | Returns the cached response immediately. Action is not re-executed. |
| Same key, different request body | Returns the cached response. The new body is ignored. |
| Key is 24 h old or older | Key has expired. The request is executed as a new operation and a fresh response is cached. |
| Request sent without any key | Treated as a standard (non-idempotent) request. Every call is executed independently. |
-
Reusing a key for a different recipient or number. If you send
Idempotency-Key: abc-123to call number A, then reuseabc-123to call number B, EnableX returns the response from the call to number A. Number B is never dialled. Always generate a fresh key for each distinct operation. - Not storing the key before sending. If your process crashes after sending but before receiving the response, and you did not persist the key, you have no way to safely retry. Persist the key to durable storage before the HTTP call.
- Generating a new key on every retry. A new key causes EnableX to execute the action again. Retries must carry the original key to be idempotent.
-
Using sequential IDs or timestamps as keys. Sequential values like
msg-1,msg-2or1714900000000are easy to accidentally reuse or predict. Use UUID v4 to avoid collisions.