Skip to content
Runtime

What is an idempotency key?

An idempotency key is a unique string sent with a write. The server uses it to recognize a retry. The server then returns the first result instead of acting a second time.

On Runtime, every write carries an idempotency key. Both SDKs create one for you and retry with it. A create whose reply was lost never makes a second sandbox, and a retried command never runs twice (errors and retries). The server keeps each key for 24 hours.

Why it matters for AI agents

Networks drop replies. When a create request times out, the client cannot tell whether the server never received it or completed it and the reply was lost. A retry without a key may start a second machine, which is billed and forgotten. A retried exec may run git push or a payment call a second time.

Agents make this worse. They retry by design, often from a new process after a crash. An MCP client may repeat a tool call that it believes failed. An idempotency key turns "did that happen?" into a question that the server answers.

How Runtime treats a key

Request What the server does
Same key, same body Returns the first result again, with "replayed": true
Same key, different body Returns 422 idempotency_key_reused
New key Treats the request as new work
Header Idempotency-Key: <any unique string>; a replay adds Idempotency-Replayed: true
How long a key is kept 24 hours
What the SDKs retry with the key Transport failures, 429, 502, 503 and 504, with a growing delay

A failed fork is final. A retry with the same key returns the same error. To try again, fork with a new key (API).

Survive a process restart

The key that the SDK creates lasts only as long as the call. To make a retry safe after your own process stops, derive the key from the job. The next attempt then sends the same key.

This demonstration chooses a new job ID once. A restarted worker loads the saved ID from its queue, and it keeps both that ID and the input unchanged. Never choose a new job ID inside a retry loop.

TypeScriptimport { randomUUID } from "node:crypto";import { Runtime } from "withruntime";const runtime = new Runtime();const job = randomUUID();const input = { labels: { job } };await using sbx = await runtime.sandboxes.create(input, { idempotencyKey: `create-${job}` });console.log(sbx.id); // a retry within 24 hours answers this same sandbox

Send the same body on the retry. If you change the input under the same key, the request is not a retry, and the server returns an error to say so.

Keys over MCP

An agent that calls Runtime's MCP tools directly should choose and record a unique idempotencyKey before the first call. After a lost reply, it should reuse that key with identical input. The server generates a key for an omitted field, and that key cannot be recovered from a lost reply. Read the resource before you repeat that write (MCP).

When a command's outcome is still unknown after a timeout, inspect its files and processes before you repeat a side effect (troubleshooting).

Facts on this page were checked on 25 October 2026.

100 free hoursin your first 30 days.

of a 1 GB machine

  • No credit card
  • Four sandboxes at once, 2 vCPU and 4 GiB each
  • Then prepaid credit from $10, no plan fee
Start free, no card
Start free, no card