Skip to main content
The endpoint pages describe one request at a time. This cookbook shows how those requests fit together. It uses a human PAT because account discovery and writes are human-only. A Service Account can call only the operations listed in Feature availability.

Prepare a safe shell

Load values through your runtime or secret storage. Do not paste a real token into a shared terminal log.
Every control-plane request uses the bearer header:
Requests inside one account also use:
The account header selects context. It cannot grant access that the PAT does not already have.

Discover account and project context

List accounts before accepting an account ID from a user or configuration file:
Then list active projects in the selected account:
Keep account and project IDs as separate values. A project ID never replaces x-account-id.

Create a project without duplicate writes

Generate one UUID for the intended create operation and keep it for retries of that same operation.
A success response contains data.project_id. Retrying the same request with the same key returns the same result. Reusing the key with a different name or description returns idempotency_key_reused_with_different_params. Project updates replace the editable values. Send every value you want to preserve:

Read record metadata before plaintext

Start with metadata. This request does not decrypt record fields:
Use the returned record ID only after checking its name, format, tags and project. To request selected encrypted sections:
The REST result is still encrypted material. Use the SDK, CLI or local MCP server when you need plaintext; those clients perform decryption locally. Do not send a vault passphrase to a REST endpoint.

Change metadata without changing the value

Only supplied metadata fields change:
This does not rotate the data key or create a value version. For value changes, rotation, rollback and sharing, prefer the SDK. Those workflows must unwrap or re-seal record keys in the trusted client.

Review record history and audit

Read value-version metadata:
Read the record’s audit feed:
For a project-wide review, use /v1/audit/record-anomalies, /record-activity, /record-alerts and /record-access with scopeType=project, scopeId=$PROJECT_ID and the account header. Audit responses describe events and actors; they do not contain plaintext records.

Create a Gateway control plane

List providers first, then create or select a provider credential. Provider secret values are write-only. For safer shell handling, use the SDK, CLI --api-key-env, or MCP apiKeyEnv instead of placing a key in raw cURL JSON. Create a gateway after you have the provider and credential IDs:
The control-plane bearer configures . Applications do not use it for model traffic; they use a separate gateway token against the data-plane URL returned by the gateway configuration.

Create and replace a gateway token safely

Create a short-lived token with only the scopes and models the workload needs:
The plaintext token appears once in data.plaintext. Store and deploy it before revoking the old token. Then revoke the old token:
Revocation stops authentication but keeps metadata for review. Deleting the token row is a separate action.

Diagnose a Gateway without reading bodies

Start with project metrics and gateway log metadata:
Use the key-access feed to distinguish provider-key denials from provider failures. Read a log detail only when request or response bodies are necessary and the caller has usage:read-bodies. Never copy sensitive bodies into general logs or support tickets.

Configure OpenTelemetry without reading secrets

Read the safe export state, then update only the intended fields:
Stored header values are write-only. A later GET confirms the endpoint and switches but never returns the secret header values.

Work with Service Accounts without exposing lifecycle

The public API can list safe Service Account metadata and let an authorized human grant an encrypted record key. It cannot create, pause, provision, rotate, revoke or delete a Service Account credential.
Do not hand-build wrappedDek for /service-accounts/{id}/grants. Use shareRecordWithServiceAccount(), airctrl record share-sa, or share_record_service_account; each uses the shared crypto implementation to prepare the correct wrapper locally.

Handle failures without broadening access

Use --fail-with-body so cURL returns a non-zero status while preserving the error envelope.
  1. Keep requestId.
  2. Read error.code and error.message.
  3. Fix 400 input errors locally.
  4. Do not retry 403 with other IDs or wider scopes.
  5. Refresh resource state after 409.
  6. Retry only 429, 500 and 503, with a short bounded backoff.
See the API error matrix for failures associated with every public operation.