Developers

Agent API (v1)

The Desyn REST API for agents and automation — base URLs, API keys and scopes, errors, pagination, rate limits and the full endpoint index.

On this page

The Agent API lets your own code and agents do what the editor and the built-in agent do: create and read designs, commit transactions, upload assets, run the agent and workflows, and export. Every endpoint is a thin HTTP wrapper over a backend function, so the API behaves exactly like the app.

Base URL#

InstallationBase URL
desyn.apphttps://api.desyn.app/api/v1
Self-hostedhttps://<CONVEX_SITE_URL host>/api/v1, e.g. https://convex-site.example.org/api/v1

Requests and responses are JSON (content-type: application/json) unless an endpoint says otherwise. Timestamps are milliseconds since the Unix epoch.

Authentication#

Create a key in Settings → API keys: give it a name, choose its scopes and, optionally, an expiry between 1 and 730 days. The key is shown once; Desyn only stores a hash of it.

Keys look like dsk_ followed by 43 characters. Send one with every request, either as a bearer token or in x-api-key:

Shell
curl https://api.desyn.app/api/v1/me \
  -H "Authorization: Bearer $DESYN_API_KEY"

A key acts as the member who created it, in the workspace it was created for, limited to its scopes. Write scopes only take effect while that member has at least the editor role in the workspace; otherwise the key is reduced to its read scopes. Revoke keys at any time in the same settings page.

Scopes#

ScopeAllows
designs:readList and read designs, documents, transactions, versions, comments, shares and folders; describe and preview pages.
designs:writeCreate, change and delete designs and folders; commit transactions; comment; manage shares and versions; instantiate templates.
assets:readList assets and get signed URLs.
assets:writeUpload, rename and delete assets.
templates:readSearch and read templates.
brand:readRead brand kits.
brand:writeCreate, change and delete brand kits.
ai:runStart and control agent runs, asset tools and workflows, and list models. Spends credits on the hosted Pro plan.
exports:writeRequest exports and read their status.
mcpConnect to the MCP server. Requires the MCP feature (Pro or self-hosted).

Errors#

Failed requests return an HTTP status and a JSON body with a stable, machine-readable code:

JSON
{
  "error": {
    "code": "LIMIT_REACHED",
    "message": "You reached your plan limit for designs (20).",
    "limit": "designs",
    "max": 20,
    "current": 20
  }
}
StatusCodeMeaning
400INVALID_ARGUMENTA parameter is missing or invalid; field names it
401UNAUTHENTICATEDMissing, malformed, expired or revoked key
403FORBIDDENThe key lacks the scope, or the member lacks the role
403FEATURE_UNAVAILABLEThe plan does not include the feature; feature names it
403EMAIL_NOT_VERIFIEDThe member must verify their email first
404NOT_FOUNDNo such resource in this workspace
409CONFLICTThe request conflicts with the current state
410EXPIREDA link, upload or run has expired
422LIMIT_REACHEDA plan limit was reached; limit, max and current explain which
429RATE_LIMITEDToo many requests; see rate limits
501NOT_CONFIGUREDThe installation has not configured what this needs (for example storage or a provider)
500INTERNALSomething failed on our side; safe to retry with backoff

The message is written for humans and safe to show to users.

Rate limits#

AI endpoints share the account's fair-use limits: per-minute and per-day request caps and a maximum number of concurrent agent runs and workflows (see credits & fair use). When a limit is hit the API responds with 429, a Retry-After header in seconds, and the error fields retryAfterMs and scope (minute, day or concurrency).

On the hosted Pro plan, AI requests beyond the monthly credit pool are not rejected but soft-throttled: they start after a short delay. Requests that run on the member's own provider keys do not use credits.

Pagination#

List endpoints accept limit and cursor and return nextCursor; pass it back to get the next page. nextCursor is null on the last page.

Idempotency#

Transactions are idempotent on their tx.id: retrying a commit after a timeout returns the original result instead of applying the change twice. Generate transaction ids on the client (12 characters, lowercase letters and digits).

Endpoints#

MethodPathEndpointScope
GET/designsList designsdesigns:read
POST/designsCreate a designdesigns:write
GET/designs/{designId}Get a designdesigns:read
PATCH/designs/{designId}Rename or move a designdesigns:write
POST/designs/{designId}/duplicateDuplicate a designdesigns:write
POST/designs/{designId}/archiveMove to trashdesigns:write
POST/designs/{designId}/restoreRestore from trashdesigns:write
DELETE/designs/{designId}Delete permanentlydesigns:write
GET/designs/{designId}/documentLoad the documentdesigns:read
POST/designs/{designId}/transactionsCommit a transactiondesigns:write
GET/designs/{designId}/transactionsList transactions since a seqdesigns:read
GET/designs/{designId}/describeDescribe a pagedesigns:read
POST/designs/{designId}/previewRender a previewdesigns:read
GET/designs/{designId}/versionsList versionsdesigns:read
POST/designs/{designId}/versionsSave a named versiondesigns:write
POST/designs/{designId}/versions/{versionId}/restoreRestore a versiondesigns:write
GET/designs/{designId}/sharesList share linksdesigns:read
POST/designs/{designId}/sharesCreate or update a share linkdesigns:write
GET/designs/{designId}/commentsList commentsdesigns:read
POST/designs/{designId}/commentsAdd a comment or replydesigns:write
POST/designs/{designId}/exportsRequest an exportexports:write
GET/exports/{exportId}Get an exportexports:write
POST/assets/uploadsRequest an uploadassets:write
POST/assets/{assetId}/finalizeFinalize an uploadassets:write
GET/assetsList assetsassets:read
GET/assets/{assetId}Get an assetassets:read
PATCH/assets/{assetId}Rename an assetassets:write
DELETE/assets/{assetId}Delete an assetassets:write
POST/designs/{designId}/agent-runsStart an agent runai:run
GET/agent-runs/{runId}Get a runai:run
GET/agent-runs/{runId}/eventsFollow run eventsai:run
POST/agent-runs/{runId}/answerAnswer a questionai:run
POST/agent-runs/{runId}/cancelCancel a runai:run
POST/assets/generateGenerate or transform an assetai:run
POST/workflowsStart a workflowai:run
GET/workflows/{workflowId}Get a workflowai:run
GET/ai/modelsList modelsai:run
GET/templatesSearch templatestemplates:read
GET/templates/{slug}Get a templatetemplates:read
POST/templates/{slug}/instantiateInstantiate a templatedesigns:write
GET/brand-kitsList brand kitsbrand:read
POST/brand-kitsCreate a brand kitbrand:write
PATCH/brand-kits/{brandKitId}Update a brand kitbrand:write
DELETE/brand-kits/{brandKitId}Delete a brand kitbrand:write
GET/foldersList foldersdesigns:read
POST/foldersCreate a folderdesigns:write
GET/meGet the current userany
GET/workspacesList workspacesany
GET/creditsGet credit balanceany
GET/usageGet usageany

Working with designs#

The endpoints that matter most for agents:

  1. Describe a page to understand it, or load the document for full detail.
  2. Change it either by committing transactions you build yourself, or by starting an agent run with a goal in plain language.
  3. Render a preview to check the result visually, then export.

Prefer the MCP server if your agent speaks MCP, and the TypeScript SDK for typed access from Node.js, Deno, Bun or the browser.

Popular pages

QuickstartGet started
Keyboard shortcutsEditor
The agentAI
Docker Compose quickstartSelf-hosting
Configuration referenceSelf-hosting
Agent API (v1)Developers