Methods and Status Codes
In v4 the method and the URL shape fully describe what an operation does and what it returns. A client, an SDK generator or an agent never has to read prose to know whether a call creates, replaces or merges, or which status code to expect.
The method table
Each URL shape allows a fixed set of methods, and each method returns a fixed success status.
| Method | Used on | Meaning | Success | Retry-safe |
|---|---|---|---|---|
| GET | any | Read. No body, no side effects. | 200 | yes (safe) |
| POST | collection | Create a resource with a server-assigned ID. | 201 + Location | no (no Idempotency-Key) |
| POST | association collection | Add an association, or replace it if it exists (upsert). | 201 created + Location, or 200 replaced | yes |
| PATCH | item, singleton | Change some fields (JSON Merge Patch). | 200 | yes |
| PUT | singleton, association item | Replace a resource whose identity the client knows. | 201 created + Location, or 200 replaced | yes |
| DELETE | item, association item | Delete. | 204 no body | yes |
The shared guidelines (METH-1, METH-2) allow more combinations. v4 narrows them, so there is exactly one way to do each thing:
Code
Code
There is one way to update a thing, and no risk of a PUT that silently clears
fields the client did not send.
Code
No HEAD or OPTIONS in the spec. The gateway answers them (CORS, for
example).
Bodies
Request and response bodies are application/json. Errors are
application/problem+json (see errors).
GET and DELETE have no request body. POST, PATCH and PUT always
have one. Send {} when all fields are optional.
A create's body holds the new resource and nothing else. What the create also
does to other resources is a query parameter: include[]=apiKey issues a new
consumer's first key, and previousKeyGracePeriodSeconds on a roll says how
long the keys it replaces keep working.
Code
Code
The same representation as GET, so a client never needs a follow-up read.
Code
Code
Code
Code
DELETE returns 204 with no body.
Code
The body is the new key. The grace period is about the keys it replaces.
Code
PATCH is JSON Merge Patch
PATCH bodies follow RFC 7396 (the
"tri-state" of DATA-2):
unchanged
cleared (set to its empty value)
set
merged recursively with the same rules
replaced as a whole
Code
The pool before and after (abridged):
Code
This renames the pool, removes all of its own budget rules, and keeps its policy template.
The consequences for the spec: Update*Request schemas have no required
properties (v4-request-schemas checks this), and fields that can be cleared
are nullable. Properties that cannot
change after creation (an app's poolId, a provider assignment's providerId) are simply not in
the update schema.
Code
Code
Associations are added or set
An association has no ID
of its own. It is identified by its parent and a key the client knows, such as a
person's userId. Either way of writing it creates it or replaces it, so sending
the same request twice leaves the same state. Each association uses exactly one of
the two, or is read-only (a person in a user app):
A person joins a pool or a project, and a consumer is linked to an app.
The association is added with a POST to the collection, with the key in the
body. Sending it again changes the existing one (a member's role) or nothing (a
link that already exists).
/v4/buckets/{bucketId}/ai/pools/{poolId}/membersPOST/v4/buckets/{bucketId}/ai/apps/{appId}/consumersA value a person has exactly one of, which always exists, is a singleton under
the association, set with a PUT and the complete value in the body: their
budget in a user app.
/v4/buckets/{bucketId}/ai/user-apps/{userAppId}/users/{userId}/budgetCode
Code
201Created with Location, its URL
(…/members/{userId}, …/users/{userId}/budget).
200OK. It is replaced.
Both operations are named upsert-{resource} and take an
Upsert{Resource}Request with the complete writable representation. An
association that is written with a POST has no PUT, and the other way round.
PUT is otherwise left for singletons, which have no collection to POST to,
such as a person's budget, or the gateway's budget rules, where the body is the
list itself.
DELETE
No body.
Idempotent behavior. Clients, SDKs and Terraform treat 404 on DELETE as
success.
The detail names the dependents (a pool that still has apps). A delete never
removes them silently.
A resource that exists but cannot be changed or deleted, such as one of Zuplo's
built-in AI providers, answers PATCH and DELETE with 409,
whose detail says it is read-only. It is never 405: the method is allowed on
the path, and only this resource refuses it.
If the delete does cascade, the operation description says what goes with it:
Code
Code
Changes that take effect asynchronously
Some writes are stored immediately but reach the data plane a few seconds later. For example, a new provider assignment is usable once the AI Gateway picks up its configuration.
The response is returned once the change is stored and validated.
For example: "Read the newest deployment until it has succeeded. That does
not guarantee every edge serves the change yet."
When a change needs a deployment, the deployment reports it, so a client can wait
for it. An AI Gateway is its project's production environment, and a provider
assignment change creates a deployment of it: a client reads the newest one
(GET/v4/projects/{projectId}/deployments with its
environmentId) until it has succeeded. The environment's status is null for
an AI Gateway, because nothing reliably says that every edge serves the newest
configuration: a succeeded deployment has rolled out, but an edge may serve the
previous version for a while.
Operations that take longer than a request should wait use the shared create-then-poll pattern (METH-3): the operation is a resource of its own. A deployment is the first in v4.
POST creates an operation resource.
Until its status is succeeded or failed.
pending / running / succeeded / failed / cancelled
Code
Code
The 201 returns it pending. Read it until its status is succeeded or
failed.
Code
A verb to learn, and nothing to read afterwards. Redeploying is creating a deployment.
Methods per URL shape, success codes, request bodies, and no required properties on PATCH.
Create-then-poll for long-running operations (METH-3).