Skip to Content

Actions

Discover and run deterministic, credit-free image transformations.

Base URL: https://app.gavana.ai/api/canvas-agent/v1 · Authentication: HTTP bearer, token format cba_<token-id>.<secret>

Operations

OperationPurposeScopes
GET /actionsList deterministic Image Actionscanvas:read
GET /actions/{actionKey}Read one Image Action schemacanvas:read
POST /actions/{actionKey}/runsRun a deterministic Image Actioncanvas:read, canvas:write, asset:read

GET /actions

List deterministic Image Actions

Returns typed schemas for the eight deterministic, credit-free raster transformations available in the browser, CLI, API, and MCP adapter.

  • Operation id: listImageActions
  • Scopes: Requires canvas:read.
  • CLI equivalent: gavana action list

Parameters

ParameterInTypeRequiredNotes
qquerystringNoFree-text Action slug, title, or summary search. max length 240.
limitqueryintegerNoMaximum number of items in this page. min 1, max 100.
cursorquerystringNoOpaque continuation cursor from page.nextCursor. Reuse it with the same list filters. max length 8192.

Responses

StatusPayloadMeaning
200objectDeterministic Image Actions with typed schemas and pagination.
defaultErrorResponseA stable machine-readable error. The response always includes X-Request-ID.

200 response body

FieldTypeRequiredNotes
actionsarray of ImageActionYes—
actions[].idstringYesPattern ^action:.
actions[].slugstringYesOne of resize, crop, change-aspect-ratio, side-by-side-composite, add-text-to-image, overlay-image, color-grade, rotate.
actions[].version“1.0.0”Yes—
actions[].titlestringYesmin length 1.
actions[].summarystringYesmin length 1.
actions[].estimatedSecondsintegerYesmin 1.
actions[].inputsarray of ImageActionInputYesmin items 1, max items 2.
actions[].inputs[].idstringYesPattern ^[A-Za-z][A-Za-z0-9_-]{0,79}$.
actions[].inputs[].titlestringYes—
actions[].inputs[].descriptionstringYes—
actions[].outputImageActionOutputYes—
actions[].output.titlestringYes—
actions[].output.descriptionstringYes—
actions[].parametersarray of ImageActionParameterYes—
actions[].parameters[].idstringYesPattern ^[A-Za-z][A-Za-z0-9_-]{0,79}$.
actions[].parameters[].titlestringYes—
actions[].parameters[].descriptionstringNo—
actions[].parameters[].typestringYesOne of number, select, text, color.
actions[].parameters[].requiredbooleanYes—
actions[].parameters[].integerbooleanNo—
actions[].parameters[].minnumberNo—
actions[].parameters[].maxnumberNo—
actions[].parameters[].stepnumberNo—
actions[].parameters[].maxLengthintegerNomin 1.
actions[].parameters[].optionsarray of ImageActionParameterOptionNo—
actions[].parameters[].options[].valuestring | numberYes—
actions[].parameters[].options[].labelstringYes—
pageCursorPageYes—
page.limitintegerYesmin 1, max 200.
page.hasMorebooleanYes—
page.nextCursorstring | nullYesmax length 8192.

Example

curl "https://app.gavana.ai/api/canvas-agent/v1/actions" \ -H "Authorization: Bearer $GAVANA_AGENT_TOKEN"

GET /actions/{actionKey}

Read one Image Action schema

Returns the exact ordered image inputs, typed parameters, defaults, limits, output contract, and cost behavior for one Action.

  • Operation id: getImageAction
  • Scopes: Requires canvas:read.
  • CLI equivalent: gavana action get

Parameters

ParameterInTypeRequiredNotes
actionKeypathstringYesAn Action slug or action:<slug> handle returned by GET /actions. Pattern ^(?:action:)?(?:resize|crop|change-aspect-ratio|side-by-side-composite|add-text-to-image|overlay-image|color-grade|rotate)$.

Responses

StatusPayloadMeaning
200objectOne deterministic Image Action with its typed input and parameter schema.
defaultErrorResponseA stable machine-readable error. The response always includes X-Request-ID.

200 response body

FieldTypeRequiredNotes
actionImageActionYes—
action.idstringYesPattern ^action:.
action.slugstringYesOne of resize, crop, change-aspect-ratio, side-by-side-composite, add-text-to-image, overlay-image, color-grade, rotate.
action.version“1.0.0”Yes—
action.titlestringYesmin length 1.
action.summarystringYesmin length 1.
action.estimatedSecondsintegerYesmin 1.
action.inputsarray of ImageActionInputYesmin items 1, max items 2.
action.inputs[].idstringYesPattern ^[A-Za-z][A-Za-z0-9_-]{0,79}$.
action.inputs[].titlestringYes—
action.inputs[].descriptionstringYes—
action.outputImageActionOutputYes—
action.output.titlestringYes—
action.output.descriptionstringYes—
action.parametersarray of ImageActionParameterYes—
action.parameters[].idstringYesPattern ^[A-Za-z][A-Za-z0-9_-]{0,79}$.
action.parameters[].titlestringYes—
action.parameters[].descriptionstringNo—
action.parameters[].typestringYesOne of number, select, text, color.
action.parameters[].requiredbooleanYes—
action.parameters[].integerbooleanNo—
action.parameters[].minnumberNo—
action.parameters[].maxnumberNo—
action.parameters[].stepnumberNo—
action.parameters[].maxLengthintegerNomin 1.
action.parameters[].optionsarray of ImageActionParameterOptionNo—
action.parameters[].options[].valuestring | numberYes—
action.parameters[].options[].labelstringYes—

Example

curl "https://app.gavana.ai/api/canvas-agent/v1/actions/action:resize" \ -H "Authorization: Bearer $GAVANA_AGENT_TOKEN"

POST /actions/{actionKey}/runs

Run a deterministic Image Action

Queues a credit-free raster transform against one or two durable node or asset handles. The result is stored as a durable asset and materialized in the selected target image node.

  • Operation id: startImageAction
  • Scopes: Requires canvas:read + canvas:write + asset:read.
  • CLI equivalent: gavana action run

Parameters

ParameterInTypeRequiredNotes
actionKeypathstringYesAn Action slug or action:<slug> handle returned by GET /actions. Pattern ^(?:action:)?(?:resize|crop|change-aspect-ratio|side-by-side-composite|add-text-to-image|overlay-image|color-grade|rotate)$.

Request body (application/json, required)

FieldTypeRequiredNotes
canvasIdstringYesA plain id, canvas:<id>, or canvas:<ownerUid>:<id> handle.
baseRevisionstringYesmin length 1, max length 200.
idempotencyKeystringYesmin length 8, max length 200.
targetNodeIdstringYesA new, empty image node reserved for this Action result. It must not also appear in inputs, and it must have no content, asset binding, or active Run. Pattern ^(?:node:)?[A-Za-z0-9_-]{1,180}$.
inputsarray of stringYesOne or two durable images in the exact order declared by the selected Action. min items 1, max items 2.
paramsResizeActionParameters | CropActionParameters | ChangeAspectRatioActionParameters | SideBySideActionParameters | AddTextActionParameters | OverlayImageActionParameters | ColorGradeActionParameters | RotateActionParametersYesUse the parameter object declared by GET /actions/{actionKey}. Unknown fields are rejected.
webhookImageJobWebhookInputNo—
webhook.urlstring (uri)YesA public HTTPS callback endpoint. Private, loopback, local-network, credential-bearing, and fragment-bearing URLs are rejected. max length 2048. Pattern ^https://.
webhook.secretstringYesA caller-owned HMAC secret encrypted at rest and never returned by the API. min length 32, max length 512.

Validation rules the service enforces across these fields:

  • targetNodeId must not identify any node supplied in inputs
  • targetNodeId must identify an empty, unbound image node

Responses

StatusPayloadMeaning
202ImageJob | VideoJobAn image, Action, or video job state or finalized result. Image and Action results follow the documented Run retention policy. Video records are retained for 30 days and expose a protected download URL after completion.
defaultErrorResponseA stable machine-readable error. The response always includes X-Request-ID.

202 response body

FieldTypeRequiredNotes
(ImageJob).idstringYesPattern ^job:.
(ImageJob).runstringYesPattern ^run:.
(ImageJob).kindstringYesOne of image, action.
(ImageJob).pollUrlstringYesPattern ^/api/canvas-agent/v1/runs/.
(ImageJob).rawIdstring (uuid)No—
(ImageJob).statusstringYesCurrent temporary job state. Successful results retain the observation record for 24 hours before the first successful server finalization and 15 minutes after it; an authenticated Run GET or pre-callback worker finalization both count. Failed and canceled records keep the normal 24-hour window. Expired tombstones remain seven days. One of preparing, queued, running, finalizing, canceling, succeeded, failed, canceled, expired.
(ImageJob).estimatedSecondsintegerNoTypical provider runtime for the selected model. This is guidance, not a deadline. min 1.
(ImageJob).durationMsintegerNoTotal observed duration once the job is terminal. min 0.
(ImageJob).timingImageJobTimingNo—
(ImageJob).timing.createdAtstring (date-time)No—
(ImageJob).timing.queuedAtstring (date-time)No—
(ImageJob).timing.startedAtstring (date-time)No—
(ImageJob).timing.completedAtstring (date-time)No—
(ImageJob).timing.queueDurationMsintegerNomin 0.
(ImageJob).timing.executionDurationMsintegerNomin 0.
(ImageJob).timing.totalDurationMsintegerNomin 0.
(ImageJob).failureImageJobFailureNo—
(ImageJob).failure.codestringYesOne of provider_authentication_failed, provider_timeout, provider_rate_limited, provider_rejected, provider_unavailable, runtime_failed, action_input_invalid, result_expired.
(ImageJob).failure.messagestringYes—
(ImageJob).failure.retryablebooleanYes—
(ImageJob).failure.providerStatusintegerNomin 400, max 599.
(ImageJob).webhookImageJobWebhookDeliveryNoDurable delivery state. Gavana makes four total attempts. Retryable network failures and 408, 425, 429, or 5xx responses back off for 10 seconds, 60 seconds, then 5 minutes; redirects and other 4xx responses stop delivery.
(ImageJob).webhook.idstringYesPattern ^webhook:.
(ImageJob).webhook.statusstringYesOne of pending, delivering, delivered, failed.
(ImageJob).webhook.attemptsintegerYesmin 0.
(ImageJob).webhook.nextAttemptAtstring (date-time)No—
(ImageJob).webhook.lastAttemptAtstring (date-time)No—
(ImageJob).webhook.deliveredAtstring (date-time)No—
(ImageJob).webhook.lastStatusintegerNomin 100, max 599.
(ImageJob).webhook.errorCodestringNoOne of invalid_destination, delivery_failed, redirect_not_allowed, endpoint_rejected, secret_unavailable, finalization_unavailable, finalization_auth_unavailable, finalization_auth_expired, finalization_failed.
(ImageJob).replayedbooleanNo—
(ImageJob).operationstringNoOne of generate, edit, variations, action.
(ImageJob).actionIdstringNoPattern ^action:.
(ImageJob).actionVersionstringNo—
(ImageJob).canvasIdstringNoPattern ^canvas:.
(ImageJob).canvasRevisionstringNo—
(ImageJob).canvasUrlstring (uri)No—
(ImageJob).canceledAtstring (date-time)No—
(ImageJob).cancelReasonstringNoOne of stale_preparing, user_requested, setup_failed.
(ImageJob).targetsarray of stringNo—
(ImageJob).referencesarray of stringNo—
(ImageJob).referenceInputsarray of ImageReferenceInputNoExact reference handles and optional semantic roles used by the provider request.
(ImageJob).referenceInputs[].handlestringYesPattern ^(?:node:[A-Za-z0-9_-]{1,180}|asset:(?:[A-Za-z0-9_-]{1,180}:)?[A-Za-z0-9_-]{1,180})$.
(ImageJob).referenceInputs[].rolestringNoOne of identity, construction, texture, fit, style.
(ImageJob).imagesarray of ImageJobResultImageNo—
(ImageJob).images[].assetIdstringYesPattern ^asset:.
(ImageJob).images[].nodeIdstringYesPattern ^node:.
(ImageJob).images[].mediaTypestringNoPattern ^image/.
(ImageJob).images[].widthintegerNomin 1.
(ImageJob).images[].heightintegerNomin 1.
(ImageJob).images[].bytesintegerNomin 1.
(ImageJob).images[].previewUrlstring (uri)Yes—
(ImageJob).images[].markdownstringNo—
(ImageJob).completionReviewCanvasCompletionReviewNo—
(ImageJob).completionReview.statusstringYesOne of ready, needs-review, blocked.
(ImageJob).completionReview.doneClaimAllowedbooleanYesFalse while agent-owned spatial or lineage findings remain, or a generated output is pending, failed, or non-durable.
(ImageJob).completionReview.instructionstringYes—
(ImageJob).completionReview.outputsCanvasCompletionOutputsYesGenerated-output count and durable, pending, and failed breakdown.
(ImageJob).completionReview.outputs.countintegerYesmin 0.
(ImageJob).completionReview.outputs.durableCountintegerYesmin 0.
(ImageJob).completionReview.outputs.pendingCountintegerYesmin 0.
(ImageJob).completionReview.outputs.failedCountintegerYesmin 0.
(ImageJob).completionReview.outputs.handlesarray of stringYes—
(ImageJob).completionReview.overlapCanvasCompletionFindingAreaYes—
(ImageJob).completionReview.overlap.statusstringYesOne of clear, needs-review, blocked.
(ImageJob).completionReview.overlap.findingCodesarray of stringYes—
(ImageJob).completionReview.overlap.nodeHandlesarray of stringYes—
(ImageJob).completionReview.overlap.connectionHandlesarray of stringYes—
(ImageJob).completionReview.containmentCanvasCompletionFindingAreaYes—
(ImageJob).completionReview.containment.statusstringYesOne of clear, needs-review, blocked.
(ImageJob).completionReview.containment.findingCodesarray of stringYes—
(ImageJob).completionReview.containment.nodeHandlesarray of stringYes—
(ImageJob).completionReview.containment.connectionHandlesarray of stringYes—
(ImageJob).completionReview.referenceLineageCanvasCompletionFindingAreaYes—
(ImageJob).completionReview.referenceLineage.statusstringYesOne of clear, needs-review, blocked.
(ImageJob).completionReview.referenceLineage.findingCodesarray of stringYes—
(ImageJob).completionReview.referenceLineage.nodeHandlesarray of stringYes—
(ImageJob).completionReview.referenceLineage.connectionHandlesarray of stringYes—
(ImageJob).completionReview.productFidelityCanvasProductFidelityReviewYesA conservative review signal, not an authoritative visual inspection.
(ImageJob).completionReview.productFidelity.statusstringYesOne of not-applicable, needs-review, passed.
(ImageJob).completionReview.productFidelity.reviewedOutputCountintegerYesmin 0.
(ImageJob).completionReview.productFidelity.needsReviewOutputHandlesarray of stringYes—
(ImageJob).completionReview.productFidelity.evidenceMissingOutputHandlesarray of stringYes—
(ImageJob).completionReview.productFidelity.reasonsarray of objectNo—
(ImageJob).completionReview.productFidelity.reasons[].nodeHandlestringYesPattern ^node:.
(ImageJob).completionReview.productFidelity.reasons[].reasonstringYes—
(ImageJob).completionReview.deliveryCanvasCompletionDeliveryYesGenerated-output delivery evidence. A blocked state prevents a Done claim.
(ImageJob).completionReview.delivery.statusstringYesOne of clear, blocked.
(ImageJob).completionReview.delivery.reasonsarray of stringNo—
(ImageJob).completionReview.delivery.pendingOutputHandlesarray of stringYes—
(ImageJob).completionReview.delivery.failedOutputHandlesarray of stringYes—
(ImageJob).completionReview.delivery.nonDurableOutputHandlesarray of stringYes—
(ImageJob).completionReview.blockingFindingCodesarray of stringYes—
(ImageJob).completionReview.advisoryFindingCodesarray of stringYes—
(VideoJob).idstringYesPattern ^job:.
(VideoJob).rawIdstring (uuid)Yes—
(VideoJob).kind“video”Yes—
(VideoJob).operation“generate”Yes—
(VideoJob).pollUrlstringYesPattern ^/api/canvas-agent/v1/jobs/.
(VideoJob).statusstringYesOne of queued, running, succeeded, failed, canceled.
(VideoJob).modelobjectYes—
(VideoJob).model.idstringYes—
(VideoJob).model.namestringYes—
(VideoJob).progressnumberYesmin 0, max 100.
(VideoJob).estimatedSecondsintegerYesmin 1.
(VideoJob).providerRunIdstringNo—
(VideoJob).failureVideoJobFailureNo—
(VideoJob).failure.codestringYesOne of video_generation_failed, canceled.
(VideoJob).failure.messagestringYes—
(VideoJob).failure.retryablebooleanYes—
(VideoJob).videoobjectNo—
(VideoJob).video.downloadUrlstringYesPattern ^/api/canvas-agent/v1/jobs/.+/output$.
(VideoJob).replayedbooleanNo—
(VideoJob).createdAtstring (date-time)Yes—
(VideoJob).updatedAtstring (date-time)Yes—

Callbacks

  • imageJobTerminal → {$request.body#/webhook/url}: Receive a signed terminal image-job event. Gavana signs ${timestamp}.${rawBody} with HMAC-SHA256 and the caller-owned secret. Return any 2xx response to acknowledge delivery. Delivery uses four total attempts. Retryable network failures and 408, 425, 429, or 5xx responses back off for 10 seconds, 60 seconds, then 5 minutes; redirects and other 4xx responses stop delivery. Successful Image and Action callbacks already contain durable asset and node handles in data.run.images, so callback-only clients do not need a follow-up GET. A caller with job:manage may read the shared Run later for inspection. Successful image and Action results retain their temporary observation record for 24 hours before the first successful server finalization and 15 minutes after it; an authenticated Run GET or pre-callback worker finalization both count. Failed and canceled records keep the normal 24-hour window.

Example

curl -X POST "https://app.gavana.ai/api/canvas-agent/v1/actions/action:resize/runs" \ -H "Authorization: Bearer $GAVANA_AGENT_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "canvasId": "canvas:8f2c1d40-9a77-4c2e-9c11-2b0a5f6d7e31", "baseRevision": "12", "idempotencyKey": "2026-08-04-first-attempt", "targetNodeId": "<targetNodeId>", "inputs": [ "<inputs>" ], "params": {} }'

Errors

Every failure uses the shared error envelope described in Errors and X-Request-ID. The response always carries X-Request-ID; share that value with support instead of the request payload.

Last updated on