Versioning
The promise
/api/v1/*is stable for ≥18 months from v1.0 ship date.- Breaking changes go in a new major version (
/api/v2/*) only. We don't break v1 mid-flight. - Non-breaking changes (new fields, new optional params, new endpoints) ship in
/api/v1/*at any time without notice. - When
/api/v2/*ships,/api/v1/*continues serving for ≥6 months alongside it.
Sunset semantics
When we deprecate /api/v1/*:
-
60 days before sunset: the v1 → v2 migration guide is published on this docs site.
-
30 days before sunset: every
/api/v1/*response carriesDeprecation: true,Sunset: <date>, andLink: <v2-path>; rel="successor-version"per RFC 8594 —/api/v1/*still serves normally; the headers are advance notice. -
Sync-tier customers: personal Slack heads-up 30+ days before sunset.
-
On sunset day:
/api/v1/*auto-migrates.- A cluster-first keeper route returns
308 Permanent Redirectto its/api/v2/*equivalent. 308 preserves the method and the query string, so a conforming client follows the redirect and keeps working without a code change. - A demoted surface (the standalone
masters/*andbandcamp/*top-level — in v2 release/master and Bandcamp data are dimensions of the artist dossier, not first-class resources) returns410 Gonewith aLinkto its successor and a JSON body explaining where the data moved.
The cutover is feature-flagged and announced; until it's flipped,
/api/v1/*serves unchanged. (This reverses an earlier draft of this page that promised no auto-redirect — for the v2 cut we chose method-preserving 308s so existing integrations migrate without breaking.) - A cluster-first keeper route returns
What counts as a breaking change
| Change | Major bump? | |---|---| | Add a new endpoint | No | | Add a new optional query/body param | No | | Add a new field to a response | No | | Remove a field from a response | YES | | Rename a field | YES | | Change a field's type (e.g. string → number) | YES | | Tighten a validation rule (rejects what was previously accepted) | YES | | Change error code mapping (e.g. 400 → 422 for the same input) | YES | | Change rate-limit values | No (but we'll announce) | | Add a new error code | No | | Change authentication scheme | YES |
What's reserved for v2
Speculative — not actually planned:
- GraphQL surface (alongside REST, not replacing it)
- Bulk dumps (currently explicitly out of scope per TOS)
- Webhooks for usage events (customer-initiated push notifications)
If you have feedback on v2 direction, the public issue tracker on github.com/hosaka-fm/crate is the right place.
What we DON'T promise
- 99.99% uptime SLA (v1.0). We publish actuals via
/api/v1/health+ aim for ≥99.5%. - Real-time data freshness beyond the existing
freshness.ridden_lag_s/freshness.mirror_lag_ssignals (typically under 2 minutes, but bursty under producer load). - Specific p50/p95/p99 response-time SLOs. We publish actuals; if you need contractual SLAs, that's a Sync-tier conversation.
- Backwards compatibility for clients of the public consumer surface (the
/cratepage) that aren't authenticated API customers. - SDK clients. We've deliberately not pre-built language SDKs; build against the OpenAPI spec. If a customer requests one, we'll ship it.
Why this matters
API customers integrate crate into paid client deliverables (sync agencies), production music apps (developers), and internal tooling (small teams). A surprise breaking change kills trust. The versioning contract on this page is what makes crate a trust-worthy substrate to build on — versioned, opinionated, sunset-honored.
Built right, an API is a quiet trust contract. This page is the trust contract.