API Changelog & Versioning Policy¶
Coalex exposes a single stable API surface under /v1/. We do not cut new URL
versions (/v2/) for evolutionary changes. Backward compatibility is preserved
through field aliasing and a deprecation window, so a customer on an older
SDK keeps working when the platform evolves.
How it works¶
- Breaking parameter/response changes keep the old name working for at least one full minor version before removal.
- When a request uses a deprecated alias, the response carries an
X-Deprecationheader describing the change and its removal version. - The SDKs read
X-Deprecationand emit a warning — Pythonwarnings.warn, TypeScriptconsole.warn— so you're notified without anything breaking. - Every SDK request sends
X-SDK-Version(e.g.coalex-python/1.13.0,coalex-ts/1.14.0), which the platform logs (sdk_version) so we can see which customers are on older SDKs before removing anything. - The proxy forwards both headers transparently (no allow-list), so this works end-to-end without per-header wiring.
Current deprecations¶
| Since | Endpoint | Deprecated | Use instead | Removal |
|---|---|---|---|---|
| v1.0 | POST /v1/evaluate |
trace_id |
request_id |
Not scheduled — see below |
evaluate() accepts trace_id as an alias for request_id. A request that sends
trace_id (and not request_id) gets:
This removal did not happen, and the date was wrong to publish
This row said v1.1. The Python SDK is now at 1.32.0 and the TypeScript SDK at 1.21.0, the
alias is still accepted, and the platform still falls back to treating the value as a trace id
(routes/evaluate.py). A removal date that passes twenty times over is worse than no date: it
tells a customer to migrate by a deadline that was never enforced, and tells us the field is
gone when it is not.
The column now says what is true. Rule 3 below is the one that governs it: the field comes out
when sdk_version traffic says nobody is still sending it, and the date goes back in this table
in the same change that schedules it.
Migrate to request_id regardless — it is the canonical name and the only one the SDKs send. The
Python and TypeScript SDKs accept trace_id only as a deprecated keyword argument and emit a
client-side warning when you use it.
Policy¶
- No silent breakage. A removed field yields a clear
422naming the replacement — never a silent failure or a "worked yesterday" surprise. - One-minor-version window. A field goes deprecated → removed across at least one full minor version.
- Observability first. We watch
sdk_versionin logs and do not remove a field while meaningful traffic still uses the old shape.
Adding a deprecation (for contributors)¶
- On the Pydantic request model, accept the old name via
Field(validation_alias=AliasChoices("new", "old"))+ amodel_validator(mode="before")that records the alias in adeprecationslist. - In the route, set
response.headers["X-Deprecation"]whenbody.deprecationsis non-empty. - Add a row to the table above with the removal version.