The Canvas API uses a single endpoint to dispatch operations via the tool field. This page documents each tool and its parameters.
Using an MCP client like Claude, ChatGPT, or Cursor? The easiest way to give
an agent these tools is the Runchat MCP server —
it exposes every tool below (plus model discovery and skills) and handles auth
for you. The REST endpoint documented here is for plain HTTP / scripted
access.
POST https://runchat.com/api/v1/{runchat_id}/canvas
Authorization: Bearer {api_key}
Content-Type: application/json
{
"tool": "<tool_name>",
"args": { ... }
}
All responses follow the shape { "result": { ... } }.
A machine-readable skill specification for this API is available at GET https://runchat.com/api/skills/canvas. AI agents can fetch this endpoint to
learn the full tool schema automatically. We also include links to this in the
ai-instructions metatag for any link to a workflow so you can simply share a
link to a workflow and ask it to follow any instructions.
Typical workflow
get_canvas — discover what’s on the canvas
read_nodes — inspect specific nodes and their handles
create_prompt_node / create_code_node / … / update_node / connect_nodes — build or modify the workflow
organize_nodes — auto-layout the result
run_nodes — execute the workflow
get_canvas
Get a high-level overview of all nodes and edges on the canvas. Returns node IDs, types, labels, positions, and edge connections. Paginated at 50 nodes per page.
| Parameter | Type | Required | Description |
|---|
offset | number | no | Pagination offset. Omit for the first page. Use the next_offset value from a previous response to fetch the next page. |
read_nodes
Read the full state of one or more nodes by ID. Returns each parameter’s name, type, label, status, and current data values. Use this to find handle names for connect_nodes.
| Parameter | Type | Required | Description |
|---|
node_ids | string[] | yes | Array of node IDs to read. |
Creating nodes
Each node type has its own creation tool with a flat, type-specific schema — easier to call correctly than one polymorphic tool. Every creation tool shares these optional fields:
| Parameter | Type | Required | Description |
|---|
label | string | no | Display label for the node. |
position | { x: number, y: number } | no | Explicit placement — offsets in canvas units from the top-left of the user’s viewport (or origin 0,0). Omit to auto-place. Nodes are ~360 units wide; leave ~420 horizontal / ~260 vertical. |
input_depths | object | no | Depth settings for input parameters. 0 = each (default), 1 = all, -1 = flatten. |
create_node (a single polymorphic call taking a type field) remains
available as a legacy alias and is the only way to create several nodes in
one call — see Creating multiple nodes.
create_prompt_node
Create an LLM node (promptNode) for reasoning, writing, analysis, or agent tasks. Output is on the messages handle; structured output (output_format) is on artifacts.
| Parameter | Type | Required | Description |
|---|
prompt | string | yes | The task or question. One task only — feeding N values in later runs the node N times. Persona/system text goes in instruction. |
model_id | string | no | api_id of the LLM (from list_models type llm). Omit for the default model. |
instruction | string | no | System prompt / persona (a hidden input — cannot be connected to). |
output_format | string | no | "list" (array of strings), "html" (complete HTML document), "code" (single code block), or a JSON schema string. Omit for text. |
tools | string[] | no | runchat_ids of published tools (from search_tools) the model can call while it runs. |
Create a user-input widget (inputNode). Its value is exposed on the content handle. One input node holds a whole list — set a list with values, not one node per item.
| Parameter | Type | Required | Description |
|---|
format | "string" | "slider" | "toggle" | "image" | "file" | "select" | "button" | "code" | no | Widget type. Defaults to "string". |
value | string | no | Initial single value. For image, an image URL. Ignored for select — use options/selected. |
values | string[] | no | Initial LIST of values held by this one node. Downstream nodes run once per item. Use instead of value for lists. |
options | string[] | no | For select only: the dropdown options. |
selected | string | no | For select only: the initially selected option (defaults to the first). |
create_image_node
Create a media generation node (imageNode) — images, video, 3D, or audio. Generated media is on the image handle. Always call get_model_params for the model first and use the returned parameter names as params keys.
| Parameter | Type | Required | Description |
|---|
model_id | string | yes | The api_id of the generation model. |
params | object | no | Model parameter values keyed by the names from get_model_params, e.g. { "prompt": "a red chair", "aspect_ratio": "16:9" }. |
create_code_node
Create a code node (codeNode). Code executes on the server only when the node is run. Output is on the result handle by default.
| Parameter | Type | Required | Description |
|---|
language | "javascript" | "html" | "rhino-python" | "blender-python" | "revit-csharp" | no | "javascript" (default) sandboxed JS/TS. "html" renders in a live preview iframe. CAD languages run in the connected app via the bridge. |
code | string | no | The source code. |
inputs | object | no | Named input handles with defaults, e.g. { "myInput": "default" }. Reference them in code by the same camelCase names. |
outputs | string[] | no | Named output handles, e.g. ["summary", "imageUrl"]. Declare only when the code returns an object with exactly these keys. |
JavaScript nodes support multiple files: add a package.json and helper modules with create_files after creation (this upgrades the node to the bundler sandbox automatically). Other languages have a single entry file.
create_note
Create a markdown note (noteNode) for documentation, summaries, or links.
| Parameter | Type | Required | Description |
|---|
content | string | yes | The markdown content of the note. |
Place a published tool (found with search_tools) onto the canvas as a runChatNode.
| Parameter | Type | Required | Description |
|---|
tool_id | string | yes | The runchat_id of the published tool (from search_tools). |
expand | boolean | no | When true, copy the tool’s full internal node graph onto the canvas as editable nodes instead of one collapsed tool node. |
inputs | object | no | Input values keyed by the tool’s input parameter names (from search_tools). |
create_artifact_node
Create an artifact node (artifactNode) that saves or fetches an artifact (blog post, website, or app).
| Parameter | Type | Required | Description |
|---|
operation | "create" | "get" | no | "create" to save/update content (default), "get" to fetch an existing artifact by ID. |
name | string | no | Artifact name (create mode). |
content | string | no | Content to save — markdown (→ blog), HTML (→ website), or app HTML that uses window.runchat (→ app). |
artifact_id | string | no | Only when fetching or updating an existing artifact. |
folder | string | no | Optional folder path, e.g. "myFolder/subFolder". |
Creating multiple nodes
The legacy create_node tool takes a nodes array to create a whole pipeline in one call. Each item is a full node spec (type required), and an optional position lays it out. The response is { "count": N, "nodes": [ ... ] }.
{
"tool": "create_node",
"args": {
"nodes": [
{
"type": "inputNode",
"label": "Topic",
"initial_data": { "input": ["robots"] },
"position": { "x": 0, "y": 0 }
},
{
"type": "promptNode",
"label": "Write",
"initial_data": { "prompt": ["Write a haiku about {{topic}}"] },
"position": { "x": 420, "y": 0 }
}
]
}
}
Omit position on any node to let it auto-place. If you set positions yourself you don’t need to call organize_nodes.
update_node
Update an existing node’s label, model, or input values.
| Parameter | Type | Required | Description |
|---|
node_id | string | yes | The ID of the node to update. |
label | string | no | New display label. |
model_id | string | no | Change the model on this node. |
inputs | object | no | Input values to set, keyed by parameter name. Values are arrays with one string element. |
input_depths | object | no | Depth settings for input parameters. |
connect_nodes
Connect an output of one node to an input of another — one edge, or many at once via edges.
| Parameter | Type | Required | Description |
|---|
source_node_id | string | yes* | The ID of the source node (data flows from here). Required for a single edge; omit at the top level when using edges. |
target_node_id | string | yes* | The ID of the target node (data flows to here). |
source_handle | string | no | Output parameter name on the source node. |
target_handle | string | no | Input parameter name on the target node. |
edges | object[] | no | Connect multiple edges in one call. Each item takes the same fields as a single connect (source_node_id and target_node_id required). When present, the top-level fields are ignored. |
Common handles:
| Node Type | Inputs | Outputs |
|---|
promptNode | messages (any type), prompt (string) | messages |
codeNode | code (string) | result |
inputNode | — | content |
imageNode | (from get_model_params) | image |
When you pass edges, the response is { "count": N, "edges": [ ... ] } with one result per edge — an edge that fails (e.g. an unknown handle) is reported individually without aborting the others.
{
"tool": "connect_nodes",
"args": {
"edges": [
{
"source_node_id": "abc",
"target_node_id": "def",
"target_handle": "prompt"
},
{
"source_node_id": "def",
"target_node_id": "ghi",
"target_handle": "messages"
}
]
}
}
organize_nodes
Auto-layout nodes on the canvas based on their connections. Call this after completing all node-creation and connect_nodes operations.
| Parameter | Type | Required | Description |
|---|
node_ids | string[] | yes | Array of node IDs to organize. |
delete_nodes
Delete one or more nodes from the canvas. Also removes any connected edges.
| Parameter | Type | Required | Description |
|---|
node_ids | string[] | yes | Array of node IDs to delete. |
delete_edges
Delete one or more edges (connections) from the canvas without deleting the nodes.
| Parameter | Type | Required | Description |
|---|
edge_ids | string[] | yes | Array of edge IDs to delete. |
run_nodes
Execute one or more nodes on the canvas. Nodes run in dependency order — upstream nodes execute first. Returns status and output parameter names for each node.
| Parameter | Type | Required | Description |
|---|
node_ids | string[] | yes | Array of node IDs to execute. |
Running nodes may consume credits. Confirm with the user before calling this
tool.
Find published tools (and the user’s own runchats) and run them directly, without first placing them on a canvas.
These tools operate on the published-tool library, not the current canvas. For
inspect_tool and execute_tool the runchat_id in args names the
tool to act on — the {runchat_id} in the endpoint URL is only the
canvas/auth scope and is ignored by these tools.
Search published tools and the user’s own runchats by keyword. Returns each tool’s runchat_id, name, description, and its input/output parameter names — enough to run it with execute_tool.
| Parameter | Type | Required | Description |
|---|
query | string | no | Keywords to match against tool names and descriptions. Omit to list popular tools. |
limit | number | no | Max results to return. Defaults to 8, max 25. |
Inspect a published tool to see its inputs/outputs and a digest of its internal nodes (models, prompts, code) and connections. Optional — use it to learn how a tool is built or before placing it on a canvas; not required to run a tool.
| Parameter | Type | Required | Description |
|---|
runchat_id | string | yes | The runchat_id of the tool to inspect (from search_tools). |
Run a published tool and return its outputs, without adding it to a canvas. Provide inputs keyed by the tool’s input parameter names (from search_tools); the result reports any inputs that didn’t match.
| Parameter | Type | Required | Description |
|---|
runchat_id | string | yes | The runchat_id of the tool to run (from search_tools). |
inputs | object | no | Input values keyed by the tool’s input parameter names. Each value is a string or array of strings. |
version_num | number | no | Specific published version to run. Defaults to the latest released version. |
Running a tool spends the authenticated user’s credits. Confirm before running
anything costly.
get_model_params
Get full parameter details for one or more models. Returns parameter names, types, and defaults — use these as initial_data keys when creating an imageNode.
| Parameter | Type | Required | Description |
|---|
model_id | string | no | A single api_id of the model. |
model_ids | string[] | no | An array of api_ids to fetch details for multiple models at once. |
view_image
Fetch an image from a URL for analysis.
| Parameter | Type | Required | Description |
|---|
url | string | yes | The URL of the image. Supports PNG, JPEG, GIF, WebP, and SVG. |
format | string | no | For SVG URLs only: render (default) rasterises to PNG; source returns the raw SVG markup. |
question | string | no | Ask a vision model a specific question about the image and return its answer as text. Useful when your own model can’t view images. |
Every codeNode exposes a uniform file model. JavaScript nodes have an entry file (index.ts, plain JS or TypeScript) plus optional additional files (package.json for npm deps, helper modules, static .html assets) — adding files upgrades the node to the bundler sandbox automatically. Other languages (html, rhino-python, blender-python, revit-csharp) have a single entry file.
Entry filenames by language:
language | Entry file |
|---|
javascript | index.ts |
html | index.html |
rhino-python / blender-python | index.py |
revit-csharp | index.cs |
Always call read_files (or read_nodes) first to discover the entry path — never guess based on language.
read_files
Read content from a code node. Returns each file’s path, line-numbered content, length, and whether it’s the entry file.
| Parameter | Type | Required | Description |
|---|
node_id | string | yes | The ID of the code node. |
files | string[] | no | Specific paths to read. Omit to read all files in the node (recommended when you don’t know paths yet). |
Response includes code_mode, entry_file, and a files array of { path, entry, length, content } plus not_found if any requested paths are missing.
edit_file
Edit one file in a code node. Two modes:
- Targeted edit — pass
old_text + new_text. old_text must match exactly (whitespace + indentation) and be unique in the file. Empty new_text deletes the matched span.
- Full overwrite — pass only
new_text (omit old_text). Replaces the entire file.
Always call read_files first to see current content.
| Parameter | Type | Required | Description |
|---|
node_id | string | yes | The ID of the code node. |
file | string | yes | The file path (e.g. "index.ts", "package.json"). Use the path returned by read_files. |
new_text | string | yes | The replacement text (when old_text is set) or the full new file contents (when omitted). |
old_text | string | no | When present: the exact substring to find and replace. Must be unique. When omitted: overwrites file. |
create_files
Create one or more new files in a JavaScript code node (e.g. package.json, lib/utils.ts, a static index.html asset). JavaScript nodes only — other languages have a single fixed entry file. Adding files upgrades the node to the bundler sandbox automatically. Errors if any path collides with the entry file or an existing file.
| Parameter | Type | Required | Description |
|---|
node_id | string | yes | The ID of the JavaScript code node. |
files | { path: string, content: string }[] | yes | Files to create. Paths must not collide with existing files. |
delete_files
Delete one or more non-entry files from a JavaScript code node. Cannot delete the entry file.
| Parameter | Type | Required | Description |
|---|
node_id | string | yes | The ID of the JavaScript code node. |
files | string[] | yes | Paths of files to delete. |
read_status
Read current error messages, status messages, preview errors, and console output for a code node. Use when debugging a failing run.
| Parameter | Type | Required | Description |
|---|
node_id | string | yes | The ID of the code node to check. |
Skill Endpoint
The Canvas API skill specification is available as a machine-readable document that AI agents can fetch to learn the full tool schema automatically.
GET https://runchat.com/api/skills/canvas
Returns a Markdown document with YAML frontmatter containing the complete tool reference. The response includes:
- API description and base URL
- All tool schemas with parameter types and descriptions
- Common handle names and workflow guidance
This is useful for integrating external AI agents (e.g. Claude, GPT) that need to discover and use the Canvas API programmatically.