Idempotency
Network timeouts and aborted connections make it hard to know whether a metering POST actually landed. Replaying the call could mean double-counted usage, which then has to be cleaned up by hand. Revenium accepts a Stripe-style Idempotency-Key header on metering write endpoints so retries are safe by default.
How it works
Send a unique, client-generated string in the Idempotency-Key header on a metering POST. Revenium caches the response (status code and body) for 24 hours keyed by your account and that key. Any retry that reuses the same key replays the cached response without re-executing the request. Use a fresh key for every distinct call, and reuse the same key only when retrying that exact call.
The header is opt-in. Requests without it pass through unchanged.
Supported endpoints
Idempotency applies to every REST metering POST endpoint.
POST
/meter/v2/ai/completions
POST
/meter/v2/ai/images
POST
/meter/v2/ai/audio
POST
/meter/v2/ai/video
POST
/meter/v2/apis/requests
POST
/meter/v2/apis/responses
POST
/meter/v2/events
POST
/meter/v2/tool/events
OTLP endpoints (/v2/otlp/**) are not covered today. The OTLP SDKs already retry internally, so end-to-end retry safety on that path will land in a future release.
Key format
Length
1 to 255 characters
Charset
Printable ASCII only (! through ~, no spaces, no control characters)
Recommended
UUID v4 generated client-side, one per logical request
Keys are scoped per account, so two accounts can use identical key strings without colliding.
Behavior matrix
What the server returns depends on whether a record already exists for (account, key) and what the request body looks like.
New key
Request runs normally, response is cached for 24 hours
Same key, same request
Cached response is replayed: original status code, body, and content type
Same key, different body
409 Conflict with code idempotency_key_mismatch
Same key, concurrent retry while the first call is in flight
409 Conflict with code idempotency_key_in_progress, header Retry-After: 1
Key fails format validation (empty value, longer than 255 characters, non-printable characters, or sent more than once in the same request)
400 Bad Request with code invalid_idempotency_key
The fingerprint that defines "same request" is (HTTP method, request path, request body). Request headers (including content type) and query string are not part of it. If you send the same body to the same endpoint with the same key, you will get the cached response back.
Error envelope
All idempotency errors share the same JSON envelope.
type
idempotency_error for 409 conflicts, validation_error for 400 bad key format
code
One of idempotency_key_mismatch, idempotency_key_in_progress, invalid_idempotency_key
message
Human-readable description of the specific case
doc_url
Link back to this page
Recommended client behavior
Generate one UUID v4 per logical request. Treat the key as part of that request, not a per-session token. The same logical retry must reuse the same key.
Persist the key with your retry state. If your client retries from another process or after a restart, it still needs the original key to benefit from replay.
Send the same body on retry. If your client mutates the payload between attempts (a fresh timestamp, a regenerated trace id), the second call returns
idempotency_key_mismatch. Build the body once, then resend the same bytes.Handle
idempotency_key_in_progresswith a short wait. Your previous call is still executing. RespectRetry-After: 1and try again.Treat the cache TTL as 24 hours. A retry sent more than 24 hours after the original call will execute fresh, with no replay. By that point a real duplicate is extremely unlikely; if you need stricter guarantees, deduplicate client-side as well.
If you have a use case that needs broader idempotency coverage, contact support.
Last updated
Was this helpful?