API Versioning Policy
GoSmarter versions its API per endpoint, not as a whole. Most endpoints never need to change; when one does need a breaking change, only that endpoint gets a new version — everything else keeps working exactly as it does today.
There is no concrete v2 endpoint yet. This page documents the policy and mechanism ahead of the first real breaking change, so that when one is needed it follows an established, low-friction path instead of becoming an ad hoc incident.
How versioning works
- Every endpoint that has never had a breaking change is implicitly v1 — its URL is unversioned (e.g.
/api/company/{companyId}/orders-slim). - A breaking change to a specific endpoint ships as a new route for that endpoint only, prefixed
v2/(e.g./api/v2/company/{companyId}/orders-slim). The v1 route keeps working, unchanged, alongside it. - There is no whole-API version switch — different endpoints can be at different version generations independently. Check each endpoint's own page in the API Reference for its current version.
What counts as a breaking change
This table is the single source of truth for classifying a change. An automated CI job checks it on pull requests that touch the API (pull requests from forks are skipped). The job compares the OpenAPI document the API serves on the pull request against the one served on the current tip of the branch it targets, using GitHub's merge result of the pull request, and flags the breaking changes that are visible in the OpenAPI contract (removed or renamed fields, type changes, new required inputs, removed routes). Changes that cannot be seen in the contract, such as status-code semantics, tighter authorization or pagination behaviour, still need reviewer judgement. New v2/ routes are new paths, so they never trip it. A new required response field is reported too, but the check cannot tell whether the field has a safe default: if it genuinely does, say so in the pull request description for the reviewer to accept. There is no automatic suppression yet; one will be designed before the check becomes blocking. During rollout the check reports findings as warnings only; it will become blocking once false positives have been ruled out.
| Change | Breaking? |
|---|---|
| Add optional response field / request field / query param | No |
| Add a new endpoint | No |
| Add a member to an enum, when the field is documented as open-ended | No |
| Remove or rename a response/request field | Yes |
| Change a field's type or semantic meaning | Yes |
| Change pagination shape, response envelope, or error format | Yes |
| Make an optional request field required | Yes |
| Add a new required response field with no safe default | Yes |
| Change status code semantics | Yes |
| Tighten authorization on an existing route | Yes |
| Add an enum member to a field with no open-ended contract | Yes (default assumption) |
Any change marked "Yes" gets a new v2/ route rather than being applied to the existing endpoint. This applies to stable endpoints; Preview endpoints are covered in the next section.
Preview APIs
Some endpoints are released as Preview so you can try new capabilities early and tell us what works for you. A Preview endpoint is fully functional and supported, but its contract is not final yet.
- How to recognise one. Preview endpoints are listed under Preview in the API Reference, their summary ends in "(Preview)", and their description starts with a Preview note. In the OpenAPI document they carry the
Previewtag and thex-stability-level: betaextension, so tooling can detect them too. - What can change. Until it is announced as stable, a Preview endpoint may change in ways this policy otherwise treats as breaking, or be removed, without a new
v2/route and without the deprecation notice period above. We avoid unnecessary churn, and every change to a Preview endpoint is listed in the API Changelog under Preview. - SDKs and generated clients. Preview endpoints are left out of GoSmarter SDKs, client kits and code samples unless you opt in to Preview endpoints, so a stable integration does not pick one up by accident. If you generate your own client from the OpenAPI document, filter on
x-stability-levelto do the same. - Graduation. When a Preview endpoint is ready, we announce its graduation to stable in the API Changelog. From that announcement on, the endpoint is a frozen v1 route like any other: later breaking changes need a new
v2/route and follow the deprecation notice period. - No downgrades. A stable endpoint never becomes Preview. If a stable endpoint needs a reworked contract, the new contract ships as a
v2/route (which may itself start as Preview) and the stable route follows the deprecation process.
The automated check described above skips Preview endpoints, still checks every stable endpoint as before, and reports any attempt to mark an existing stable endpoint as Preview.
Deprecation notice period
Once a v2 route ships and the corresponding v1 route is scheduled for retirement:
- Minimum 90 days' notice before a v(n-1) route is retired.
- Minimum 180 days' notice for high-traffic or high-integration-cost endpoints.
- The deprecated route remains fully supported — not just reachable — for the entire notice window. It receives the same operational care as any current endpoint until the day it is retired.
Security exception
The only exception to the notice period above is a change required for security or compliance reasons (for example, closing a vulnerability or complying with a new regulatory requirement). In that case GoSmarter may retire or change an endpoint faster than the standard window, with as much notice as the situation safely allows.
How you'll know a route is deprecated
Deprecated routes carry machine-readable signals on every response, in addition to being called out in the API Changelog:
| Header | Meaning |
|---|---|
Deprecation: true | This route is deprecated and has a replacement. |
Sunset | The date (RFC 8594 / RFC 1123 format) after which the route will stop working. |
Link: <...>; rel="deprecation" | A link to that route's migration guide. |
The same information is in the OpenAPI document: a deprecated operation has deprecated: true and an x-sunset extension holding the sunset date (YYYY-MM-DD; the route stops being guaranteed from the start of that UTC day, matching the Sunset header), so tooling that reads the spec, such as oasdiff, can detect a pending retirement without calling the API.
If you're building an integration against GoSmarter, check for the Deprecation response header rather than relying on reading the changelog manually — this lets your own monitoring flag a pending migration automatically.
Where to find migration guidance
Every breaking change ships with a dedicated migration guide (before/after request and response shapes, a working curl example, and the sunset date) linked from both the API Changelog and the deprecated route's own reference page.
Related
- API Changelog — dated log of every
Added/Changed/Deprecated/Removedchange to the public API, with Preview endpoint changes listed separately underPreview - ADR-1426: API Versioning Strategy — the internal decision record this policy implements

