info.version is a publication date, not a release you can request. There is no version
header, no Accept parameter and no query string that selects one — the path segment is the
whole mechanism, so two integrations pointed at /v1 are always looking at the same
contract.
What changes without notice
These are additive, they ship whenever they are ready, and each one is recorded in the changelog:- a new operation, or a new optional query parameter on an existing one;
- a new optional member on a request body;
- a new member on a response body;
- a new member on an existing enum — a new
code, a newstatus, a newevent_type; - a new webhook event type, which reaches you only if you subscribe to it.
code as its HTTP status class,
and treat an unrecognised enum value as “something newer than my client” rather than as
corrupt data. Nothing in this document is additionalProperties: true, so the reverse is not
true — a field you invent is still a 400.
Read that literally when you generate a validator. Most response objects here are published
closed (additionalProperties: false), and a response object is closed as published: a
new member arrives in the schema in the same release it arrives on the wire. So regenerate
against the current document rather than pinning an old copy, and do not reject an
unrecognised member at runtime — the closedness describes what we had published when you
generated, not a promise that nothing will ever be added.
What does not change without notice
Removing an operation, a member or an enum value; renaming any of them; narrowing a type; tightening a validation rule; or changing what a status code means. None of that happens inside/v1.
This is the promise from the first production key onward. The corrections dated 2026-09-07
and 2026-09-30 predate that and are named in the changelog; nothing has
changed under an integration since.
A change of that kind gets a new major — /v2 — served alongside /v1 for a stated
overlap period, so nothing you have built stops working on the day it appears. The length of
that overlap is a commitment we have not published yet; it will be stated here before the
first one exists, and no major has ever been retired.
Deprecation, when it happens
Nothing in this contract is deprecated today, and nothing carries a retirement date. When something is:- the operation, parameter or member is marked
deprecated: truein the OpenAPI document, so a generated client warns at compile time rather than at three in the morning; - responses from it carry a
Sunsetheader giving the date after which it stops answering, in HTTP-date form; - the changelog carries the entry, naming the replacement.
Sunset date. It does not start refusing, and it
does not start returning less.
How you hear about a change
The changelog is the record, and it is the only one — there is no email list, no RSS feed and nocontract.changed webhook today. If you want to watch for changes
mechanically, the OpenAPI document is served at a stable URL and its info.version moves
whenever it does.
Using this document
The specification and these guides are published so you can build an integration against Maat Stays. What your integration may do with the platform, and with anything it receives from it, is set by the Developer Terms your workspace signed before its first key was issued. They are not published at a public URL today, which is why this document carries notermsOfService: pointing at one that does not exist would be worse than pointing at
nothing. The copy that binds you is the one your workspace signed, in your own Maat account.