Platform
The resource pages tell you what each operation takes and returns. These pages tell you how the API behaves around those operations — the rules that are the same whether you are reading a canvas or queuing a video.
Every one of them is generated from, or verified against, the same OpenAPI document the Gavana browser, CLI, and MCP adapter are built on.
The six mechanisms
- Authentication — Agent Access token format, the eight scopes and how they depend on each other, token lifetime, and what a scope denial looks like.
- Errors and X-Request-ID — the single error envelope, all seventeen error codes with their HTTP status, which are retryable, and the correlation id to give support.
- Idempotency — why keys must be caller-stable, exactly what a replay returns, and how the same key with different inputs is rejected.
- Revisions and baseRevision — optimistic concurrency on the canvas graph, the shape of a
409conflict, and the dry run that costs nothing. - Pagination — cursor pages, the per-endpoint limit ceilings, and what happens when the underlying list changes mid-walk.
- Webhooks — the two signed terminal callbacks, verification code you can paste, and the exact retry schedule.
The three invariants underneath them
Almost every rule on these pages is one of three ideas applied to a different resource.
Read before you write. The canvas graph is a document with a revision. You
cannot safely change it without having just read it — baseRevision is how the
server checks that you did. The same instinct applies to discovery: read
GET /models before naming a model, read GET /recipes/{recipeId} before
binding Recipe inputs, read GET /actions/{actionKey} before sending Action
parameters. Guessing an identifier is the most common cause of a 404 not_found
that looks like a permissions problem.
A retry must be indistinguishable from the first attempt. Every mutating
operation takes an idempotencyKey. The key is what makes a network timeout
recoverable — you resend the identical request and either the original work is
replayed or the original result is returned. It only works if the key is derived
from the intent, not generated fresh on each attempt.
Paid work is explicit and never automatic. Image generation, image edits,
image variations, video generation, and Recipe Runs can spend provider credit.
Nothing in the API queues that work as a side effect of a read, a fork, or a
validation. When an agent is acting on someone’s behalf, get approval in the
current turn before the first paid call, and never auto-retry a paid request
after a failure — inspect failure.retryable, surface it, and ask again.
Deterministic Image Actions are the exception that
proves the rule: each one reports chargedCost: 0 and spends no AI-generation
credit.
Conventions used across the whole API
| Convention | Detail |
|---|---|
| Base URL | https://app.gavana.ai/api/canvas-agent/v1 |
| Content type | application/json for every request body except a raster upload to POST /assets |
| Handles | Stable, prefixed, opaque: canvas:, node:, connection:, asset:, element:, element-collection:, recipe:, action:, model:, run:, job:, webhook:, event: |
| Owner-qualified handles | Shared canvases and assets carry the owner: canvas:<ownerUid>:<id> and asset:<ownerUid>:<id>. Pass ownerUid as a query parameter when you only have the plain id. |
| Correlation | Every response carries X-Request-ID |
| Caching | Error responses are sent with Cache-Control: no-store |
| Surface hint | The first-party clients send X-Gavana-Agent-Surface: cli, mcp, or api. It is optional, affects only provenance and analytics attribution, and any unrecognised value is treated as api. |
Do not decode, construct, or pattern-match the inside of a handle, a cursor, or a revision. They are server-owned strings. The prefix is the only part of a handle you should ever branch on.
Where to go next
If you have not made a call yet, start with a quickstart. If you have, the recipes put these mechanisms together into complete tasks.