Two schemas can run behind one endpoint only if every request says which one it wants. Without that, the server guesses from the payload shape, and guessing is the failure mode you are trying to avoid: a caller sends a field that exists in version 2 but not version 1, the server picks the wrong schema, and validation passes against the wrong contract.
A version identifier belongs in one of two places.
A request header, such as X-Tool-Schema: 2. Headers keep the payload clean, so the JSON body is exactly the tool arguments. The cost is that headers are easy to strip. Proxies, API gateways, and some agent frameworks rebuild requests and drop unknown headers, so the version can vanish silently.
An envelope field, a wrapper object with the version and the arguments:
{
"schema_version": "2",
"tool": "create_invoice",
"arguments": { "customer_id": "cus_8841", "amount_cents": 24900 }
}
The envelope survives every hop because it is part of the body. It also makes the contract self-describing in logs and traces: a stored request tells you which schema it targeted without header capture. The cost is one extra level of nesting in every payload.
The tradeoffs between URI, query parameter, header, and hybrid versioning strategies are covered in Gravitee's overview. For tool calls the envelope wins more often than it does for REST, because tool arguments are usually generated by a language model and the envelope gives you a place for metadata the model does not have to invent.
A practical rule: if your callers are your own agents and you control the client library, use a header. If callers are third parties, or you pass through a gateway you do not fully control, use the envelope from day one. Pick one as canonical and treat the other as an alias you can retire. Two ways to say the same thing is two ways to disagree.
Wherever the version goes, the routing layer reads it first, before deserialization into a typed tool-arguments struct. Deserialize after you know the schema, not before, because a tolerant parser that accepts fields from versions it does not understand is how wrong-schema bugs slip through.



