Endpoints
Every endpoint of the PopCraft REST API, generated from the OpenAPI spec.
Endpoints
Generated from the OpenAPI spec (version 1.4.0). Do not edit by hand: run npx tsx scripts/gen-api-docs.ts.
All paths are relative to /api/v1. See the overview for authentication, scopes, rate limits and paging.
| Endpoint | What it does | Scope |
|---|---|---|
GET /me | The token’s user and workspaces | any token |
GET /files | Files you can open | files:read |
POST /files | Create a file | files:write |
GET /files/{key} | File metadata, your role and document JSON | files:read |
PUT /files/{key} | Replace the document | files:write |
POST /files/{key}/commands | Run editing commands | files:write |
GET /files/{key}/nodes | Nodes with their subtrees | files:read |
GET /files/{key}/images | Thumbnail and media assets the file references | files:read |
GET /files/{key}/thumbnail | Preview image bytes | files:read |
POST /files/{key}/media | Upload media the file uses | files:write |
GET /files/{key}/media/{hash} | Media asset bytes | files:read |
GET /projects/{id}/files | Files in a project | files:read |
GET /files/{key}/comments | Comments (threads and replies), oldest first | comments:read |
POST /files/{key}/comments | Post a thread or reply | comments:write |
PATCH /files/{key}/comments/{id} | Edit, resolve, react to or move a comment | comments:write |
DELETE /files/{key}/comments/{id} | Delete a comment | comments:write |
GET /files/{key}/versions | Versions, newest first | versions:read |
GET /files/{key}/versions/{id} | A version’s document snapshot | versions:read |
GET /workspaces/{id}/integrations | A workspace's integrations and connected accounts | integrations:read |
GET /workspaces/{id}/integrations/candidates | Every place for one use, across connected accounts | integrations:read |
GET /integrations/connections/{id}/resources | What a connected account holds, one level at a time | integrations:read |
GET /files/{key}/site/destinations | Where the site also goes | files:read |
POST /files/{key}/site/destinations | Add a destination | sites:publish |
POST /files/{key}/site/destinations/{id}/deploy | Send a published version to a destination | sites:publish |
GET /files/{key}/site/database | The database behind the site | files:read |
PUT /files/{key}/site/database | Attach a database | sites:publish |
DELETE /files/{key}/site/database | Detach the database | sites:publish |
GET /files/{key}/site/database/submissions | Form submissions | files:read |
GET /files/{key}/site | The file's published website | files:read |
PATCH /files/{key}/site | Roll back, take offline or rename a site | sites:publish |
POST /files/{key}/site/publish | Publish a new version of the site | sites:publish |
PUT /files/{key}/site/blobs/{hash} | Upload one of the site's files | sites:publish |
GET /templates | Templates you can use | files:read |
GET /templates/{id} | A template with its payload | files:read |
PUT /templates/{id}/preview/{file} | Store a template's hover loop or detail still | marketplace:publish |
GET /templates/{id}/media/{hash} | One of a template's own media files | files:read |
PUT /templates/{id}/media/{hash} | Upload one of a template's media files | marketplace:publish |
POST /templates | Save a template | marketplace:publish |
POST /plugins | Publish a plugin or theme pack version | marketplace:publish |
POST /packs | Publish a brush or shader pack | marketplace:publish |
GET /marketplace | Browse the public marketplace | none (public) |
GET /marketplace/{kind}/{id} | One marketplace item with its versions | none (public) |
Account
Who the token is
GET /me
The token’s user and workspaces
Scope: any token.
Response 200: Me.
Files
Files you can open, their documents, nodes and images; creating and editing them with a files:write token
GET /files
Files you can open Recent files across your workspaces, or one container. Filters combine. Sorted by last modified unless sort=name.
Scope: files:read.
| Parameter | In | Type | Description |
|---|---|---|---|
workspace | query | string | Only this workspace |
project | query | string | Only this project (and its folders) |
folder | query | string | Only this folder |
trash | query | 1 | Trashed files instead of live ones |
shared | query | 1 | Only files shared with you from other workspaces |
q | query | string | Search by name (up to 100 characters) |
sort | query | updated · name (default updated) | Order |
limit | query | integer (default 60) | Page size |
cursor | query | string | The previous page’s nextCursor |
Response 200: FileList.
POST /files
Create a file Optionally with its document. The plan’s team-workspace, page and cloud-file limits apply as in the app.
Scope: files:write.
Request body: FileCreate.
Response 201: FileCreated.
GET /files/{key}
File metadata, your role and document JSON
Scope: files:read.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
depth | query | metadata | Omit the document |
Response 200: FileDetail.
PUT /files/{key}
Replace the document Body: a Document, { document } or a .popcraft export, and may be gzipped (Content-Encoding: gzip). Requests are capped at about 4.5 MB on the wire, so upload pictures, video and fonts first (POST /files/{key}/media) and send a document that names them as media://<hash>. A live file takes the difference as one edit in its collaborative log, so people editing it see the change merge in; private (PopCorn) layers are never written. Send If-Match: <revision> to write only if the file has not changed since you read it. Needs edit access.
Scope: files:write.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
If-Match | header | string | The revision you read |
Request body: Document.
Response 200: WriteResult.
POST /files/{key}/commands
Run editing commands Runs up to 100 commands in order on the current document and saves the result as one edit (conditional on the revision they ran against). Commands that need the canvas (exports, rendering), generate media, drive the editor’s screen or ask for confirmation are refused. A batch stops at the first failure and saves nothing (422) unless keepGoing. Read-only batches need view access, others edit access.
Scope: files:write.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
If-Match | header | string | Run only if the file is still at this revision |
Request body: CommandBatch.
Response 200: CommandBatchResult.
GET /files/{key}/nodes
Nodes with their subtrees
Scope: files:read.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
ids (required) | query | string | Comma-separated node ids (≤ 200) |
depth | query | 1 | Only the nodes themselves, no descendants |
Response 200: NodeResult.
GET /files/{key}/images
Thumbnail and media assets the file references
Scope: files:read.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
Response 200: Images.
GET /files/{key}/thumbnail
Preview image bytes
Scope: files:read.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
Response 200: PNG or WebP bytes (image/*).
POST /files/{key}/media
Upload media the file uses The raw bytes of a picture, video, audio or font file, with x-media-hash set to their hash (SHA-256, the first 32 hex characters). The document, or a command such as font.add (src: "media://<hash>"), can then name them. A workspace stores the same bytes once. Needs edit access.
Scope: files:write.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
x-media-hash (required) | header | string | The bytes' hash: the first 32 hex characters of their SHA-256 |
Response 201: Stored (application/json).
GET /files/{key}/media/{hash}
Media asset bytes
Scope: files:read.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
hash (required) | path | string | From /files/{key}/images |
Response 200: The asset, with its own content type (*/*).
GET /projects/{id}/files
Files in a project Shorthand for /files?project={id}; takes the same paging parameters.
Scope: files:read.
| Parameter | In | Type | Description |
|---|---|---|---|
id (required) | path | string | Project id |
limit | query | integer (default 60) | Page size |
cursor | query | string | The previous page’s nextCursor |
Response 200: FileList.
Comments
Threads and replies on a file
GET /files/{key}/comments
Comments (threads and replies), oldest first
Scope: comments:read.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
limit | query | integer (default 500) | Page size |
cursor | query | string | The previous page’s nextCursor |
Response 200: CommentList.
POST /files/{key}/comments
Post a thread or reply
Scope: comments:write.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
Request body: CommentCreate.
Response 201: Created (application/json).
PATCH /files/{key}/comments/{id}
Edit, resolve, react to or move a comment Send only the fields you change. body is the author’s to edit; anyone who can comment may resolve, react or move.
Scope: comments:write.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
id (required) | path | string | Comment id |
Request body: CommentPatch.
Response 200: OK (application/json).
DELETE /files/{key}/comments/{id}
Delete a comment
Scope: comments:write.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
id (required) | path | string | Comment id |
Response 200: OK (application/json).
Versions
Saved versions of a file
GET /files/{key}/versions
Versions, newest first Up to 200. Auto-saved versions older than the plan’s history window are not listed; named ones always are.
Scope: versions:read.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
Response 200: VersionList.
GET /files/{key}/versions/{id}
A version’s document snapshot
Scope: versions:read.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
id (required) | path | string | Version id |
Response 200: VersionSnapshot.
Integrations
A workspace's own accounts at GitHub, Vercel, Neon and Supabase
GET /workspaces/{id}/integrations
A workspace's integrations and connected accounts Every integration, how it can be connected, and the accounts this workspace has connected. Credentials are never returned. Accounts are connected by a person in the app (the Integrations dialog), never through the API.
Scope: integrations:read.
| Parameter | In | Type | Description |
|---|---|---|---|
id (required) | path | string | Workspace id (from GET /me) |
Response 200: IntegrationList.
GET /workspaces/{id}/integrations/candidates
Every place for one use, across connected accounts Every database, repository or hosting project the workspace's connected accounts hold, as one list (each a complete target inside a connection, ready for attaching or adding). The last-used account's come first; a large account is cut short, and the list is cached for a minute.
Scope: integrations:read.
| Parameter | In | Type | Description |
|---|---|---|---|
id (required) | path | string | Workspace id (from GET /me) |
capability (required) | query | repo · deploy · database | What the place is for |
Response 200: OK (application/json).
GET /integrations/connections/{id}/resources
What a connected account holds, one level at a time A connection is an account: it holds several repositories, projects or databases. Lists the level after path (omit path for the outermost).
Scope: integrations:read.
| Parameter | In | Type | Description |
|---|---|---|---|
id (required) | path | string | Connection id |
capability (required) | query | repo · deploy · database · auth | What the place is for |
path | query | string | JSON array of the resources chosen so far: [{"id":"acme","name":"acme"}] |
Response 200: ResourceLevel.
Sites
A file published as a website: publish a version, roll back, take it offline
GET /files/{key}/site/destinations
Where the site also goes The repositories and hosting projects this file's site is sent to, with what was last sent.
Scope: files:read.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
Response 200: OK (application/json).
POST /files/{key}/site/destinations
Add a destination Choose a repository (repo) or a hosting project (deploy) inside one of the workspace's connected accounts. Every level of target is checked against the account. Or send create: true with capability (and provider or connectionId) to make a new one named after the site.
Scope: sites:publish.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
Request body: DestinationCreate.
Response 201: Added (application/json).
POST /files/{key}/site/destinations/{id}/deploy
Send a published version to a destination A repository gets one commit on its default branch (files PopCraft did not write are left alone); a hosting project gets a production deployment. Sends the version online unless version is given.
Scope: sites:publish.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
id (required) | path | string | Destination id |
Request body: object.
Response 200: OK (application/json).
GET /files/{key}/site/database
The database behind the site Which database of the user's own the site keeps its form submissions in. The connection string is never returned.
Scope: files:read.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
Response 200: SiteDatabase.
PUT /files/{key}/site/database
Attach a database Use a database inside one of the workspace's connected accounts (target: the levels its integration lists, e.g. organization, project, database for Neon; organization, project for Supabase). Or send create: true (with provider or connectionId, else the account last used) to make a new one named after the site. The site's tables are made there if they are not.
Scope: sites:publish.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
Request body: object.
Response 200: SiteDatabase.
DELETE /files/{key}/site/database
Detach the database The site stops keeping submissions. What is in the database stays.
Scope: sites:publish.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
Response 200: SiteDatabase.
GET /files/{key}/site/database/submissions
Form submissions What visitors sent through the site's forms, newest first, read from the attached database.
Scope: files:read.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
form | query | string | Only this form (its name) |
limit | query | integer (default 100) | How many |
Response 200: OK (application/json).
GET /files/{key}/site
The file's published website Its address, the version online and the versions so far (newest first). site is null until the file is published.
Scope: files:read.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
Response 200: Site.
PATCH /files/{key}/site
Roll back, take offline or rename a site currentVersion serves that version (an earlier one is a rollback); null takes the site offline. slug changes its address.
Scope: sites:publish.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
Request body: SitePatch.
Response 200: Site.
POST /files/{key}/site/publish
Publish a new version of the site Two calls. First send the manifest (every file's path, SHA-256 and size): the reply lists the hashes the server does not have (missing). Upload those with PUT /files/{key}/site/blobs/{hash}, then send the same manifest with commit: true: that makes the version and puts it online (201, with version, url and versionUrl). The files are the ones a static website export writes (popcraft site publish builds and uploads them in one go).
Scope: sites:publish.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
Request body: SiteManifest.
Response 201: SitePublished.
PUT /files/{key}/site/blobs/{hash}
Upload one of the site's files The raw bytes of a file the publish call said was missing. path says what kind of file it is; the bytes must hash to {hash}.
Scope: sites:publish.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | File key (the id in /pop/) |
hash (required) | path | string | SHA-256 of the bytes, hex |
path (required) | query | string | The file's path in the site (index.html, assets/photo.png) |
Response 201: Stored (application/json).
Marketplace
Public plugins, theme packs and libraries (no token needed)
GET /marketplace
Browse the public marketplace
Scope: none (public).
| Parameter | In | Type | Description |
|---|---|---|---|
q | query | string | Search name, description and author |
kind | query | all · plugin · theme · template · library · brush · shader (default all) | One kind |
category | query | productivity · design-systems · ui-kits · icons · themes · ai · import-export · prototyping · motion · widgets · accessibility · data · fun | One topic (plugins, libraries, brush and shader packs) |
group | query | print · comic · social · slides · web · app · game · email · motion · board | One template group (templates only), the same groups New file uses |
limit | query | integer | Page size (default 48). Without limit or cursor, the whole listing in one answer |
cursor | query | string | The previous page's nextCursor |
Response 200: MarketplaceList.
GET /marketplace/{kind}/{id}
One marketplace item with its versions
Scope: none (public).
| Parameter | In | Type | Description |
|---|---|---|---|
kind (required) | path | plugin · theme · template · library · brush · shader | |
id (required) | path | string | Plugin, library or template id |
Response 200: MarketplaceDetail.
Publishing
Publish marketplace items from CI with a marketplace:publish token
POST /templates
Save a template Body: { meta: { localId, name, kind, category, … }, payload: { mode, nodes, variants, … } }. A localId seen before updates that template. Starts private.
Scope: marketplace:publish.
Request body: object.
Response 201: Created (application/json).
POST /plugins
Publish a plugin or theme pack version Body: a .zip package or a JSON bundle { manifest, main?, ui?, themes? }, as the editor uploads it. The version goes into review; a version that is not greater than the latest returns 409.
Scope: marketplace:publish.
Request body: object.
Response 201: Published (pending review) (application/json).
POST /packs
Publish a brush or shader pack Body: { meta: { localId, kind, name, … }, payload }. A localId seen before updates that pack. New packs start private: the owner lists them from the editor.
Scope: marketplace:publish.
Request body: object.
Response 201: Created (application/json).
Commands
What POST /files/{key}/commands runs: name a step by its id or its agent tool name. Commands that need the canvas, generate media, drive the editor’s screen or ask for confirmation are not here; the CLI runs the canvas ones in a headless editor. popcraft commands <id> prints a command’s parameters.
| Command | Tool name | What it does |
|---|---|---|
code.editModule | edit_code | Edit code module |
code.getModules | get_code | Get code modules |
component.create | create_component | Create component |
component.createInstance | create_instance | Place instance |
component.setCode | set_component_code | Draw component with code |
data.editCollection | edit_collection | Edit collection |
data.editRecords | edit_records | Edit records |
data.getRecords | get_records | Get records |
design.readReference | read_design_reference | Read design reference |
doc.outline | get_document_outline | Document outline |
font.add | add_font | Add font to file |
font.list | list_fonts | List fonts |
font.remove | remove_font | Remove font from file |
meta.notify | notify | Notify |
motion.applyPreset | apply_motion_preset | Apply a motion preset |
motion.createComponent | create_motion_component | Create motion component |
motion.cutToBeat | cut_to_beat | Cut scenes to the beat |
motion.edit3D | edit_3d_scene | Edit a 3D scene |
motion.editBehaviour | edit_behaviours | Edit a behaviour |
motion.editComponentProperty | edit_component_property | Edit a component property |
motion.editComposition | edit_composition | Edit a composition |
motion.editFrameAudio | edit_frame_audio | Edit a frame's audio |
motion.editStateMachine | edit_state_machine | Edit a state machine |
motion.editTextAnimation | edit_text_animation | Edit text animation |
motion.editVideo | edit_video_clip | Edit a video clip |
motion.getAnimation | get_animation | Read a layer's animation |
motion.getCompositions | get_compositions | Read compositions |
motion.getStateMachine | get_state_machine | Read a state machine |
motion.newComposition | create_composition | New composition from frames |
motion.setKeys | set_keyframes | Set keyframes |
motion.setLayerTiming | set_layer_timing | Set layer timing |
motion.setPlayback | set_instance_playback | Set instance playback |
motion.setShaderFill | set_shader_fill | Set a shader fill |
motion.setTimeline | set_timeline | Set a timeline |
motion.stagger | stagger_motion | Stagger animations |
node.align | align | Align layers |
node.applyAutoLayout | apply_auto_layout | Apply auto layout |
node.bindField | bind_field | Bind to a field |
node.create | create_node | Create layer |
node.delete | delete_nodes | Delete layers |
node.distribute | distribute | Distribute layers |
node.duplicate | duplicate_nodes | Duplicate layers |
node.find | find_nodes | Find layers |
node.flip | flip | Flip layers |
node.get | get_node | Read layer properties |
node.group | group | Group layers |
node.importSvg | import_svg | Import SVG |
node.measure | measure | Measure layers |
node.move | move_nodes | Move layers |
node.order | order | Reorder layers |
node.rename | rename_nodes | Rename layers |
node.reparent | reparent | Reparent layers |
node.resize | resize_nodes | Resize layers |
node.rotate | rotate | Rotate layers |
node.setControl | set_control | Set form control |
node.setLock | set_lock | Lock layers |
node.setRecord | set_record | Show a record |
node.setRepeat | set_repeat | Repeat for each record |
node.setResponsive | set_responsive | Set breakpoint overrides |
node.setSemantics | set_semantics | Set web semantics |
node.setVisibility | set_visibility | Show or hide layers |
node.ungroup | ungroup | Ungroup layers |
node.update | update_nodes | Update layers |
page.create | create_page | Create page |
page.list | list_pages | List pages |
page.rename | rename_page | Rename page |
page.setCurrent | set_current_page | Switch page |
paint.replaceColor | replace_color | Replace color |
paint.setEffects | set_effects | Set effects |
paint.setFills | set_fills | Set fills |
paint.setStrokes | set_strokes | Set strokes |
prototype.edit | edit_prototype | Edit prototype |
shader.editGraph | edit_shader_graph | Edit a shader graph |
show.setAdvance | set_show_advance | Set how the show advances |
site.getBreakpoints | get_breakpoints | Get breakpoints |
site.getEnvironment | get_site_environment | Get site environment |
site.setBreakpoints | set_breakpoints | Set breakpoints |
site.setEnvironment | set_site_environment | Set site environment |
site.setGpuTransitions | set_gpu_transitions | Draw 3D transitions with WebGPU |
site.setRoute | set_route | Set page address |
site.setShareImage | set_share_image | Set share image |
style.apply | set_node_style | Apply style |
style.create | create_style | Create style |
style.list | get_styles | List styles |
style.setVariable | set_variable | Set variable |
text.detach | detach_text | Detach text |
text.flowIntoShape | flow_text_into_shape | Flow text into shape |
text.searchFonts | search_fonts | Search fonts |
text.set | set_text | Set text |
text.setEffect | set_text_effect | Set text effect |
text.setFit | set_text_fit | Auto-size text |
text.setPath | set_text_path | Set text path |
text.setTypography | set_typography | Set typography |
vector.setMaskType | set_mask_type | Mask type |
Schemas
Object shapes referenced above. null means the field may be null.
Error
| Field | Type | Description |
|---|---|---|
error | object |
User
| Field | Type | Description |
|---|---|---|
id | string | |
email | string | |
name | string |
Author
A person as others see them: never the email.
| Field | Type | Description |
|---|---|---|
id | string | |
name | string | |
image (optional) | `string | null` |
Workspace
| Field | Type | Description |
|---|---|---|
id | string | |
name | string | |
personal | boolean | The user’s own workspace (one per account) |
tier (optional) | string | Plan tier, when plans are on |
pastDue (optional) | boolean |
Me
File
| Field | Type | Description |
|---|---|---|
key | string | |
name | string | |
workspaceId | string | |
projectId (optional) | `string | null` |
folderId (optional) | `string | null` |
updatedAt | string (date-time) | |
createdAt (optional) | string (date-time) | |
trashedAt (optional) | `string | null` (date-time) |
thumbnailUrl (optional) | `string | null` |
version (optional) | integer | Snapshot version; increases on every save |
FileCounts
How many files match the query in each container (before paging).
| Field | Type | Description |
|---|---|---|
total | integer | |
workspaces (optional) | object | |
projects (optional) | object | |
folders (optional) | object |
FileList
| Field | Type | Description |
|---|---|---|
files | File[] | |
counts | FileCounts | |
nextCursor | `string | null` |
FileDetail
| Field | Type | Description |
|---|---|---|
file | object | |
role | owner · editor · commenter · viewer | Your role on the file |
document (optional) | Document | The current document, live edits included. Omitted with ?depth=metadata; null before the file has one |
Document
The document JSON: id, name, pages (page node ids, in order), nodes (a map of node id → node; pages are PAGE nodes), styles and variables. See the file-format docs.
| Field | Type | Description |
|---|---|---|
id (optional) | string | |
name (optional) | string | |
pages (optional) | string[] | |
nodes (optional) | object |
Node
A layer. type is FRAME, RECTANGLE, ELLIPSE, TEXT, VECTOR, IMAGE, GROUP, COMPONENT, INSTANCE, … Geometry is in the parent’s coordinate space.
| Field | Type | Description |
|---|---|---|
id | string | |
type | string | |
name | string | |
parentId (optional) | `string | null` |
childIds (optional) | string[] | |
x (optional) | number | |
y (optional) | number | |
width (optional) | number | |
height (optional) | number | |
rotation (optional) | number | |
visible (optional) | boolean | |
locked (optional) | boolean | |
opacity (optional) | number |
NodeResult
| Field | Type | Description |
|---|---|---|
nodes | object | Keyed by requested id; null when the id does not exist |
Images
| Field | Type | Description |
|---|---|---|
thumbnail | `string | null` (uri) |
media | object[] |
Comment
| Field | Type | Description |
|---|---|---|
id | string | |
parentId | `string | null` |
authorId | string | |
author (optional) | undefined | |
body | string | |
pageId (optional) | `string | null` |
x (optional) | `number | null` |
y (optional) | `number | null` |
nodeId (optional) | `string | null` |
offsetX (optional) | `number | null` |
offsetY (optional) | `number | null` |
reactions | object | Emoji → user ids |
resolvedAt (optional) | `string | null` (date-time) |
resolvedBy (optional) | `string | null` |
createdAt | string (date-time) | |
updatedAt | string (date-time) |
CommentList
| Field | Type | Description |
|---|---|---|
comments | Comment[] | |
nextCursor | `string | null` |
CommentCreate
| Field | Type | Description |
|---|---|---|
body | string | Text; mention people as @[Name](userId) |
parentId (optional) | string | Reply to this thread |
x (optional) | number | |
y (optional) | number | |
pageId (optional) | string | |
nodeId (optional) | string | Pin to a layer (with offsetX/offsetY inside it) |
offsetX (optional) | number | |
offsetY (optional) | number |
CommentPatch
| Field | Type | Description |
|---|---|---|
body (optional) | string | New text (author only) |
resolved (optional) | boolean | Resolve or reopen the thread |
reaction (optional) | string | Toggle an emoji reaction for the caller |
x (optional) | number | |
y (optional) | number | |
pageId (optional) | string | |
nodeId (optional) | `string | null` |
offsetX (optional) | number | |
offsetY (optional) | number |
Version
| Field | Type | Description |
|---|---|---|
id | string | |
kind | auto · named | |
name (optional) | `string | null` |
description (optional) | `string | null` |
createdAt | string (date-time) | |
author (optional) | undefined |
VersionList
| Field | Type | Description |
|---|---|---|
versions | Version[] |
Integration
| Field | Type | Description |
|---|---|---|
manifest | object | |
available | string[] | The ways it can be connected on this server |
connections | object[] |
Resource
| Field | Type | Description |
|---|---|---|
id | string | |
name | string | |
detail (optional) | string |
Candidate
| Field | Type | Description |
|---|---|---|
connectionId | string | |
provider | string | |
account | string | |
target | Resource[] |
ResourceLevel
| Field | Type | Description |
|---|---|---|
level | undefined | The level these are: owner, repo, team, project. null when the path is complete |
resources | Resource[] | |
canCreate | boolean |
DestinationDeploy
| Field | Type | Description |
|---|---|---|
version | integer | |
at | string (date-time) | |
url | string | |
ref | string | A commit sha or a deployment id |
status | ready · building · failed | |
error (optional) | string |
Destination
| Field | Type | Description |
|---|---|---|
id | string | |
capability | repo · deploy | |
target | object[] | |
lastDeploy | undefined | |
createdAt (optional) | string (date-time) | |
connection | object |
DestinationCreate
| Field | Type | Description |
|---|---|---|
connectionId (optional) | string | |
capability | repo · deploy | |
target (optional) | object[] | One resource per level, outermost first: [owner, repository] or [team, project]. Leave out with create |
create (optional) | true | Make a new one named after the site instead of choosing target |
provider (optional) | string | With create: whose account (github, vercel), when connectionId is not given |
SiteDatabase
| Field | Type | Description |
|---|---|---|
database | undefined | null when the site has no database |
Submission
| Field | Type | Description |
|---|---|---|
id | string | |
form | string | The form's name |
data | object | The fields as sent |
createdAt | string (date-time) |
IntegrationList
| Field | Type | Description |
|---|---|---|
integrations | Integration[] | |
manages | boolean | Whether you can connect and disconnect accounts (workspace owners and admins) |
SiteVersion
| Field | Type | Description |
|---|---|---|
version | integer | |
pages | integer | |
bytes | integer | |
createdAt | string (date-time) | |
url | string |
Site
| Field | Type | Description |
|---|---|---|
configured | boolean | Whether this server publishes websites at all |
host (optional) | string | The domain sites are served under |
site | undefined | null until the file is published |
SitePatch
| Field | Type | Description |
|---|---|---|
currentVersion (optional) | `integer | null` |
slug (optional) | string | A new address: 3 to 40 letters, digits and dashes |
SiteManifest
| Field | Type | Description |
|---|---|---|
slug (optional) | string | The address for a first publish (default: from the file's name) |
commit (optional) | boolean | Make the version once every file is uploaded |
files | object | Every file of the site by its path (index.html is required) |
SitePublished
| Field | Type | Description |
|---|---|---|
slug | string | |
missing (optional) | string[] | |
version (optional) | integer | |
url (optional) | string | |
versionUrl (optional) | string |
VersionSnapshot
| Field | Type | Description |
|---|---|---|
document | Document |
MarketplaceItem
| Field | Type | Description |
|---|---|---|
kind | plugin · theme · template · library · brush · shader | |
id | string | |
name | string | |
description (optional) | `string | null` |
author (optional) | `string | null` |
version | string | Plugins: semver. Libraries: the version number |
installs | integer | |
updatedAt | string (date-time) | |
permissions | string[] | Plugins: permissions the latest approved version asks for |
themes | integer | Theme packs: how many themes |
counts (optional) | object | |
icon (optional) | `string | null` |
screenshots | string[] | |
category (optional) | productivity · design-systems · ui-kits · icons · themes · ai · import-export · prototyping · motion · widgets · accessibility · data · fun · null | |
tags | string[] | |
homepage (optional) | `string | null` |
MarketplaceList
| Field | Type | Description |
|---|---|---|
items | MarketplaceItem[] | |
nextCursor (optional) | `string | null` |
counts (optional) | object | Per-kind totals for the search and topic/group, whatever kind is, plus all |
Template
| Field | Type | Description |
|---|---|---|
id | string | |
name | string | |
description (optional) | `string | null` |
kind | CANVAS · PRINT · SOCIAL · PRESENTATION · WEB · APP · BOARD · EMAIL | |
category | string | |
tags | string[] | |
sizes (optional) | string[] | |
fonts (optional) | string[] | |
media (optional) | string[] | |
thumbnail (optional) | `string | null` |
workspaceId (optional) | `string | null` |
ownerId (optional) | string | |
public | boolean | |
installs (optional) | integer | |
source (optional) | workspace · marketplace | |
createdAt | string (date-time) | |
updatedAt | string (date-time) |
TemplateList
| Field | Type | Description |
|---|---|---|
templates | Template[] |
TemplateDetail
| Field | Type | Description |
|---|---|---|
template | Template | |
payload | object |
FileCreate
| Field | Type | Description |
|---|---|---|
name (optional) | string | Defaults to the document’s name, else Untitled |
workspaceId (optional) | string | Defaults to your personal workspace |
projectId (optional) | string | |
folderId (optional) | string | A folder of projectId |
document (optional) | Document | The initial document (or a .popcraft export); the file starts empty without one |
FileCreated
| Field | Type | Description |
|---|---|---|
key | string | |
revision | string |
WriteResult
| Field | Type | Description |
|---|---|---|
revision | string | The file’s revision after the write |
live | boolean | Written as one edit to the live log (open sessions merged it) rather than as a new snapshot |
changed | boolean | False when the document already matched |
CommandStep
| Field | Type | Description |
|---|---|---|
command | string | Command id (node.create), agent tool name (create_node) or plugin method (createNode); see Commands |
params (optional) | object | The command’s parameters (popcraft commands <id> prints them) |
CommandBatch
| Field | Type | Description |
|---|---|---|
commands | CommandStep[] | |
page (optional) | string | Page id or name the commands act on (default: the first page) |
selection (optional) | string[] | Node ids selected when the batch starts |
keepGoing (optional) | boolean | Run every step even after one fails, and save what succeeded |
dryRun (optional) | boolean | Run the batch and return the results without saving |
CommandBatchResult
| Field | Type | Description |
|---|---|---|
results | object[] | |
saved | boolean | The document changed and was saved |
revision | string | |
notices (optional) | object[] |
MarketplaceDetail
Everything in MarketplaceItem, plus versions: a list of { version, notes, createdAt }.