Versioning & deprecation
Every endpoint lives under /api/v1. This page is the whole policy: what /api/v1 promises never to do, what counts as a breaking change, how one operation is deprecated without breaking anyone still calling it, and the changelog of every contract-level correction we've ever made.
/api/v1 stability
Inside /api/v1 we only ever make additive changes:
- A new endpoint.
- A new optional request field.
- A new response field.
- A new, distinct error
codefor a genuinely new failure condition.
We never, inside /api/v1:
- Remove a field from a response.
- Narrow a field's type (e.g. a nullable field becoming non-nullable would be fine; the reverse — or widening
stringtostring | number— is not). - Add a required request field.
- Change the HTTP status code an operation returns for a given outcome.
- Change which
error.codean existing failure condition returns.
If your integration only ever reads fields it knows about and tolerates new ones showing up, it will keep working on /api/v1 indefinitely — that's the point of the rule.
What counts as breaking
Anything in the "never" list above is breaking, and it never lands inside /api/v1. A breaking change instead means /api/v2, announced at least 180 days before /api/v1 begins its own deprecation. Both versions run side by side for the whole notice period — nothing is ever pulled out from under an integrator without warning.
Deprecating an operation
A single operation can be deprecated inside /api/v1 — still fully functional, but marked for eventual removal (typically because /api/v2 or a newer operation replaces it). For its entire remaining life it carries three headers and "deprecated": true in the OpenAPI document:
HTTP/1.1 200 OK
Deprecation: @1735689600
Sunset: Wed, 01 Jul 2026 00:00:00 GMT
Link: <https://developers.institflow.com/en/guides/versioning#deprecations>; rel="deprecation"Deprecation— when the deprecation started, as@followed by Unix seconds (RFC 9745). The example above,@1735689600, is2025-01-01T00:00:00Z.Sunset— the earliest date the operation may be removed, as an IMF-fixdate (RFC 8594), always at least 180 days afterDeprecation.Link— points back to this page's deprecations table below, so a client that only logs headers still has a way to find out why.
replacedBy, when there is a direct successor, and a short human-readable note, appear in the table below and in the generated API reference for that operation — never in the headers themselves, which stay small and machine-parseable.
Rate-limit headers
Every response — deprecated or not, successful or not — carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset. Every 429 RATE_LIMITED response — from the per-IP/per-user limiter that guards every route, or from a secret API key's own per-key budget — additionally carries Retry-After, in seconds, so a well-behaved client always knows exactly how long to wait without guessing from RateLimit-Reset alone.
Currently deprecated operations
None. No operation in the current API is deprecated.
Changelog
Contract-level corrections and deprecations, newest first.
| Date | Change |
|---|---|
| 2026-09-07 | Documentation correction, not a breaking change: nextCursor was published in the OpenAPI document as string[]; the wire format was always string | null. The spec now matches what the API has always sent — no client that reads nextCursor as a nullable string was ever wrong. |