API versioning
The Driftstack API is currently at v1. This page covers how versioning works, what we consider a breaking change, and how deprecation timelines are communicated.
How versions are expressed
Every endpoint is prefixed with /v1/. The version
lives in the URL, not in a header, so callers always know
which contract they're hitting. Example:
POST https://api.driftstack.dev/v1/sessions
GET https://api.driftstack.dev/v1/profiles
POST https://api.driftstack.dev/v1/billing/crypto-checkout
A future v2 would live at /v2/ in parallel with
v1 — old clients keep working while you migrate.
Definition of a breaking change
Breaking changes increment the major version (v1 → v2). The following are breaking:
- Removing an endpoint.
- Removing a field from a response.
- Changing the type of a response field (e.g. string → number).
- Renaming a field.
- Adding a new required field to a request body.
- Changing the meaning of an existing status code.
- Tightening validation on an existing field (e.g. shrinking the max length, restricting the regex).
- Changing the URL path or HTTP method of an endpoint.
Non-breaking changes (no version bump)
- Adding a new endpoint.
- Adding a new field to a response.
- Adding a new optional field to a request body.
- Loosening validation (longer max length, broader regex).
- Adding a new value to an enum field whose schema is
documented as open-ended (e.g.
statusmay gain new states over time — clients should default-handle unknown values). - Adding a new event type to the webhook event stream.
- Performance improvements that don't change observable behaviour.
Build clients defensively against the "open enum" cases —
handle unknown status values gracefully rather
than crashing on them. The SDKs do this automatically; if you
handcraft a client, do the same.
Deprecation timeline
When we decide to deprecate something within v1 (rare — we'd usually wait for v2), the timeline is:
- Day 0: Deprecation announced in the
changelog and via a
Deprecationresponse header on the affected endpoint. The header includes a sunset date in RFC 5988 format. - Day 0 → 90: Endpoint continues to work unchanged. We email accounts that have called the endpoint in the last 30 days at the 60-day and 30-day marks.
- Day 90+: Endpoint returns a non-fatal
410 Gonewith a pointer to the replacement.
Major version transitions (v1 → v2) follow a longer schedule: minimum 12 months of parallel availability, with the same 60-day / 30-day email reminders.
Detecting the current version
The version is in the URL path — every endpoint is prefixed
with /v1/. If you handcraft a client, log the
base URL alongside your request id so you can diagnose
"is my SDK pinned to the right URL?" issues. The
X-Request-Id header is always set on the response;
our SDKs surface it on every typed error.
Beta endpoints
No customer-facing endpoints are in beta today — the surface
under /v1/ is stable per the breaking-change policy
above. If we introduce a beta path in the future we'll document
it explicitly on its own docs page and announce it in the
changelog before it ships.
What "v1" guarantees about behaviour
As long as you stay on v1, you get:
- The same URL paths.
- The same response shapes (additive fields only).
- The same status-code semantics.
- The same authentication scheme (Bearer API key or OAuth).
- The same idempotency semantics (DELETE is idempotent, POST creates new resources, PUT/PATCH are explicit replacements).
SDK version vs API version
The official SDKs (TypeScript,
Python,
Go) follow semver independently of
the API. SDK 0.x is the current pre-1.0 line —
surface is stable for the published methods but new resources
land in minor versions. When the SDK reaches 1.x
it will continue to target API /v1/; an API
/v2/ would mean an SDK 2.x in
lockstep.
Support
Versioning, deprecation, or migration questions: [email protected]. Subscribe to the changelog RSS for deprecation announcements.