Skip to main content
When you record a decision, the network can fail after MeshQu has persisted it but before your code receives the response. Retrying blindly would create a duplicate decision. An idempotency key closes that gap: retry as many times as you like and you get back the same decision, recorded once.
Mental model: the idempotency key is a stable name for a business operation. The first request with that key records a decision; every later request with the same key returns the decision that already exists.
Evaluate vs Record — Idempotency applies to record, the endpoint that persists a decision. evaluate is stateless and stores nothing, so it has nothing to deduplicate.

How it works

When you call POST /v1/decisions/record with an idempotency_key, MeshQu checks whether a decision already exists with that key for your tenant: The second call returns the stored decision without running policies again, so retries are both safe and cheap.

Recording with an idempotency key

The TypeScript SDK requires idempotency_key on record() and throws if it is missing or blank. The REST API treats it as optional but strongly recommended — a record call without a key still succeeds, it just won’t be deduplicated. For any workflow that can retry (which is most of them), always supply one.

Choosing good keys

A key should uniquely and deterministically identify the business operation, so that a retry of the same operation produces the same key. Good keys — derived from a stable business identifier:
Bad keys — collide across operations, or change on every retry (defeating the purpose):

Key format

A key, once used, is bound to that decision permanently within the tenant. There is no expiry, so a retry months later still returns the original decision. If a decision genuinely needs to be re-made (for example after corrected input data), use a new key with a version suffix:

Safe-retry pattern

Treat both 200 and 201 as success. Retry only on server errors (5xx) and network failures — never on client errors (4xx), which indicate a request that won’t succeed on retry.
Because the key is stable, a retry after a post-write network failure returns the already-recorded decision instead of creating a second one.

Common patterns

Queue processing — use the message ID so reprocessing a redelivered message is a no-op:
Inbound webhooks — key on the delivery ID of the upstream system so its retries are absorbed:
Environment prefixes — avoid cross-environment collisions if a non-production system can ever reach the same tenant:

Verifying a key was used

Recorded decisions carry their idempotency_key. List recent decisions and filter: