Terms of Service
Chronary captures an immutable audit trail of Terms of Service acceptance at signup and re-acceptance when the document changes. These endpoints let CLIs, SDKs, and the console read the current version and record re-acceptance without a build-time constant.
The authoritative source is the TOS_VERSIONS manifest in @chronary/shared, exported as CURRENT_TERMS_VERSION.
Get the current version
Section titled “Get the current version”GET /v1/auth/terms/currentUnauthenticated. Returns the latest manifest entry. Cacheable on the client for short windows — the underlying manifest changes infrequently and material version bumps are coordinated.
Example
Section titled “Example”curl https://api.chronary.ai/v1/auth/terms/currentconst res = await fetch('https://api.chronary.ai/v1/auth/terms/current');const current = await res.json();// { version: '2026-04-26', effective_at: '2026-04-26', url: '...', material: true }Response
Section titled “Response”{ "version": "2026-04-26", "effective_at": "2026-04-26", "url": "https://chronary.ai/terms/v/2026-04-26", "material": true}| Field | Type | Description |
|-------|------|-------------|
| version | string | Opaque identifier. Pass verbatim as tos_version on signup and re-acceptance. |
| effective_at | string | ISO date the version became effective. |
| url | string | Canonical URL of the archived document. Future versions archive to /terms/v/<version>. |
| material | boolean | When true, existing customers must re-accept to continue (the Chronary-Terms-Upgrade-Required response header is also set on authenticated traffic). |
Re-accept after a version bump
Section titled “Re-accept after a version bump”PATCH /v1/auth/termsAuthenticated via JWT (console session cookie or Bearer token — not an API key). Appends a new row to the tos_acceptances audit table (source = 'reaccept') with the client IP, user-agent, and document SHA-256, then updates the denormalized columns on the organization. Prior acceptance rows are preserved.
Request body
Section titled “Request body”| Field | Type | Required | Description |
|-------|------|----------|-------------|
| tos_version | string | yes | Must equal CURRENT_TERMS_VERSION. Sending a stale value returns 409 tos_version_stale. |
Example
Section titled “Example”curl -X PATCH https://api.chronary.ai/v1/auth/terms \ -H "Authorization: Bearer <console-jwt>" \ -H "Content-Type: application/json" \ -d '{ "tos_version": "2026-04-26" }'Response
Section titled “Response”{ "data": { "accepted_terms_version": "2026-04-26", "accepted_terms_at": "2026-04-24T02:30:00.000Z" }}Staleness indicators
Section titled “Staleness indicators”Chronary-Terms-Upgrade-Required response header
Section titled “Chronary-Terms-Upgrade-Required response header”Set on authenticated REST and MCP responses when:
CURRENT_TERMS_VERSIONis markedmaterial: true, and- The authenticated org’s
accepted_terms_versiondiffers from it.
The header value is the new version. The response body is not modified, so agents can continue operating; the console uses the header (and the accepted_terms_version field on GET /v1/auth/me) to surface a blocking re-acceptance modal.
409 tos_version_stale
Section titled “409 tos_version_stale”Returned by POST /v1/auth/signup, GET /v1/auth/oauth/:provider, POST /v1/agent/sign-up, and PATCH /v1/auth/terms whenever the submitted tos_version does not match CURRENT_TERMS_VERSION.
{ "error": { "type": "tos_version_stale", "message": "The submitted terms-of-service version is out of date", "current_version": "2026-04-26", "request_id": "req_..." }}Refresh the manifest via GET /v1/auth/terms/current, re-render your disclosure UI against the new version, and retry.