Idempotency in the API
There is no Idempotency-Key header on any Connect interface, and no key lifetime to plan around. Every published operation is a read, so repeating one has no effect beyond spending an allowance. The interesting question is not safety but sameness — whether a repeated call returns the same answer.
What an idempotency key is for, and why there is none#
A key exists so that a client which cannot tell whether its request arrived can send it again without creating a second charge, a second message or a second record. It matters exactly where a request has an effect. Everything Connect publishes is a GET over generated documentation, or a JSON-RPC read; there is no public write endpoint, no record to duplicate and nothing to charge. A key would be ceremony around an operation that already cannot go wrong twice.
So no header is accepted. Sending Idempotency-Key is harmless and is ignored, like any other unrecognised header, and there is no store of keys, no replay window and no conflict response to handle.
Does Connect use this?#
- Public HTTP API
- No key. All five endpoints are
GET; HTTP already defines them as safe and idempotent. - MCP tools
- No key. Every tool declares
idempotentHint: trueandreadOnlyHint: truein its annotations, which is a hint to a client rather than a contract, but here it happens to be exact. - A2A skills
- No key. A skill has no side effect, though see the caveat below about identifiers.
- Inside the product
- Retried provider callbacks are a real problem that Connect has to solve, and it is solved inside the product rather than through a client-supplied key. Idempotency for retried telephony webhooks is the engineering note on that; nothing about it is exposed on a public interface.
Where sameness actually stops#
*Safe* and *identical* are different promises, and only the first is unconditional here. Two calls a second apart return the same page; two calls either side of a deploy may not, because the corpus is regenerated and a page's prose, summary or status can change. The updated date on every page is how you detect that, and it is the right cache key.
Search is the other place a repeat can differ. Results are ranked, and ranking depends on the index — which rebuilds when the manifest's modification time changes. Ordering is deterministic for a given index and query, with ties broken by path so it never wobbles for equal scores, but a new deploy can reorder results. Pin to a url or an id when you need the same page tomorrow, never to a position in a list.
Retrying safely#
Retry
429and5xxfreely — there is no double-effect risk to weigh against it.Result The only cost of an extra attempt is the allowance it spends.
Do not retry
404or a validation failure.Result The request was wrong; the same request will be wrong again.
Key your own cache on
urlplusupdated, not on the response body.Result You get correct invalidation across a deploy without comparing prose.
If you need a result set to stay stable across a job, snapshot it.
Result Re-running a search mid-job can reorder it; a snapshot cannot.
Questions#
Will an Idempotency-Key header break anything?
No. It is not read and not rejected. Nothing stores it, so nothing can go stale or conflict.
If a write API ever exists, will this page describe it?
This page describes what is published now, which is read-only. It makes no claim about anything else, and neither should a client built from it.
Is a repeated MCP tools/call guaranteed to return byte-identical JSON?
Within one deployment, in practice yes for a fetch by id or path. Across deployments, no — the corpus is regenerated. Compare updated, not bytes.