What is an idempotency key for AI agent tool calls?
An idempotency key names one operation, so repeating an agent's tool call returns the first result instead of running it twice. How to choose one, what it does not stop, and how Anlyon uses it.
An idempotency key for an AI agent tool call is an identifier for one intended operation, sent with every attempt of it, so a repeated call returns the recorded result instead of performing the side effect again. In plain words: a retry can't charge the card twice.
Why do agents need one?
Agents repeat calls more than ordinary clients. The model calls the tool again because it lost the result. The framework retries a tool that threw. A worker restarts between "call the API" and "record that we did". A response is lost after the write succeeded. Each of these sends the same refund again, and without a key each one looks new.
How do you choose the key?
Name the operation, not the attempt:
refund:ord_42is one refund per order. A later, intended second refund gets its own identity, such asrefund:ord_42:partial_2.- A UUID created once and stored with the business request also works.
- A fresh UUID or timestamp on every attempt makes every retry look like a new operation.
Create the key before the first attempt and send the identical key on every retry.
Example
import { Client } from '@anlyonhq/sdk';
const agent = new Client({ apiKey: process.env.ANLYON_AGENT_KEY! });
const orderId = 'ord_42';
const { data } = await agent.actions.invoke(
'refund-order',
{ charge: 'ch_3P9x', amount: 12000 },
{ idempotencyKey: `refund:${orderId}` },
);
| Situation | What Anlyon does |
|---|---|
| Same key, same request | Answers from the recorded invocation. Nothing is executed, admitted or charged again |
| Same key, different request | Refuses with 409 idempotency_key_reuse |
| The first request is still running | Waits and replays, or answers 409 idempotency_request_in_progress |
| No key passed | The SDK generates one for that call and resends it on transport retries |
A key the SDK generates covers one SDK call. Two calls are two invocations. Pass your own key when the operation can be retried across calls or restarts.
What an idempotency key does not do
- It does not retry for you. Anlyon does not retry an action invocation. A deliberate re-run of a template action needs a failed original, a new key and
retryOf. - It does not settle an unknown outcome. Reusing the key reads the existing invocation in its current state. An unknown outcome must be resolved before a retry.
- It does not bound business intent. Two different keys can request two refunds of the same payment. A shared limit bounds that.
- Provider idempotency is a separate layer. Stripe and Resend keep a key for 24 hours. On a governed action,
operationKeynames the business operation: the same key with the same request returns the existing effect.
Related terms
Read next
Frequently asked questions
What happens when an agent repeats a call with the same idempotency key?
In Anlyon, a same-key, same-request invoke is answered from the recorded invocation. It is not executed, admitted or charged again. The same key with a different request is refused with 409 idempotency_key_reuse.
Does an idempotency key stop an agent from refunding twice?
It stops the same operation running twice. It does not stop the agent asking for a second refund under a new key, because two keys are two operations. A shared limit is what bounds the total.
