Idempotency
Safely retry POST and PATCH with the Idempotency-Key header.
POST and PATCH requests can be made idempotent by passing an Idempotency-Key header. Dolores caches the response (status code + body) keyed on (project, key) for 24 hours. Replays return the original response — even if it was an error — so a network blip during your retry doesn't create a duplicate customer or double-book an appointment.
Sending an idempotency key
The key is any string up to 255 characters. UUIDs are the conventional choice:
curl https://app.meetdolores.ai/v1/customers \
-H "Authorization: Bearer $DOLORES_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 1d8f4a2c-5e9b-4a07-9c6b-2f1d0a8b3c41" \
-d '{ "phone": "+14155551234", "name": "Alice" }'const res = await fetch('https://app.meetdolores.ai/v1/customers', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.DOLORES_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({ phone: '+14155551234', name: 'Alice' }),
});What gets cached
When the original request succeeds (2xx), Dolores caches:
- The HTTP status code
- The full response body
Replays return the cached value with an additional Idempotent-Replay: true header so your client can tell a replay from a fresh response.
Body mismatch detection
Reusing the same key with a different request body within the 24-hour window returns 409:
{
"error": {
"type": "invalid_request_error",
"code": "idempotency_key_conflict",
"message": "This Idempotency-Key was used with a different request body within the last 24 hours.",
"request_id": "req_01HXY..."
}
}This is a hard safety net: if you accidentally re-use a key for a totally different operation, you get a loud failure instead of a silent shadow-write.
Best practices
- Generate the key once per logical operation, not once per HTTP request. If you retry the same operation across reconnects, use the same key.
- Keep the body stable. Don't include client-side timestamps or random nonces inside the body if you're going to retry the same call.
- 24h is the cache TTL. After that, replays count as fresh calls. Don't use idempotency keys as a long-term de-dup mechanism — use your own database for that.
- Use UUIDs. Anything random and long enough avoids accidental collisions. Don't use sequential integers or user-supplied input.
When to use it
Idempotency keys matter most for side-effectful POSTs where a duplicate would cause downstream problems:
- Creating a customer (could create two with the same phone if your duplicate detection is via external system)
- Creating an appointment
- Sending a test webhook
GET and DELETE are naturally idempotent at the protocol level — no key needed. PATCH accepts the header for the same retry-safety reasons as POST.