What we promise and how we deprecate
Root Herald's wire protocol is versioned, signed, and tier-bound. Here is exactly what we won't break, when we will deprecate something, and how to read the signed manifest that proves the contract.
Versioning model
The API base path is /api/v1/. Within v1, we follow a strict additive policy:
- New fields in responses: allowed, may ship at any time.
- New endpoints: allowed, may ship at any time.
- New optional request fields: allowed.
- New required request fields: never shipped inside v1. Always v2.
- Removing or renaming response fields: never inside v1.
- Changing the meaning of an existing field: never inside v1.
The signed manifest
We publish a signed protocol manifest at /.well-known/rootherald-protocol-manifest. It is a compact JWT (served as application/jwt), signed by the same publishing key as attestation tokens — verify it against our published JWKS at /.well-known/jwks.json. There is no separate detached signature; the JWS is the signature.
The manifest does not enumerate endpoints or fields. Its job is to pin the wire-protocol version and a cryptographic hash of the live OpenAPI document so clients can detect server-side schema drift at startup without re-downloading the full spec. Decoded, the JWT payload looks like this:
{
"iss": "https://rootherald.io",
"sub": "protocol-manifest",
"iat": 1747440000,
"wire_version": "1.0",
"openapi_sha256": "9f2c…<64 hex chars>…e1a0",
"compatibility_floor": "1.0",
"deprecation_window_days": 90
}The machine-authoritative contract is the OpenAPI document itself, served at /api/v1/openapi.json — that is what openapi_sha256 hashes, and it is the source of truth for every endpoint, request, and response field. For the error model, see the error-codes page: errors are stable string identifiers, not numeric codes.
Deprecation notice & windows
Every wire-protocol deprecation gives you a 90-day window (measured from announcement to removal) regardless of tier — this is the deprecation_window_days value published in the signed manifest. Higher tiers just add notification channels:
| Tier | Deprecation window | Notification channel |
|---|---|---|
| Free | 90 days | Dashboard banner · email · blog |
| Pro | 90 days | Dashboard banner · email · blog |
| Business | 90 days | All of the above + shared Slack ping |
| Enterprise | 90 days | All of the above + dedicated CSM walkthrough |
Headers that signal deprecation
When you hit a deprecated endpoint or pass a deprecated field, we add the standardDeprecation and Sunset response headers (RFC 8594, RFC 9745):
HTTP/1.1 200 OK
Deprecation: Tue, 17 Nov 2026 00:00:00 GMT
Sunset: Mon, 15 Feb 2027 00:00:00 GMT
Link: <https://rootherald.io/changelog/2026-11-deprecation>; rel="deprecation"
Content-Type: application/json
…Wire these into your observability stack. SDKs emit a one-time warning to stderron first encounter; we don't spam, but we do tell you.
This isn't a promise that the platform never changes: it's a promise about how and when. New features ship regularly; what they don't do is silently change existing behavior or remove fields you depend on.