Developers
Designs endpoints
Agent API v1 endpoints for designs — list, create, read, rename, duplicate, archive and delete; load documents, commit transactions, describe, preview; versions, shares, comments and exports.
On this page
- Designs
- List designs
- Create a design
- Get a design
- Rename or move a design
- Duplicate a design
- Move to trash
- Restore from trash
- Delete permanently
- Document & transactions
- Load the document
- Commit a transaction
- List transactions since a seq
- Describe a page
- Render a preview
- Versions, shares, comments & exports
- List versions
- Save a named version
- Restore a version
- List share links
- Create or update a share link
- List comments
- Add a comment or reply
- Request an export
- Get an export
All paths are relative to the base URL. Every endpoint lists the backend function it calls and the scope it needs.
Designs#
Create, find, rename, organize and delete designs.
List designs#
/designsDesigns in a workspace, most recently updated first.
Parameters
workspaceIdstringQueryDefaults to the key's workspace.
folderIdstringQueryOnly designs in this folder.
kindDesignKindQueryFilter by design kind, e.g. presentation.
archivedbooleanQueryList the trash instead. Default false.
limitintegerQuery1–100, default 25.
cursorstringQuerynextCursor from the previous page.
curl "https://api.desyn.app/api/v1/designs" \
-H "Authorization: Bearer $DESYN_API_KEY"{
"items": [
{
"id": "k17c2v9m3n8q4r5s6t7u8w9x0y",
"name": "Spring launch / Instagram",
"kind": "social-post",
"workspaceId": "j57a1b2c3d4e5f6g7h8i9j0k1m",
"folderId": null,
"seq": 128,
"pageCount": 3,
"thumbnailUrl": "https://files.desyn.app/thumbs/k17c2v9m3n8q4r5s6t7u8w9x0y/128.webp?sig=…",
"archived": false,
"updatedAt": 1792483200000
}
],
"nextCursor": "eyJvZmZzZXQiOjI1fQ"
}Create a design#
/designsCreates an empty design with one page of the given size. To start from a template use Instantiate a template; to have the AI build it, create the design and then start an agent run.
Parameters
namestringBodyRequiredDisplay name.
kindDesignKindBodyRequiredOne of the design kinds, or custom.
widthnumberBodyRequiredFirst page width in design pixels.
heightnumberBodyRequiredFirst page height in design pixels.
unit"px" | "mm" | "in" | "pt"BodyDisplay unit of the page. Default px.
folderIdstringBodyFolder to create it in.
brandKitIdstringBodyBrand kit the design follows.
curl -X POST "https://api.desyn.app/api/v1/designs" \
-H "Authorization: Bearer $DESYN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Spring launch / Instagram",
"kind": "social-post",
"width": 1080,
"height": 1350
}'{
"id": "k17c2v9m3n8q4r5s6t7u8w9x0y",
"name": "Spring launch / Instagram",
"kind": "social-post",
"workspaceId": "j57a1b2c3d4e5f6g7h8i9j0k1m",
"folderId": null,
"seq": 1,
"pageCount": 1,
"thumbnailUrl": "https://files.desyn.app/thumbs/k17c2v9m3n8q4r5s6t7u8w9x0y/128.webp?sig=…",
"archived": false,
"updatedAt": 1792483200000,
"rootPageId": "p8k2m4n6q8r0"
}Get a design#
/designs/{designId}Metadata of one design. Use Load the document for its content.
Parameters
designIdstringPathRequiredDesign id.
curl "https://api.desyn.app/api/v1/designs/$DESIGN_ID" \
-H "Authorization: Bearer $DESYN_API_KEY"{
"id": "k17c2v9m3n8q4r5s6t7u8w9x0y",
"name": "Spring launch / Instagram",
"kind": "social-post",
"workspaceId": "j57a1b2c3d4e5f6g7h8i9j0k1m",
"folderId": null,
"seq": 128,
"pageCount": 3,
"thumbnailUrl": "https://files.desyn.app/thumbs/k17c2v9m3n8q4r5s6t7u8w9x0y/128.webp?sig=…",
"archived": false,
"updatedAt": 1792483200000
}Rename or move a design#
/designs/{designId}Change the name and/or folder. Send only the fields you change; folderId: null moves it to the workspace root.
Parameters
designIdstringPathRequiredDesign id.
namestringBodyNew name.
folderIdstring | nullBodyTarget folder.
curl -X PATCH "https://api.desyn.app/api/v1/designs/$DESIGN_ID" \
-H "Authorization: Bearer $DESYN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Spring launch / Instagram (final)"
}'{
"id": "k17c2v9m3n8q4r5s6t7u8w9x0y",
"name": "Spring launch / Instagram (final)",
"kind": "social-post",
"workspaceId": "j57a1b2c3d4e5f6g7h8i9j0k1m",
"folderId": null,
"seq": 128,
"pageCount": 3,
"thumbnailUrl": "https://files.desyn.app/thumbs/k17c2v9m3n8q4r5s6t7u8w9x0y/128.webp?sig=…",
"archived": false,
"updatedAt": 1792483200000
}Duplicate a design#
/designs/{designId}/duplicateCopies the current state (not the history) into a new design in the same folder.
Parameters
designIdstringPathRequiredDesign to copy.
namestringBodyName of the copy. Default: original name + " copy".
curl -X POST "https://api.desyn.app/api/v1/designs/$DESIGN_ID/duplicate" \
-H "Authorization: Bearer $DESYN_API_KEY"{
"id": "k19d4w0n5p7r9t1v3x5z7b9d1f",
"name": "Spring launch / Instagram copy",
"kind": "social-post",
"workspaceId": "j57a1b2c3d4e5f6g7h8i9j0k1m",
"folderId": null,
"seq": 1,
"pageCount": 3,
"thumbnailUrl": "https://files.desyn.app/thumbs/k17c2v9m3n8q4r5s6t7u8w9x0y/128.webp?sig=…",
"archived": false,
"updatedAt": 1792483200000
}Move to trash#
/designs/{designId}/archiveArchives the design. It disappears from lists but can be restored.
Parameters
designIdstringPathRequiredDesign id.
curl -X POST "https://api.desyn.app/api/v1/designs/$DESIGN_ID/archive" \
-H "Authorization: Bearer $DESYN_API_KEY"{
"id": "k17c2v9m3n8q4r5s6t7u8w9x0y",
"name": "Spring launch / Instagram",
"kind": "social-post",
"workspaceId": "j57a1b2c3d4e5f6g7h8i9j0k1m",
"folderId": null,
"seq": 128,
"pageCount": 3,
"thumbnailUrl": "https://files.desyn.app/thumbs/k17c2v9m3n8q4r5s6t7u8w9x0y/128.webp?sig=…",
"archived": true,
"updatedAt": 1792483200000
}Restore from trash#
/designs/{designId}/restoreUndo an archive.
Parameters
designIdstringPathRequiredDesign id.
curl -X POST "https://api.desyn.app/api/v1/designs/$DESIGN_ID/restore" \
-H "Authorization: Bearer $DESYN_API_KEY"{
"id": "k17c2v9m3n8q4r5s6t7u8w9x0y",
"name": "Spring launch / Instagram",
"kind": "social-post",
"workspaceId": "j57a1b2c3d4e5f6g7h8i9j0k1m",
"folderId": null,
"seq": 128,
"pageCount": 3,
"thumbnailUrl": "https://files.desyn.app/thumbs/k17c2v9m3n8q4r5s6t7u8w9x0y/128.webp?sig=…",
"archived": false,
"updatedAt": 1792483200000
}Delete permanently#
/designs/{designId}Deletes the design, its history, versions, comments and shares. Assets that no other design references are removed by the orphan cleanup job. This cannot be undone.
Parameters
designIdstringPathRequiredDesign id.
curl -X DELETE "https://api.desyn.app/api/v1/designs/$DESIGN_ID" \
-H "Authorization: Bearer $DESYN_API_KEY"{
"deleted": true
}Document & transactions#
Read a design's full document, commit transactions and follow changes. These endpoints speak the document model and operations exactly.
Load the document#
/designs/{designId}/documentReturns the full Design (see the document model) and the seq it reflects. Asset urls are filled with signed URLs valid for one hour. Large designs are assembled from 500-node chunks on the server.
Parameters
designIdstringPathRequiredDesign id.
pageIdstringQueryOnly this page's subtree (plus root).
curl "https://api.desyn.app/api/v1/designs/$DESIGN_ID/document" \
-H "Authorization: Bearer $DESYN_API_KEY"{
"seq": 128,
"design": {
"schema": 1,
"id": "d3k5m7p9r1t3",
"name": "Spring launch / Instagram",
"kind": "social-post",
"nodes": {
"root": {
"id": "root",
"type": "root",
"name": "Root",
"parent": null,
"children": [
"p8k2m4n6q8r0"
],
"…": "…"
},
"p8k2m4n6q8r0": {
"id": "p8k2m4n6q8r0",
"type": "page",
"name": "Page 1",
"width": 1080,
"height": 1350,
"…": "…"
}
},
"assets": {},
"styles": {
"colors": {},
"text": {},
"effects": {},
"variables": {}
},
"meta": {
"createdAt": 1792483200000
}
}
}Commit a transaction#
/designs/{designId}/transactionsApplies a Transaction to the current server state. Ops that no longer apply are dropped and reported, never fatal. Idempotent on tx.id: retrying the same transaction returns the original result. Collaborators see the change live and it is one undo step in their history.
Parameters
designIdstringPathRequiredDesign id.
baseSeqintegerBodyRequiredThe seq your view of the design is based on.
txTransactionBodyRequiredUse source: "ai" or "workflow" when an agent made the change.
curl -X POST "https://api.desyn.app/api/v1/designs/$DESIGN_ID/transactions" \
-H "Authorization: Bearer $DESYN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"baseSeq": 128,
"tx": {
"id": "tx4m8q2w6e0r",
"label": "Make the headline warmer",
"source": "ai",
"actor": {
"agent": "my-agent"
},
"ts": 1792483260000,
"ops": [
{
"op": "patch",
"id": "h1a2b3c4d5e6",
"path": [
"style",
"fills",
0,
"color"
],
"value": "#ffb02e"
},
{
"op": "update",
"id": "h1a2b3c4d5e6",
"set": {
"name": "Headline"
}
}
]
}
}'{
"seq": 129,
"applied": [
{
"op": "patch",
"id": "h1a2b3c4d5e6",
"path": [
"style",
"fills",
0,
"color"
],
"value": "#ffb02e"
},
{
"op": "update",
"id": "h1a2b3c4d5e6",
"set": {
"name": "Headline"
}
}
],
"dropped": []
}List transactions since a seq#
/designs/{designId}/transactionsAccepted transactions after since, in order. Poll it to follow a design, or use the reactive Convex query directly from a Convex client. If the gap is too large, reload is true and you should load the document again.
Parameters
designIdstringPathRequiredDesign id.
sinceintegerQueryRequiredReturn transactions with seq > since.
limitintegerQuery1–500, default 100.
curl "https://api.desyn.app/api/v1/designs/$DESIGN_ID/transactions" \
-H "Authorization: Bearer $DESYN_API_KEY"{
"reload": false,
"items": [
{
"seq": 129,
"tx": {
"id": "tx4m8q2w6e0r",
"label": "Make the headline warmer",
"source": "ai",
"ops": [
"…"
]
},
"actor": {
"agent": "my-agent"
},
"ts": 1792483260412
}
]
}Describe a page#
/designs/{designId}/describeThe semantic description the AI reads: tree in page coordinates, palette, fonts, typographic scale, alignment grid, hierarchy and lint issues. See Describe.
Parameters
designIdstringPathRequiredDesign id.
pageIdstringQueryDefaults to the first page.
selectionstringQueryComma-separated node ids to mark as selected.
maxDepthintegerQueryLimit tree depth.
curl "https://api.desyn.app/api/v1/designs/$DESIGN_ID/describe" \
-H "Authorization: Bearer $DESYN_API_KEY"{
"design": {
"id": "d3k5m7p9r1t3",
"name": "Spring launch / Instagram",
"kind": "social-post",
"pageCount": 3
},
"page": {
"id": "p8k2m4n6q8r0",
"index": 0,
"width": 1080,
"height": 1350,
"unit": "px",
"background": "solid #0a0a0a"
},
"selection": [],
"tree": [
"…"
],
"palette": [
{
"color": "#0a0a0a",
"share": 0.62
},
{
"color": "#ffb02e",
"share": 0.14
}
],
"issues": [
{
"severity": "warn",
"code": "low-contrast",
"ids": [
"c7d8e9f0a1b2"
],
"message": "Caption contrast is 2.8:1 (needs 4.5:1)."
}
],
"…": "…"
}Render a preview#
/designs/{designId}/previewRenders one page (or a region of it) to PNG or WebP synchronously and returns the image bytes. For full-quality files and every other format, use Request an export.
Parameters
designIdstringPathRequiredDesign id.
pageIdstringBodyDefaults to the first page.
region{ x, y, w, h }BodyCrop in page coordinates.
scalenumberBody0.1–2, default 1.
format"png" | "webp"BodyDefault png.
curl -X POST "https://api.desyn.app/api/v1/designs/$DESIGN_ID/preview" \
-H "Authorization: Bearer $DESYN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"pageId": "p8k2m4n6q8r0",
"scale": 0.5,
"format": "webp"
}' \
--output preview.webp<binary image/webp>Versions, shares, comments & exports#
Everything around a design that is not the document itself.
List versions#
/designs/{designId}/versionsNamed versions and automatic snapshots, newest first. History older than your plan's retention is not returned.
Parameters
designIdstringPathRequiredDesign id.
curl "https://api.desyn.app/api/v1/designs/$DESIGN_ID/versions" \
-H "Authorization: Bearer $DESYN_API_KEY"{
"items": [
{
"id": "v0a1b2c3d4e5",
"name": "Sent to client",
"seq": 96,
"auto": false,
"createdBy": "Ada Park",
"createdAt": 1792396800000
}
]
}Save a named version#
/designs/{designId}/versionsPins the current state under a name.
Parameters
designIdstringPathRequiredDesign id.
namestringBodyRequiredVersion name.
curl -X POST "https://api.desyn.app/api/v1/designs/$DESIGN_ID/versions" \
-H "Authorization: Bearer $DESYN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Before AI restyle"
}'{
"id": "v1b2c3d4e5f6",
"name": "Before AI restyle",
"seq": 129,
"auto": false,
"createdAt": 1792483300000
}Restore a version#
/designs/{designId}/versions/{versionId}/restoreRestores the design to that version by committing one transaction, so the restore itself is undoable and appears in history.
Parameters
designIdstringPathRequiredDesign id.
versionIdstringPathRequiredVersion id.
curl -X POST "https://api.desyn.app/api/v1/designs/$DESIGN_ID/versions/$VERSION_ID/restore" \
-H "Authorization: Bearer $DESYN_API_KEY"{
"seq": 130
}List share links#
/designs/{designId}/sharesActive share links of a design.
Parameters
designIdstringPathRequiredDesign id.
curl "https://api.desyn.app/api/v1/designs/$DESIGN_ID/shares" \
-H "Authorization: Bearer $DESYN_API_KEY"{
"items": [
{
"token": "s_9f8e7d6c5b4a",
"permission": "view",
"url": "https://app.desyn.app/share/s_9f8e7d6c5b4a",
"hasPassword": false,
"expiresAt": null
}
]
}Create or update a share link#
/designs/{designId}/sharesCreates a link, or updates the one identified by token. Send permission: "none" to revoke it. Edit links require the share.editLink feature.
Parameters
designIdstringPathRequiredDesign id.
tokenstringBodyExisting link to update.
permission"view" | "comment" | "edit" | "none"BodyRequiredWhat visitors can do.
passwordstring | nullBodyOptional password.
expiresAtnumber | nullBodyExpiry as ms epoch.
curl -X POST "https://api.desyn.app/api/v1/designs/$DESIGN_ID/shares" \
-H "Authorization: Bearer $DESYN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"permission": "view",
"expiresAt": 1795075200000
}'{
"token": "s_9f8e7d6c5b4a",
"permission": "view",
"url": "https://app.desyn.app/share/s_9f8e7d6c5b4a",
"hasPassword": false,
"expiresAt": 1795075200000
}List comments#
/designs/{designId}/commentsComment threads, pinned to a page position or to a layer.
Parameters
designIdstringPathRequiredDesign id.
resolvedbooleanQueryInclude resolved threads. Default false.
curl "https://api.desyn.app/api/v1/designs/$DESIGN_ID/comments" \
-H "Authorization: Bearer $DESYN_API_KEY"{
"items": [
{
"id": "c1d2e3f4a5b6",
"pageId": "p8k2m4n6q8r0",
"nodeId": "h1a2b3c4d5e6",
"x": 540,
"y": 220,
"body": "Can the headline be one line?",
"author": "Ada Park",
"resolved": false,
"replies": [],
"createdAt": 1792483400000
}
]
}Add a comment or reply#
/designs/{designId}/commentsStart a thread on a page position or a layer, or reply with parentId. @name mentions notify workspace members.
Parameters
designIdstringPathRequiredDesign id.
bodystringBodyRequiredComment text (plain text with @mentions).
pageIdstringBodyPage for a new thread.
nodeIdstringBodyPin to a layer.
xnumberBodyPage x of the pin.
ynumberBodyPage y of the pin.
parentIdstringBodyReply to this thread.
curl -X POST "https://api.desyn.app/api/v1/designs/$DESIGN_ID/comments" \
-H "Authorization: Bearer $DESYN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"pageId": "p8k2m4n6q8r0",
"nodeId": "h1a2b3c4d5e6",
"body": "Shortened to one line in v3."
}'{
"id": "c2e3f4a5b6c7",
"body": "Shortened to one line in v3.",
"resolved": false,
"createdAt": 1792483500000
}Request an export#
/designs/{designId}/exportsQueues an export job on the render worker. Poll Get an export until status is done, then download url. Formats are gated by plan (export.* features).
Parameters
designIdstringPathRequiredDesign id.
format"png" | "jpeg" | "webp" | "svg" | "pdf" | "pptx" | "gif" | "mp4"BodyRequiredOutput format.
pageIdsstring[] | "all"BodyPages to export. Default: all pages.
scalenumberBodyRaster scale factor, default 1.
qualitynumberBody0–100 for JPEG/WebP.
backgroundColor | "transparent"BodyOverride the page background (PNG/WebP).
pdf{ bleed, cropMarks, cmyk }BodyPrint options for PDF.
curl -X POST "https://api.desyn.app/api/v1/designs/$DESIGN_ID/exports" \
-H "Authorization: Bearer $DESYN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"format": "pdf",
"pageIds": "all",
"pdf": {
"bleed": true,
"cropMarks": true,
"cmyk": false
}
}'{
"exportId": "e5f6a7b8c9d0",
"status": "queued"
}Get an export#
/exports/{exportId}Status of an export job. url is a signed download link valid for one hour once status is done.
Parameters
exportIdstringPathRequiredExport id.
curl "https://api.desyn.app/api/v1/exports/$EXPORT_ID" \
-H "Authorization: Bearer $DESYN_API_KEY"{
"exportId": "e5f6a7b8c9d0",
"status": "done",
"format": "pdf",
"bytes": 4821331,
"url": "https://files.desyn.app/exports/e5f6a7b8c9d0.pdf?sig=…"
}