What the standard guarantees
The reference documents every endpoint. These pages document the rules all of them obey — which is the more useful half, because it lets you predict an endpoint you have not read yet: what its URL looks like, what a write returns, how its list is paged and filtered, what its failures look like, and what it does when the work outlives the call.
They are the platform's own API standard, the normative document its code is reviewed against, transcluded here at build time. Not a summary of it, and not a second copy: the same file, minus the sections that concern only the people implementing it — which is why the numbering below has gaps in it.
The transport is ordinary REST over JSON — no protobuf, no transcoding, nothing a curl
user cannot read. The semantics come from
Google's API Improvement Proposals, which is why an endpoint you
have never seen behaves the way you expect it to. Where this API departs from them it says
so, in the table of deviations below; their labels, D1 to D6, are how the rest of these
pages refer to them.
1. The one sentence
Every endpoint is one of five standard methods or a named custom method
on a resource that has a hierarchical name, requests and responses are
snake_case JSON, lists are paginated with page_size/page_token and
filtered with filter, and every failure is a google.rpc.Status body
with a canonical code.
3. Deliberate deviations from AIP
These are permanent and load-bearing. Everything not listed here follows the AIP as written; when in doubt, the AIP wins.
| # | AIP says | We do | Why |
|---|---|---|---|
| D1 | Collection ids and JSON fields are lowerCamelCase (AIP-122/140, proto3 JSON mapping) | snake_case everywhere — path segments, fields, query params, custom-method verbs | AIP-140 defines field names as lower_snake_case; camelCase is purely an artifact of proto3→JSON transcoding, which we do not do. Our models, our Mongo documents and our existing JSON are already snake_case. One spelling, end to end. |
| D2 | Resource names carry the full ancestry (accounts/a/projects/p/websites/w/cms_pages/c) | Names are rooted at the nearest globally-addressable ancestor: websites/{website}/cms_pages/{cms_page} | Every id is a Mongo ObjectId and therefore globally unique, so the extra ancestry adds no addressing power, only length. website.parent carries the link upward for anyone who needs it. |
| D3 | Fields that reference another resource hold its resource name (AIP-122) | References stay bare ids in <field>_id / <field>_ids fields, each documenting its resource type | 26 distinct reference fields across 33 models, all resolvable within a scope the URL already fixes. |
| D4 | Create returns 200 OK | Create returns 201 Created with a Location header | The transport is REST, not transcoded gRPC. 201 + Location is what REST clients and caches already understand. |
| D5 | Output-only fields sent on a write are silently ignored (AIP-203) | Ignored by default; a resource MAY declare a field IMMUTABLE instead and reject it with INVALID_ARGUMENT | Silent-ignore is the AIP rule and the default. Where the team has already decided a silent drop is a footgun (menu_item.sort_order), IMMUTABLE is the sanctioned escape hatch — it is explicit, not ad-hoc. |
| D6 | error.details entries are Any-typed with @type URLs | details entries are plain objects with a "type" string discriminator from a closed set (§13) | No type registry to publish or resolve. Same information, readable without tooling. |
23. AIP index
Adopted as written: 121 (resource-oriented design), 122 (names, except D2/D3), 126 (enums), 131–135 (standard methods, except D4), 136 (custom methods), 140 (field names, per D1), 142 (time), 143 (standardized codes), 148 (standard fields), 151 (operations), 154 (etags), 155 (request ids), 156 (singletons), 157 (partial responses, optional), 158 (pagination), 160 (filtering, subset per §8), 163 (validate-only), 180 (compatibility), 185 (versioning), 193 (errors, except D6), 203 (field behavior, except D5), 216 (states), 231/234 (batch methods).
Not adopted: everything proto/gRPC-specific (191–192 file layout, 213 common
components, google.protobuf wrappers), 127 (HTTP transcoding annotations),
and the Any-typed error details of 193 (see D6).