Skip to content

REST API ​

All endpoints require authentication via API key (Authorization: Bearer ask_...) or session cookie.

API keys are scoped: read (queries), write (create/update/delete), deploy (deploy/trigger/takedown/run control). All keys require at least read scope.

Base URL: https://your-instance/api

Authentication ​

bash
# API key
curl https://your-instance/api/workflows \
  -H "Authorization: Bearer ask_your_api_key"

Rate Limits ​

ScopeLimit
Global200 req/min per IP
Write operations30 req/min per user
Deploy operations10 req/min per user
Credential verification10 req/min per user

Pagination ​

All list endpoints support cursor-based pagination via cursor and limit query parameters.

json
{
  "data": [...],
  "nextCursor": "abc123_2026-03-29T10:00:00.000Z"
}

When nextCursor is null, there are no more pages.


Workflows ​

GET /workflows read ​

List all workflows in the active project.

ParamInRequiredDescription
cursorquerynoPagination cursor
limitquerynoItems per page (1–100, default 50)

GET /workflows/:id read ​

Get a single workflow by ID.


GET /workflows/:id/full read ​

Get a workflow with its current version, all version summaries, and active deployment.

ParamInRequiredDescription
versionquerynoSpecific version ID to load

POST /workflows write ​

Create a new workflow or function.

Request body:

json
{
  "name": "My Workflow",
  "description": "",
  "kind": "workflow"
}
FieldRequiredDescription
nameyesDisplay name
descriptionnoOptional description
kindno"workflow" (default) or "script". Functions (kind: "script") are fetch-only Workers — no durable runtime, no Runs. Set at create time only; cannot be changed via PATCH. See Functions for constraints and invocation.

PATCH /workflows/:id write ​

Update a workflow's name, description, environment variables, trigger code, dependencies, or deploy config.

Request body:

json
{
  "name": "Updated Name",
  "description": "optional",
  "envVars": [{ "name": "KEY", "value": "val", "isSecret": false }],
  "triggerCode": "optional trigger code string",
  "dependencies": { "lodash": "^4.0.0" },
  "deployConfig": {
    "route": {
      "pattern": "api.example.com/my-workflow/*",
      "zoneName": "example.com"
    }
  }
}

PATCH /workflows/:id/move write ​

Move a workflow to another project within the same organization.

Request body:

json
{ "targetProjectId": "project-id" }

DELETE /workflows/:id write ​

Delete a workflow and all its versions, deployments, and runs.


Functions ​

Functions are workflows with kind: "script". They share the same routes (POST /workflows to create, PATCH to update, DELETE to remove, POST /versions to compile a new version, POST /deploy to deploy) but compile to a fetch-only Cloudflare Worker instead of a WorkflowEntrypoint class.

Constraints ​

  • HTTP-only trigger. Script IR requires trigger: { type: "http" }. Cron, event, and manual triggers are rejected at validation.
  • No durable-runtime nodes. sleep, sleep_until, and wait_for_event are rejected — they require a durable instance the script doesn't have.
  • No WORKFLOW self-binding. The generated Worker has no Workflow binding to itself. Sub-workflow bindings (calls into other deployed workflows) and resource bindings (KV/D1/R2/etc.) are still detected.
  • No instance lifecycle. No Runs, no pause/resume/terminate. POST /workflows/:id/trigger returns 400. Invoke the deployed Worker URL directly via HTTP POST.
  • kind is immutable. Set at create time only; not accepted on PATCH.

Invocation ​

bash
curl -X POST https://<your-worker-url> \
  -H "Content-Type: application/json" \
  -d '{ "anything": "here" }'

The body is parsed and exposed to nodes as event.payload. The default response is Response.json(graph) where graph contains only nodes whose display name was prefixed with EXPORT_. Override the fetch handler body via the workflow's triggerCode field (PATCH /workflows/:id); the auto-generated runGraph(env, event) function and graph.* outputs stay stable across edits.

See Compilation → Full Generated Worker Shape for the emitted code, and Workflow IR → Scripts vs Workflows for the type-level split.


Projects ​

GET /projects read ​

List all projects in the active organization.


POST /projects write ​

Create a new project.

Request body:

json
{
  "name": "My Project",
  "slug": "my-project",
  "description": ""
}

PATCH /projects/:id write ​

Update a project's name or description.

Request body:

json
{ "name": "Updated Name", "description": "optional" }

DELETE /projects/:id write ​

Delete a project.


Versions ​

GET /workflows/:workflowId/versions read ​

List all versions for a workflow.


GET /workflows/:workflowId/versions/:versionId read ​

Get a specific version including its IR and generated code.


POST /workflows/:workflowId/versions write ​

Create a new version by submitting a workflow IR. The IR is validated and compiled to code.

Request body:

json
{ "ir": { ... } }

PATCH /workflows/:workflowId/versions/:versionId write ​

Lock or unlock a version. Locked versions cannot be deployed.

Request body:

json
{ "locked": true }

POST /workflows/:workflowId/versions/:versionId/revert write ​

Revert to a previous version. Creates a new version with the target version's IR.


DELETE /workflows/:workflowId/versions/:versionId write ​

Delete a version. Cannot delete the active, deployed, or locked version.


Deployments ​

GET /deployments read ​

List all deployments across all workflows.


GET /workflows/:workflowId/deployments read ​

List deployments for a specific workflow.


POST /workflows/:workflowId/deploy deploy ​

Deploy a workflow version to a connection. Validates environment variables and credentials before deploying.

Request body:

json
{
  "connectionId": "connection-id",
  "versionId": "optional-version-id"
}

POST /workflows/:workflowId/deploy-stream deploy ​

Deploy with real-time progress updates via Server-Sent Events. Same request body as /deploy.

Progress stages:

INITIALIZING → GENERATING_CODE → CODE_READY → DETECTING_BINDINGS →
BINDINGS_READY → CREATING_WORKER → DEPLOYING → WORKER_DEPLOYED →
UPDATING_WORKFLOW → COMPLETED

POST /workflows/:workflowId/trigger deploy ​

Trigger an execution of a deployed workflow. Params payload is capped at 100 KB.

Functions only

This endpoint is for kind: "workflow" only. Calling it on a function (kind: "script") returns 400 — functions have no instance lifecycle. Invoke the deployed Worker URL directly via HTTP POST instead. See Functions → Invocation.

Request body:

json
{
  "connectionId": "connection-id",
  "params": { "key": "value" }
}

Response:

json
{
  "id": "run-id",
  "instanceId": "cf-instance-id",
  "status": "queued"
}

POST /workflows/:workflowId/takedown deploy ​

Remove a deployment and clear the workflow's active version.

Request body:

json
{ "connectionId": "connection-id" }

Runs ​

GET /runs read ​

List all runs across all workflows.


GET /workflows/:workflowId/runs read ​

List runs for a specific workflow.


GET /workflows/:workflowId/runs/:runId read ​

Get a specific run. If the run is in a non-terminal state, live status is fetched from Cloudflare.


POST /workflows/:workflowId/runs/:runId/pause deploy ​

Pause a running workflow instance.


POST /workflows/:workflowId/runs/:runId/resume deploy ​

Resume a paused workflow instance.


POST /workflows/:workflowId/runs/:runId/terminate deploy ​

Terminate a running or paused workflow instance.


Connections ​

GET /connections read ​

List all connections. Credential values are redacted in the response.


POST /connections write ​

Create a new provider connection.

Request body:

json
{
  "provider": "cloudflare",
  "credentials": { "apiToken": "...", "accountId": "..." },
  "name": "My Connection"
}

POST /connections/verify-token write ​

Verify provider credentials before saving.

Request body:

json
{ "provider": "cloudflare", "credentials": { "apiToken": "..." } }

Response:

json
{
  "valid": true,
  "accounts": [{ "id": "abc123", "name": "My Account" }]
}

PATCH /connections/:id write ​

Update a connection's name or credentials.


DELETE /connections/:id write ​

Delete a connection.


Environment Variables ​

GET /env-vars read ​

List all global environment variables. Secret values are masked.


POST /env-vars write ​

Create a global environment variable. Name must match ^[A-Z][A-Z0-9_]*$.

Request body:

json
{ "name": "MY_VAR", "value": "my-value", "isSecret": false }

PATCH /env-vars/:id write ​

Update an environment variable's name, value, or secret flag.


DELETE /env-vars/:id write ​

Delete an environment variable.


Resources ​

All resource endpoints require a connectionId query parameter pointing to a valid Cloudflare connection.

GET /resources/kv/namespaces read ​

List KV namespaces.


GET /resources/kv/namespaces/:namespaceId/keys read ​

List keys in a KV namespace. Supports prefix, cursor, and limit query params.


GET /resources/kv/namespaces/:namespaceId/values/:key read ​

Get the value of a KV key.


GET /resources/d1/databases read ​

List D1 databases.


POST /resources/d1/databases/:databaseId/query read ​

Execute a SQL query against a D1 database.

Request body:

json
{ "connectionId": "connection-id", "sql": "SELECT 1", "params": [] }

GET /resources/r2/buckets read ​

List R2 buckets.


GET /resources/r2/buckets/:bucketName/objects read ​

List objects in an R2 bucket. Supports prefix, cursor, and limit query params.


Nodes ​

GET /nodes read ​

List all available node definitions from the registry.


GET /nodes/templates read ​

Get node template resolver data.


GET /nodes/:nodeId read ​

Get a single node definition.


Marketplace ​

GET /marketplace read ​

Get the full marketplace catalog with installation status for the current organization.


GET /marketplace/:nodeId read ​

Get details for a specific marketplace node, including available versions and installation status.


GET /marketplace/installed read ​

List installed marketplace nodes for the current organization.


POST /marketplace/install write ​

Install a node from the marketplace.

Request body:

json
{ "nodeId": "stripe", "version": "1.0.0" }

version is optional — defaults to the latest available version.


POST /marketplace/uninstall write ​

Uninstall a previously installed node.

Request body:

json
{ "nodeId": "stripe" }

POST /marketplace/update write ​

Update an installed node to a newer version.

Request body:

json
{ "nodeId": "stripe", "version": "1.1.0" }

API Keys session only ​

These endpoints require session authentication and are not accessible via API key.

GET /api-keys ​

List all API keys for the current organization.


POST /api-keys ​

Create a new API key scoped to a project. The full key is returned only once.

Request body:

json
{
  "name": "My Key",
  "projectId": "project-id",
  "scopes": ["read", "write"],
  "expiresAt": "2025-12-31T00:00:00Z"
}

expiresAt is optional.


DELETE /api-keys/:id ​

Revoke an API key.