Docs

Start here

Save a canvas

POST/v1/studio/projects/{project}/canvases/{canvas}on https://api.auray.ai/v1

Save a canvas over the revision it was drawn from.

Save a canvas over the revision it was drawn from. A save from an older revision is refused revision_conflict with the current rev, so two windows never overwrite each other unseen; once a canvas is edited live, a save is written into its live state as well. Any run a document carries is ignored. Needs the edit_canvas capability. Takes a key holding studio:write — Account offers it unticked — or the desktop's own session key. Spends nothing.

#Authentication

Authorization: Bearer auray_sk_… — studio:write — Account offers it unticked; the desktop's session key holds it.

#Request

#Path parameters

NameTypeRequiredDescription
projectstringyes
canvasstringyes

#Body

application/json, required.

FieldTypeRequiredDefaultDescription
docobjectyes—A canvas document, version 1: pages (up to 20), each with its viewport, its nodes (up to 1,500 — prompts, generators, uploads and the project's assets, upscalers, editors, notes, stickies, shapes, text, drawn strokes, tables, comment pins, reactions and frames) and the edges wiring an output port into an input port that takes its type. The full shape is published with the Studio's contract; a document that does not read is refused canvas_invalid, naming each problem. A node's run is the server's: anything sent there is ignored.
doc.vintegeryes—One of 1.
doc.pagesobject[]yes—
doc.pages[].idstringyes—
doc.pages[].namestringyes—0 to 80 characters.
doc.pages[].viewportobjectyes—
doc.pages[].viewport.xnumberno—
doc.pages[].viewport.ynumberno—
doc.pages[].viewport.zoomnumberno—0.05 to 4.
doc.pages[].nodesobject[]yes—
doc.pages[].nodes[].idstringyes—
doc.pages[].nodes[].kindstringyes—One of "prompt", "number", "upload", "assets", "image_gen", "video_gen", "audio_gen", "llm", "upscale", "edit", "note", "sticky", "shape", "text", "stroke", "table", "comment_pin", "reaction", "frame".
doc.pages[].nodes[].xnumberyes—
doc.pages[].nodes[].ynumberyes—
doc.pages[].nodes[].wnumberyes—
doc.pages[].nodes[].hnumberyes—
doc.pages[].nodes[].parentstringno—May be null.
doc.pages[].nodes[].zintegerno—
doc.pages[].nodes[].lockedbooleanno—
doc.pages[].nodes[].dataobjectyes—
doc.pages[].nodes[].runobjectno—A node's last run, read off the jobs it started — never written by a request. Null before it ran. May be null.
doc.pages[].edgesobject[]yes—
doc.pages[].edges[].idstringyes—
doc.pages[].edges[].fromobjectyes—
doc.pages[].edges[].toobjectyes—
base_revintegeryes—The rev the canvas was read at. 1 to ….
namestringno—A new name; the old one is kept when none is sent. 1 to 80 characters.

#Example request

curl -X POST https://api.auray.ai/v1/studio/projects/3f0c8a52-6a1d-4e8b-9c2d-7e5f4a3b2c1d/canvases/… \
  -H "Authorization: Bearer $AURAY_API_KEY" \
  -H "content-type: application/json" \
  -d '{
  "doc": {
    "v": 1,
    "pages": [
      {
        "id": "page-1",
        "name": "Page 1",
        "viewport": {
          "x": 0,
          "y": 0,
          "zoom": 1
        },
        "nodes": [
          {
            "id": "prompt-1",
            "kind": "prompt",
            "x": 0,
            "y": 0,
            "w": 280,
            "h": 160,
            "parent": null,
            "z": 0,
            "locked": false,
            "data": {
              "text": "A lighthouse in a storm, seen from the sea."
            },
            "run": null
          },
          {
            "id": "image-1",
            "kind": "image_gen",
            "x": 400,
            "y": 0,
            "w": 300,
            "h": 340,
            "parent": null,
            "z": 0,
            "locked": false,
            "data": {
              "model": null,
              "prompt": "",
              "params": {}
            },
            "run": null
          }
        ],
        "edges": [
          {
            "id": "edge-1",
            "from": {
              "node": "prompt-1",
              "port": "text"
            },
            "to": {
              "node": "image-1",
              "port": "prompt"
            }
          }
        ]
      }
    ]
  },
  "base_rev": 1
}'

#Responses

#200 OK

OK.

FieldTypeRequiredDefaultDescription
objectstringyes—One of "canvas".
idstringyes—
project_idstringyes—
namestringyes—0 to 80 characters.
revintegeryes—A save names the rev it was drawn from. 1 to ….
pagesintegeryes—1 to ….
nodesintegeryes—0 to ….
updated_atstringyes—
updated_bynull or objectyes—Who saved it last, while they are a member; null once they left.
docobjectyes—A canvas document, version 1: pages (up to 20), each with its viewport, its nodes (up to 1,500 — prompts, generators, uploads and the project's assets, upscalers, editors, notes, stickies, shapes, text, drawn strokes, tables, comment pins, reactions and frames) and the edges wiring an output port into an input port that takes its type. The full shape is published with the Studio's contract; a document that does not read is refused canvas_invalid, naming each problem. A node's run is the server's: anything sent there is ignored.
doc.vintegeryes—One of 1.
doc.pagesobject[]yes—
doc.pages[].idstringyes—
doc.pages[].namestringyes—0 to 80 characters.
doc.pages[].viewportobjectyes—
doc.pages[].viewport.xnumberno—
doc.pages[].viewport.ynumberno—
doc.pages[].viewport.zoomnumberno—0.05 to 4.
doc.pages[].nodesobject[]yes—
doc.pages[].nodes[].idstringyes—
doc.pages[].nodes[].kindstringyes—One of "prompt", "number", "upload", "assets", "image_gen", "video_gen", "audio_gen", "llm", "upscale", "edit", "note", "sticky", "shape", "text", "stroke", "table", "comment_pin", "reaction", "frame".
doc.pages[].nodes[].xnumberyes—
doc.pages[].nodes[].ynumberyes—
doc.pages[].nodes[].wnumberyes—
doc.pages[].nodes[].hnumberyes—
doc.pages[].nodes[].parentstringno—May be null.
doc.pages[].nodes[].zintegerno—
doc.pages[].nodes[].lockedbooleanno—
doc.pages[].nodes[].dataobjectyes—
doc.pages[].nodes[].runobjectno—A node's last run, read off the jobs it started — never written by a request. Null before it ran. May be null.
doc.pages[].edgesobject[]yes—
doc.pages[].edges[].idstringyes—
doc.pages[].edges[].fromobjectyes—
doc.pages[].edges[].toobjectyes—
bytesintegeryes—The document's size as JSON, which is kept up to 2 MB. 0 to ….
crdtstringyes—The name the canvas's live edits travel under: canvas: and its id.
request_idstringno—Mirrored in the X-Request-Id header.

Headers:

HeaderDescription
RateLimit-LimitBurst capacity.
RateLimit-Remaining
RateLimit-ResetSeconds until refill.
X-RateLimit-Limit
X-RateLimit-Remaining
X-RateLimit-ResetUnix seconds. The X- spelling is what client libraries read.
X-Request-Id

#400 Bad Request

#401 Unauthorized

#403 Forbidden

#404 Not Found

#409 Conflict

#413 Payload Too Large

#429 Too Many Requests

#500 Internal Server Error

#503 Service Unavailable

#Status codes

StatusMeaning
200OK.
400Bad Request
401Unauthorized
403Forbidden
404Not Found
409Conflict
413Payload Too Large
429Too Many Requests
500Internal Server Error
503Service Unavailable

Every refusal names its code, and every code is explained at Errors.

Start typing to search every page of the documentation.

Up arrow Down arrow to moveEnter to openEscape to close