Core APIIdempotency

Idempotency

Opt-in safe retries with the Idempotency-Key header — 24-hour replay cache, conflict detection, and the privacy trade-off made explicit.

Safe retries

Network timeouts leave you not knowing whether a conversion happened — and whether retrying will bill you twice. Send an Idempotency-Key header on any POST and retries become safe:

curl -sS -X POST "https://api.transmute.403fin.io/v1/convert?to=camt.053" \
  -H "Authorization: Bearer $TRANSMUTE_KEY" \
  -H "Idempotency-Key: stmt-2026-07-05-batch17" \
  -H "Content-Type: text/plain" \
  --data-binary @statement.mt940

The first request executes normally and its response is cached for 24 hours. A retry with the same key and the same body gets the cached response verbatim, marked:

Idempotency-Replayed: true

Replays are never billed and never consume quota. They do pass through rate limiting, so a burst of retries still counts against your request rate.

The rules

RuleBehavior
Key format1–255 characters; anything else is a 400
Cache scopePer API key + idempotency key + SHA-256 of the body
Same key, different bodyidempotency-conflict 409 — pick a new key
Cache lifetime24 hours
Large responsesResponses over 1 MiB are not cached (the request still succeeds)
File uploads (multipart/form-data)Not supported — the header is refused with invalid-input 400, because the multipart boundary changes on every request. Use the JSON or raw form for idempotent retries

Choose keys that identify the logical operation — a statement id, a file hash, a job id — not random values (a random key per attempt defeats the purpose).

The privacy trade-off, stated plainly

transmute keeps message bodies in request memory. The replay cache is one of the two documented places data is held for a limited time (the other is batch jobs), and it applies to every POST you send with the header, not only convert:

  • What is kept: the full response (status, content type and a body of up to 1 MiB) and a SHA-256 of the request body. For convert, normalize, validate, verify, diff, anonymize and enrich, the body is the result, so it contains message data. For POST /v1/webhooks it includes the one-time signing secret.
  • For how long: 24 hours from the first request. Entries cannot be deleted early.
  • Where: in the API's process memory, or in Redis when a deployment configures one.
  • Never kept: the raw request body. Only its hash is stored, for conflict detection.

If that retention is unacceptable for your data, omit the header. Idempotency is opt-in, and nothing else about the API changes.