The compatibility contract
The compatibility contract
Every path under /v1/ is frozen by a short set of promises. They are
printed in full at the top of the permits reference, which is
generated from the same file our servers are tested against, so the two
cannot disagree. This page is the short version and the retirement rule.
In one paragraph
We may add fields, add enum values, add endpoints, return null for a
field documented as nullable, and add or remove entries in a list. We will
never remove or rename a field, change a field's type, change what an enum
value means, change or reuse an id, change an endpoint's URL, or remove an
enum value. So: ignore what you do not recognise, treat an unknown enum
value as "unknown" and still render the rest, store ids rather than labels,
and expect an id to disappear from a list when a district retires a status.
Versions and retirement
A change that would break a promise ships as /v2/permits/… beside v1.
Versions are per product. A retired version keeps working for at least 12
months after its successor ships; during that window its responses carry
Deprecation and Sunset headers and every key holder is emailed. Nothing
is retired today.
Ids
An id is a UUID that names one thing forever: a district, a status row, a permit type. Ids authorize nothing. When a district renames a status, the old row retires and a new one appears with a new id; that is a list entry leaving and another arriving, which the contract allows.