Idempotency
Use stable idempotency keys so retryable Kadryn operations do not create duplicate usage, deliveries or actions.
Idempotency prevents duplicate side effects when a request is retried.
Use idempotency keys for retryable writes such as direct ingest events, batch imports, webhook tests, replay operations and workflow calls that can be safely retried.
Why it matters
Networks fail, workers retry and providers can time out.
Without idempotency, a retry can create duplicate usage events, duplicate costs or duplicate downstream effects.
With idempotency, Kadryn can recognize that two requests represent the same logical operation.
Header
Idempotency-Key: usage-event-prod-api-2026-07-06-001
Use the same key for retries of the same logical operation.
Use a different key for a different logical operation.
Good keys
Good idempotency keys are:
- stable;
- unique per logical operation;
- deterministic when retrying;
- scoped enough to avoid collisions;
- safe to log.
Examples:
usage-event-prod-api-openai-req-abc123
invoice-run-2026-07-06-001:step-01
batch-import-2026-07-06:page-004
webhook-test-endpoint-123:2026-07-06T12:00
Bad keys
Avoid:
random-value-created-on-every-retry
timestamp-only
user-input-only
same-key-for-all-events
full-secret-or-token
A random key per retry defeats idempotency.
Direct ingest example
curl "$KADRYN_API_BASE_URL/usage/events" \
-H "Authorization: Bearer $KADRYN_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: usage-event-openai-req-abc123" \
-d '{
"timestamp": "2026-07-06T12:00:00.000Z",
"provider": "openai",
"model": "gpt-4.1-mini",
"inputTokens": 1200,
"outputTokens": 300,
"costCents": "4",
"project": "prod-api",
"environment": "prod"
}'
Gateway retry example
curl "$KADRYN_GATEWAY_BASE_URL/chat/completions" \
-H "Authorization: Bearer $KADRYN_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Kadryn-Request-Group-Id: invoice-run-2026-07-06-001" \
-H "Idempotency-Key: invoice-run-2026-07-06-001:step-01" \
-d '{
"model": "gpt-4.1-mini",
"messages": [
{
"role": "user",
"content": "Summarize invoice status."
}
]
}'
Retry rules
When retrying:
- keep the same idempotency key;
- keep the same request group ID;
- preserve trace context;
- use exponential backoff;
- stop after a bounded number of attempts;
- do not retry permanent errors.
Retryable vs permanent errors
Usually retry:
- rate limits;
- network timeouts;
- temporary server errors;
- transient provider errors.
Do not retry blindly:
- authentication errors;
- validation errors;
- policy blocks;
- missing provider keys;
- permission errors.
Troubleshooting
I still see duplicates
Check whether retries reused the same idempotency key and whether the source event has a stable provider request ID or ingestion key.
A retry returns the original result
That is expected. Kadryn may return the existing result for the same logical operation.
A key collision happened
Make the key more specific. Include provider request ID, workflow step, timestamp bucket or batch page.