
# Idempotency

Networks drop, timeouts fire, processes crash mid-call. On a pay-per-call platform the question "did that charge?" needs a better answer than *call again and hope*. The answer is the `Idempotency-Key` header — **every billable call takes one**, platform-wide, and you should always send your own.

## The contract

- **Same key, retried → the original result, once-billed.** If your call reached us and completed, a retry with the same key returns the stored original response and does not charge again.
- **Same key, different body → `409 IDEMPOTENCY_CONFLICT`.** A key names one exact request. Reusing it with changed content is rejected rather than silently returning the old result — the error tells you which mistake you made.
- **New key → new call, new charge.** A retry with a fresh key is a genuinely new operation. Generate one key per *intent*, reuse it for every retry of that intent.
- **Omitted key → the call still runs, unprotected.** We do not reject a key-less billable call; we mint an internal one. But then a retry of yours is indistinguishable from a new call — and bills as one. Always send your own key.
- **Scope.** Keys are scoped to you (another customer's identical string is unrelated) and remembered for 24 hours — past that, the same key is treated as new. Retries belong in the seconds-to-minutes window anyway.
- **Free reads don't need one.** Discovery and read endpoints (`GET /v1/doc/formats`, `GET /v1/llm/tasks`, status polls) are unbilled and take no key.

## The retry recipe

```bash
KEY=$(uuidgen)   # one key per intent — generate BEFORE the first attempt
curl -s -X POST https://api.relaystation.ai/v1/image/convert \
  -H "Authorization: Bearer $API_KEY" \
  -H "Idempotency-Key: $KEY" \
  -d '{"file":{"inline":"..."},"format":"webp"}'
# timeout? connection reset? → send the SAME request with the SAME $KEY
```

The failure mode this prevents: generating the key inside your retry loop. That turns three timeouts into three separately-billed calls. Generate once, outside the loop.

## On the lodestone path

x402 payments have their own replay protection (the signed authorization's nonce is single-use), and the `Idempotency-Key` matters there too: the nonce stops a *payment* from settling twice, while the key lets a retry *reuse* the completed work instead of being rejected as a replay. Sign once, pick one key, retry safely.
