Canvases

For instructions on how to authenticate to use this endpoint, see API overview.

Endpoints

POST
POST
POST
POST
GET
GET
POST
GET
POST
GET
GET
GET
GET
POST

Create canvases report error

Report a runtime error observed while rendering a canvas build.

Files the report in the authoring task's thread (deduped per build and error type) so the canvas's agent can be asked to fix it. Reports never start an agent run by themselves — dispatch is request_fix. Only the error class crosses the server; full messages and stacks stay client-side because rendering sessions can carry viewer data.

Required API key scopes

canvas:write

Path parameters

  • id
    string

Request parameters

  • build_id
    string
  • error_type
    string

Response


Example request

POST /api/projects/:project_id/canvases/:id/report_error
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/canvases/:id/report_error/\
-d build_id="string",\
-d error_type="string"

Example response

Status 202
RESPONSE
{
"report_outcome": "filed"
}
Status 404 Build not found for this canvas.

Create canvases request agent

Route a viewer-approved change request to the canvas's authoring task.

Required API key scopes

canvas:writetask:write

Path parameters

  • id
    string

Request parameters

  • prompt
    string

Response


Example request

POST /api/projects/:project_id/canvases/:id/request_agent
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/canvases/:id/request_agent/\
-d prompt="string"

Example response

Status 202
RESPONSE
{
"request_outcome": "signaled",
"task_id": "736fde4d-9029-4915-8189-01353d6982cb"
}
Status 403 Agent requests are not declared or the caller is a sandbox.
Status 409 The canvas has no authoring task.
Status 429 The request was denied for compute: the team's quota is exhausted (retry later), or the organization is deactivated (not retryable).

Create canvases request fix

Wake the canvas's authoring agent to fix a failing build or runtime error.

Starts (or signals) an agent run on the authoring task, instructed to stage the fix as a draft the user reviews and promotes. This is the human-initiated dispatch step behind error reports; it spends agent compute, so it never fires automatically, and only the authoring task's creator may dispatch — the run executes with their credentials.

Required API key scopes

canvas:writetask:write

Path parameters

  • id
    string

Request parameters

  • build_id
    string
  • error_type
    string

Response


Example request

POST /api/projects/:project_id/canvases/:id/request_fix
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/canvases/:id/request_fix/\
-d build_id="string"

Example response

Status 202
RESPONSE
{
"dispatch_outcome": "signaled",
"task_id": "736fde4d-9029-4915-8189-01353d6982cb"
}
Status 403 The caller is a sandbox (agents stage fixes directly as drafts), or is not the authoring task's creator (only the creator can dispatch a run under their credentials).
Status 404 Build not found for this canvas.
Status 409 The canvas has no authoring task to route the fix to.
Status 429 The team's compute quota is exhausted; retry later.

Create canvases revert

Move the canvas's head back to an existing source version and rebuild it.

Required API key scopes

canvas:write

Path parameters

  • id
    string

Request parameters

  • version_id
    string
  • expected_current_version_id
    string | null

Response


Example request

POST /api/projects/:project_id/canvases/:id/revert
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/canvases/:id/revert/\
-d version_id="string",\
-d expected_current_version_id="string"

Example response

Status 200
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"source_version_id": "adb2dc89-2007-42cb-8da1-8d6c68cbf772",
"build_status": "queued",
"diagnostics": [
{
"severity": "error",
"code": "string",
"message": "string",
"path": "string",
"line": 0
}
],
"manifest": {
"entryHtml": "string",
"assets": [
{
"path": "string",
"contentHash": "string",
"sizeBytes": 0
}
],
"dependencies": {
"property1": "string",
"property2": "string"
},
"canvasSdkVersion": "string",
"legacyComponentPath": "string",
"legacyCode": "string",
"capabilities": {},
"component": {}
},
"integrity": "string",
"artifact_url": "string",
"pinned": true,
"created_at": "2019-08-24T14:15:22Z",
"finished_at": "2019-08-24T14:15:22Z"
}
Status 429 The team's build capacity is exhausted; retry shortly.

Retrieve canvases source

Read the canvas's source project and its current_version_id.

Always call this before editing: edit the returned files, then publish the complete project passing the returned version id as expected_current_version_id so concurrent edits are not overwritten. ?version_id= reads a historical version instead of the head.

Required API key scopes

canvas:read

Path parameters

  • id
    string

Query parameters

  • version_id
    string

Response


Example request

GET /api/projects/:project_id/canvases/:id/source
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/canvases/:id/source/

Example response

Status 200
RESPONSE
{
"canvas": {
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"name": "string",
"kind": "freeform",
"channel_id": "bbe8aa76-a4bb-46f6-a785-df8e831cc459",
"current_version_id": "string",
"published_build_id": "string",
"created_at": "2019-08-24T14:15:22Z",
"url": "string"
},
"project": {
"schemaVersion": 0,
"files": {
"property1": "string",
"property2": "string"
},
"assets": {
"property1": {
"encoding": "base64",
"contentType": "image/png",
"content": "string"
},
"property2": {
"encoding": "base64",
"contentType": "image/png",
"content": "string"
}
},
"entryHtml": "string",
"dependencies": {
"property1": "string",
"property2": "string"
},
"canvasSdkVersion": "string",
"component": {
"size": {
"defaultW": 1,
"defaultH": 1,
"minW": 1,
"minH": 1,
"maxW": 1,
"maxH": 1
},
"configSchema": {}
},
"capabilities": {
"posthog": {
"insights": [
"string"
],
"inlineQueries": true,
"captureEvents": [
"string"
],
"state": [
"user"
],
"actions": [
"string"
],
"agentRequests": false
},
"network": {
"origins": [
"http://example.com"
]
},
"connectors": [
{
"provider": "string",
"tools": [
"string"
]
}
]
}
},
"current_version_id": "string"
}

Retrieve canvases state

Read the canvas's runtime key-value state (the ph.state store).

Returns shared entries plus the authenticated user's own user-scoped entries — never another user's.

Required API key scopes

canvas:read

Path parameters

  • id
    string

Query parameters

  • cursor
    string
  • key
    string
  • key_prefix
    string
  • keys_only
    boolean
    Default: false
  • limit
    integer
  • offset
    integer
    Default: 0
  • scope
    string
    One of: "user""shared"

Response


Example request

GET /api/projects/:project_id/canvases/:id/state
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/canvases/:id/state/

Example response

Status 200
RESPONSE
{
"entries": [
{
"scope": "user",
"key": "string",
"value": null,
"updated_at": "2019-08-24T14:15:22Z"
}
],
"next_offset": 0,
"next_cursor": "string",
"complete": true
}
Status 400 Invalid query, or a malformed cursor.
Status 403 Canvas state requires an authenticated user.

Create canvases state

Write one key of the canvas's runtime state, or delete it with a null value.

Required API key scopes

canvas:write

Path parameters

  • id
    string

Request parameters

  • scope
  • key
    string
  • value

Response


Example request

POST /api/projects/:project_id/canvases/:id/state/set
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/canvases/:id/state/set/\
-d scope=undefined,\
-d key="string",\
-d value=undefined

Example response

Status 200
RESPONSE
{
"scope": "user",
"key": "string",
"value": null,
"updated_at": "2019-08-24T14:15:22Z"
}
Status 204 The key was deleted (value was null).
Status 400 The value or the scope's key count exceeds the state bounds.
Status 403 The scope is not declared in the canvas's capabilities, or the caller is a sandbox.

Retrieve canvases state value

Canvases: agent-built sandboxed browser apps, filed into channels.

Source is versioned per publish and built server-side; the canvas app renders the published build's artifact from the isolated artifact origin.

Required API key scopes

canvas:read

Path parameters

  • id
    string

Query parameters

  • key
    string
  • limit
    integer
    Default: 12000
  • offset
    integer
    Default: 0
  • revision
    string
  • scope
    string
    One of: "user""shared"

Response


Example request

GET /api/projects/:project_id/canvases/:id/state/value
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/canvases/:id/state/value/

Example response

Status 200
RESPONSE
{
"scope": "user",
"key": "string",
"value_json": "string",
"revision": "string",
"offset": 0,
"total_length": 0,
"next_offset": 0,
"complete": true
}
Status 400 Invalid query, or the offset exceeds the value length.
Status 404 No readable value for this scope and key.
Status 409 The value changed. Restart from offset zero.

Create canvases validate

Validate a candidate source project without publishing it. Side-effect free.

Required API key scopes

canvas:read

Path parameters

  • id
    string

Request parameters

  • project

Response


Example request

POST /api/projects/:project_id/canvases/:id/validate
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/canvases/:id/validate/\
-d project=undefined

Example response

Status 200
RESPONSE
{
"valid": true,
"diagnostics": [
{
"severity": "error",
"code": "string",
"message": "string",
"path": "string",
"line": 0
}
]
}

Retrieve canvases versions

The canvas's published source-version history, newest first (metadata only).

Drafts are excluded: they are staged versions that have never been the head, so they are not part of the undo/revert timeline. Fetch a draft's files with source?version_id= to preview it before promoting.

Required API key scopes

canvas:read

Path parameters

  • id
    string

Query parameters

  • limit
    integer
  • offset
    integer

Response


Example request

GET /api/projects/:project_id/canvases/:id/versions
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/canvases/:id/versions/

Example response

Status 200
RESPONSE
{
"count": 123,
"next": "http://api.example.org/accounts/?offset=400&limit=100",
"previous": "http://api.example.org/accounts/?offset=200&limit=100",
"results": [
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"parent_version_id": "f8d7c285-7613-4ade-8a91-ac987c2c73a9",
"prompt": "string",
"task_id": "736fde4d-9029-4915-8189-01353d6982cb",
"draft": true,
"created_by": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"distinct_id": "string",
"first_name": "string",
"last_name": "string",
"email": "user@example.com",
"is_email_verified": true,
"hedgehog_config": {},
"role_at_organization": "engineering"
},
"created_at": "2019-08-24T14:15:22Z"
}
]
}

Retrieve canvases view

Everything needed to open the canvas, in one round trip.

Returns the record, the live build (with its signed artifact URL), and — only when there is nothing built to render — the head source project (freeform/component) or the layout document (grid). Send the response's ETag back as If-None-Match to revalidate without a body.

Required API key scopes

canvas:read

Path parameters

  • id
    string

Response


Example request

GET /api/projects/:project_id/canvases/:id/view
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/canvases/:id/view/

Example response

Status 200
RESPONSE
{
"canvas": {
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"name": "string",
"kind": "freeform",
"description": "string",
"channel": "e03ac425-e659-44cf-b8d7-f4176416fcf2",
"template_id": "string",
"generation_task_id": "3dbed3af-6ffc-42e6-a65f-e4359d320aee",
"pinned": true,
"pinned_at": "2019-08-24T14:15:22Z",
"current_version_id": "158beffb-f9de-457f-bbee-873740e72504",
"published_build_id": "69a71d2a-40ba-4471-84c6-e403214736b9",
"component_meta": {
"size": {
"defaultW": 1,
"defaultH": 1,
"minW": 1,
"minH": 1,
"maxW": 1,
"maxH": 1
},
"configSchema": {}
},
"created_by": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"distinct_id": "string",
"first_name": "string",
"last_name": "string",
"email": "user@example.com",
"is_email_verified": true,
"hedgehog_config": {},
"role_at_organization": "engineering"
},
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"url": "string"
},
"published_build": {
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"source_version_id": "adb2dc89-2007-42cb-8da1-8d6c68cbf772",
"build_status": "queued",
"diagnostics": [
{
"severity": "error",
"code": "string",
"message": "string",
"path": "string",
"line": 0
}
],
"manifest": {
"entryHtml": "string",
"assets": [
{
"path": "string",
"contentHash": "string",
"sizeBytes": 0
}
],
"dependencies": {
"property1": "string",
"property2": "string"
},
"canvasSdkVersion": "string",
"legacyComponentPath": "string",
"legacyCode": "string",
"capabilities": {},
"component": {}
},
"integrity": "string",
"artifact_url": "string",
"pinned": true,
"created_at": "2019-08-24T14:15:22Z",
"finished_at": "2019-08-24T14:15:22Z"
},
"current_version_id": "string",
"has_active_build": true,
"source": {
"schemaVersion": 0,
"files": {
"property1": "string",
"property2": "string"
},
"assets": {
"property1": {
"encoding": "base64",
"contentType": "image/png",
"content": "string"
},
"property2": {
"encoding": "base64",
"contentType": "image/png",
"content": "string"
}
},
"entryHtml": "string",
"dependencies": {
"property1": "string",
"property2": "string"
},
"canvasSdkVersion": "string",
"component": {
"size": {
"defaultW": 1,
"defaultH": 1,
"minW": 1,
"minH": 1,
"maxW": 1,
"maxH": 1
},
"configSchema": {}
},
"capabilities": {
"posthog": {
"insights": [
"string"
],
"inlineQueries": true,
"captureEvents": [
"string"
],
"state": [
"user"
],
"actions": [
"string"
],
"agentRequests": false
},
"network": {
"origins": [
"http://example.com"
]
},
"connectors": [
{
"provider": "string",
"tools": [
"string"
]
}
]
}
},
"layout": {
"schemaVersion": 1,
"grid": {
"columns": 4,
"rowHeight": 24,
"gap": 48
},
"placements": [
{
"id": "string",
"status": "pending",
"component": "string",
"version": "string",
"x": 0,
"y": 0,
"w": 1,
"h": 1,
"config": {},
"prompt": "string",
"generationTaskId": "string"
}
]
},
"component_lifecycles": [
{
"canvas_id": "string",
"requested_version_id": "string",
"published_build_id": "string",
"current_version_id": "string",
"builds": [
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"source_version_id": "adb2dc89-2007-42cb-8da1-8d6c68cbf772",
"build_status": "queued",
"diagnostics": [
{
"severity": "error",
"code": "string",
"message": "string",
"path": "string",
"line": 0
}
],
"manifest": {
"entryHtml": "string",
"assets": [
{
"path": "string",
"contentHash": "string",
"sizeBytes": 0
}
],
"dependencies": {
"property1": "string",
"property2": "string"
},
"canvasSdkVersion": "string",
"legacyComponentPath": "string",
"legacyCode": "string",
"capabilities": {},
"component": {}
},
"integrity": "string",
"artifact_url": "string",
"pinned": true,
"created_at": "2019-08-24T14:15:22Z",
"finished_at": "2019-08-24T14:15:22Z"
}
]
}
],
"sandbox_document_url": "string"
}
Status 304 Not modified — the client's cached view payload is current.

Retrieve canvases actions

List the action registry: every verb a canvas may declare and invoke.

Response


Example request

GET /api/projects/:project_id/canvases/actions
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/canvases/actions/

Example response

Status 200
RESPONSE
{
"actions": [
{
"verb": "string",
"summary": "string",
"destructive": true,
"usage": "string"
}
]
}

Retrieve canvases connectors

List the connector catalog: every provider and tool a canvas may declare, with the caller's connection state.

Authoring agents read this to write ph.connectors.call sites and the matching capabilities.connectors declarations. Sandbox tokens receive only static native tools, with no connection lookup or MCP installation data.

Required API key scopes

canvas:read

Query parameters

  • mcp_hosts
    string

Response


Example request

GET /api/projects/:project_id/canvases/connectors
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/canvases/connectors/

Example response

Status 200
RESPONSE
{
"connectors": [
{
"provider": "string",
"display_name": "string",
"kind": "native",
"connected": true,
"connect_path": "string",
"tools": [
{
"name": "string",
"summary": "string",
"is_read_only": true,
"input_schema": {},
"usage": "string"
}
]
}
]
}
Status 403 Connectors are not enabled for this team.

Create canvases home

Get or provision the caller's home canvas.

Idempotent: returns the user's existing home canvas, or creates a grid canvas in their personal channel and points their home preference at it. The home surface calls this on open.

Required API key scopes

canvas:write

Response


Example request

POST /api/projects/:project_id/canvases/home
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/canvases/home/

Example response

Status 200 The caller's existing home canvas.
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"name": "string",
"kind": "freeform",
"description": "string",
"channel": "e03ac425-e659-44cf-b8d7-f4176416fcf2",
"template_id": "string",
"generation_task_id": "3dbed3af-6ffc-42e6-a65f-e4359d320aee",
"pinned": true,
"pinned_at": "2019-08-24T14:15:22Z",
"current_version_id": "158beffb-f9de-457f-bbee-873740e72504",
"published_build_id": "69a71d2a-40ba-4471-84c6-e403214736b9",
"component_meta": {
"size": {
"defaultW": 1,
"defaultH": 1,
"minW": 1,
"minH": 1,
"maxW": 1,
"maxH": 1
},
"configSchema": {}
},
"created_by": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"distinct_id": "string",
"first_name": "string",
"last_name": "string",
"email": "user@example.com",
"is_email_verified": true,
"hedgehog_config": {},
"role_at_organization": "engineering"
},
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"url": "string"
}
Status 201 A home canvas was provisioned for the caller.
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"name": "string",
"kind": "freeform",
"description": "string",
"channel": "e03ac425-e659-44cf-b8d7-f4176416fcf2",
"template_id": "string",
"generation_task_id": "3dbed3af-6ffc-42e6-a65f-e4359d320aee",
"pinned": true,
"pinned_at": "2019-08-24T14:15:22Z",
"current_version_id": "158beffb-f9de-457f-bbee-873740e72504",
"published_build_id": "69a71d2a-40ba-4471-84c6-e403214736b9",
"component_meta": {
"size": {
"defaultW": 1,
"defaultH": 1,
"minW": 1,
"minH": 1,
"maxW": 1,
"maxH": 1
},
"configSchema": {}
},
"created_by": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"distinct_id": "string",
"first_name": "string",
"last_name": "string",
"email": "user@example.com",
"is_email_verified": true,
"hedgehog_config": {},
"role_at_organization": "engineering"
},
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"url": "string"
}
Status 403 Home is a viewer surface; sandbox tokens cannot provision it.