Idempotency
Use Agent-Idempotency-Key to make retried POST requests safe, the agent-idempotent-replay response header, and the replay and in-flight-conflict semantics.
A network blip between your client and Zumik leaves you unsure whether a mutation landed. Retrying blindly risks a double charge, a duplicate session event, or two artifacts. An idempotency key makes the retry safe: the same key replays the original response instead of running the mutation again.
How it works
Attach a key to any POST request:
-H "Agent-Idempotency-Key: a1b2c3-your-unique-token"Zumik scopes the key to your project and the request path. The first time it sees a given (project, path, key) triple, it runs the handler and caches the successful response. A later request with the same triple returns that cached response verbatim, flagged as a replay, without re-executing.
The key is yours to choose. Use a UUID, or a deterministic value derived from the operation (for example a hash of the work unit) so a retry naturally reuses it.
Idempotency applies to POST only. GET and DELETE are naturally safe to repeat, so a key on them is ignored.
The replay header
Every idempotency-eligible response carries agent-idempotent-replay so you can tell a fresh execution from a replay:
| Header value | Meaning |
|---|---|
agent-idempotent-replay: false | This request executed for the first time and its result was cached. |
agent-idempotent-replay: true | This is a replay of a previously cached response. The mutation did not run again. |
A replay returns the original status code, content type, and body byte-for-byte.
In-flight conflict
If a second request carrying the same key arrives while the first is still executing, Zumik does not run it. Running it could double-charge. Instead it returns 409 with the idempotency_conflict type:
{
"error": {
"type": "idempotency_conflict",
"message": "A request with this Agent-Idempotency-Key is already in progress. Retry after it completes."
}
}Wait for the original to settle, then retry; you will get the cached result with agent-idempotent-replay: true.
What gets cached, and for how long
- Only successful responses are cached. A
4xxor5xxreleases the key immediately, so a transient failure stays retryable and a corrected request can run. - Replays last 24 hours. After that the key ages out and a request with it executes fresh.
- A reservation from a handler that crashed mid-flight is reclaimed after 60 seconds, so a key is never stuck.
The cache is keyed per project, so two tenants using the same key string never collide.
Example
# First call: executes, caches, returns agent-idempotent-replay: false
curl https://api.zumik.ai/v2/artifacts \
-H "Authorization: Bearer zk_live_..." \
-H "Content-Type: application/json" \
-H "Agent-Idempotency-Key: create-policy-2026-06-15" \
-d '{"artifact_type":"policy","content":"Run the linter before every commit."}'
# Retry after a timeout: same key returns the identical artifact,
# now with agent-idempotent-replay: true
curl https://api.zumik.ai/v2/artifacts \
-H "Authorization: Bearer zk_live_..." \
-H "Content-Type: application/json" \
-H "Agent-Idempotency-Key: create-policy-2026-06-15" \
-d '{"artifact_type":"policy","content":"Run the linter before every commit."}'See idempotency and retries for a complete client retry pattern, and headers for the full header reference.
Errors
The OpenAI-compatible error envelope and the full Zumik error-code table, with HTTP status, meaning, and how to fix each one.
Headers
Every Agent-* request header Zumik reads and every response header it emits, including alias release, resolved provider, execution profile, trace id, region, and QoS signal.