Summary: 7Mind versions its HTTP APIs through two HTTP headers rather than URL prefixes: clients identify themselves and their build via user-agent, and may optionally request a specific response version via accept. The convention is declared once in api-contracts and is expected to be honoured by every client and server in the system. Sources: direct code inspection (contracts/shared/common.tsp in api-contracts); cross-references a Notion document linked from the contract Last updated: 2026-05-15


The two headers

Both headers are defined as the VersioningHeaders alias in contracts/shared/common.tsp.

user-agent (always sent)

Format: <APP>/<VERSION>+<BUILD NUMBER> (<META>...)

  • APP — short app name, e.g. 7sleep, 7mind
  • VERSION — semantic version of the running app, e.g. 1.2.3
  • BUILD NUMBER — monotonic build number, e.g. 32
  • META — optional additional metadata (see the linked Notion page for accepted forms)

Example: 7mind/4.12.0+8421 (ios; 17.4)

The server uses this to decide which behaviour to deliver when no explicit accept version is given. Clients must send it on every request.

accept (optional explicit version request)

Format: application/vnd.<APP>.api.<RESPONSE VERSION>+json

  • APP — the app name (matches the one in user-agent)
  • RESPONSE VERSION — the requested version label, e.g. v1, v2

Example: application/vnd.7mind.api.v2+json

When omitted, the server chooses a default based on the user-agent — so an old mobile build keeps receiving the response shape it expects without code changes on the client.

Why headers, not URL prefixes

The decision is recorded in Notion (linked from the contract). The short version: header-based versioning lets the same URL serve multiple response shapes, which makes rolling out a new version transparent for clients that do not opt in, and avoids the routing-table explosion of /v1/..., /v2/... URL trees.

What agents should know

  • When you add a new endpoint, do not invent a new URL prefix to signal a version. Either evolve the existing response shape backwards-compatibly, or declare a new response version and have the server branch on the accept header.
  • The user-agent is the canonical client identifier across elixir-backend log lines, analytics events, and feature gates. Do not synthesise it from other sources.
  • Clients that omit a valid user-agent should be assumed to be the latest version on the server side — the contract does not document a fallback behaviour, so treat missing values defensively.
  • The header convention is declared in api-contracts but is not enforced by the contract itself — it is enforced by client code and server middleware. Verify both sides when changing behaviour.

Where it lives

  • Declaration: contracts/shared/common.tsp (Shared.Common.Requests.VersioningHeaders) in api-contracts
  • Client-side application: 7mind-mobile-apps-monorepo and nuxt-website should build these headers on every outgoing request. Exact code paths TBD.
  • Server-side application: elixir-backend parses the headers in the public API layer. Exact module path TBD.