API versioning
The Trade HQ API is versioned by date. Each version is named for the day it was released, written
YYYY-MM-DD, and once released a version does not change: an integration built against one keeps
getting the same behaviour until it chooses to move.
The current version is 2026-10-01.
Choosing a version
Send the version you built against in the Trade-HQ-Version request header:
Trade-HQ-Version: 2026-10-01
The version a request is served is decided in this order:
- The
Trade-HQ-Versionheader, when the request sends one. - The API key’s pinned version, when the request is made with an API key and sends no header.
- The current version, when neither applies.
Every response, including errors, carries a Trade-HQ-Version header naming the version that served
it. If you are not sure which version your integration is running on, read that header.
API keys are pinned
An API key is pinned to the version that is current on the day it is created. A request made with
that key and no Trade-HQ-Version header is served the pinned version, so an integration that never
sends the header is not moved to a new version when one is released.
The header always wins over the pin. To try a newer version, send it in the header on the requests
you want to test; when you are ready to move everything, change the key’s pinned version on
Settings > Organization > API keys (“Change version”), or with the set_api_key_version capability
through the API or MCP. An organisation admin may re-pin a key to any version the API serves, an older
one included, which is how a move that broke an integration is undone. Keys created before versioning
existed are pinned to 2026-10-01, the first version.
Signed-in sessions in the Trade HQ web app are not pinned; they use the current version.
Errors
A request naming a version the API does not serve is refused with 400 Bad Request before anything
else is done with it, and the error names the reason:
| code | meaning |
|---|---|
malformed_version | The header is not a single YYYY-MM-DD date. v1, latest and 2026-10-1 are all malformed. |
unknown_version | The header is a date, but not one of the versions listed below. |
unknown_pinned_version | No header was sent, and the key is pinned to a version that is no longer supported. Send the header, or re-pin the key. |
malformed_pinned_version | No header was sent, and the key’s pinned version is not a date. Send the header, or re-pin the key. |
{
"error": {
"code": "unknown_version",
"message": "Trade-HQ-Version 2020-01-01 is not a version this API serves; it serves 2026-10-01"
}
}
When a new version is released
A new version is released only for a breaking change. A change is breaking when an integration that worked before it could fail or behave differently after it. That includes:
- removing or renaming a field, an argument, an operation or an endpoint;
- changing a field’s type, format or nullability, or narrowing the values it accepts;
- changing the shape of an error, or the status or code a request is refused with;
- changing a default, including the default ordering, page size, or what an omitted argument means;
- adding a new required argument or header.
Additive changes ship in the current version and do not get a new one: a new field, a new optional argument, a new operation or endpoint, a new value in a list you should already treat as open-ended, or a new error code for a condition that previously could not occur. Build your integration to ignore fields it does not recognise.
A version is never changed after its release date. A fix that would alter documented behaviour of a released version is itself a breaking change and ships in a new version.
Support
A version is supported for twelve months after the version that replaces it is released. From
the day it is replaced, every response served under it carries Deprecation (when it was replaced)
and Sunset (when it stops being served), and the admins of every organisation holding a key pinned
to it are emailed the same two dates and how to move. HTTP.md says exactly what the twelve months
cover. During
that window it is served exactly as released. When the window ends, requests naming that version,
and keys pinned to it, are refused with unknown_version or unknown_pinned_version. The date a
version stops being served is published in the table below as soon as its successor is released.
| version | released | status | supported until |
|---|---|---|---|
2026-10-01 | 2026-10-01 | current | until twelve months after the next version |
Changelog
Every changelog entry names the version it belongs to.
- An entry for a breaking change is filed under the new version it introduces, dated that version’s release day, and says what to change in an integration to move to it.
- An entry for an additive change is filed under the version it shipped in (always the current version at the time), dated the day it shipped.
An entry that does not name a version is not a changelog entry.