The five standard methods
There are five methods, and almost every one of the platform's endpoints is one of them on some resource. Learn them once and the reference stops being a list of endpoints and becomes a list of resources: five known shapes each.
Code
7. Standard methods
Five, and only five, have HTTP-shorthand status. Everything else is a custom method with a name.
| Method | HTTP | Success | Body in | Body out |
|---|---|---|---|---|
| List (AIP-132) | GET {collection} | 200 | — | list response (§8) |
| Get (AIP-131) | GET {name} | 200 | — | the resource |
| Create (AIP-133) | POST {collection} | 201 + Location | the resource | the created resource |
| Update (AIP-134) | PATCH {name} | 200 | partial resource | the updated resource |
| Delete (AIP-135) | DELETE {name} | 204 (hard) / 200 (soft) | — | — / the resource |
Non-negotiable consequences of that table:
- Mutations return the resource, not a receipt. The client that
just wrote something needs the server's view of it — including
server-generated fields,
update_timeand the newetag. PATCH, notPUT.PATCHcarries merge semantics: only the fields present in the body are written. That is what AIP-134 specifies.- Field-mask deletes. Merge semantics alone cannot clear a field: omitting
it means "leave it". A client that must clear one sends
?update_mask=with the field listed and the field absent (ornull) in the body.update_maskis a comma-separated list of top-level field paths. Whenupdate_maskis absent, every field present in the body is written and nothing else is touched. - Create id assignment. Ids are server-assigned. A client that needs to
choose one (imports, seeds, idempotent provisioning) passes
?id=and the server either honours it or failsALREADY_EXISTS. - Get on a missing resource is
NOT_FOUND, always. Including when the parent scope does not exist, and including when the caller may not see it — a tenant probing another tenant's website id getsNOT_FOUND, neverPERMISSION_DENIED, because the alternative confirms existence.
Optional, per-resource, when the cost is justified:
?validate_only=trueon Create/Update — run every check, write nothing, return the resource that would result. The admin's form-level validation is the use case.?allow_missing=trueon Update — upsert (AIP-134). Only where a caller genuinely cannot know whether the resource exists.
The CORS preflight has to admit these methods. PATCH is not a
CORS-"simple" method and neither If-Match (§14) nor Authorization is a
simple header, so a browser sends none of them unless
Access-Control-Allow-Methods / -Headers say it may — and when the preflight
refuses, the request never leaves the browser: no status, no server log,
nothing to read but a save that silently does nothing.
9. Singleton resources (AIP-156)
Some things exist at most once per parent and have no id of their own:
websites/{w}/custom_domain, users/{u}/profile.
- The name ends with the singular collection id.
- They support Get and Update only. No List, no Create, no Delete —
creation is implicit in the first Update, and removal is a field or a custom
method (
:disconnect), neverDELETEon the singleton. - Get on a singleton that has never been written returns the resource with
default values, not
NOT_FOUND, unless the resource documents otherwise. - A singleton carries no
id. §12'sidis the final segment ofname, and a singleton's name has none — publishing its storage id under that field would break the one invariantidhas. Everything else in §12 still applies: a stored singleton hascreate_time,update_timeand anetag, and a never-written one omits the timestamps because there is nothing to date.
Settings are not a singleton — they are a collection keyed by their dotted path:
Code
:batch_update is AIP-234: it takes a list of resources, and it is atomic
— all writes land or none do. Partial success is not a shape this API returns.
10. Custom methods (AIP-136)
When an operation is not one of the five, it is a custom method:
Code
- The separator is a colon, never a path segment.
…/menus/{m}/items/{i}:move, not…/items/{i}/move. - The verb is
snake_case(D1) and is a verb::move,:verify,:reindex,:batch_update,:undelete,:authenticate. - Custom methods are
POSTunless they are side-effect-free reads that cannot be expressed as a List filter, which areGET. - Request and response bodies are ordinary JSON objects. A custom method that mutates one resource SHOULD return that resource.