Multi-step flows

Start, poll, approve, resume, and cancel server-run multi-step automations.

A flow is a server-run, multi-step automation built from a template. Where an execution runs one action, a flow chains several steps — tool calls, data transforms, timed waits, and human approval gates — while ClawLink persists state between them. Flows are useful when work spans multiple actions or needs to pause for approval.

Each step is one of four types: tool_call, transform, wait, or approval.

Lifecycle

A flow moves through these statuses:

pending → running → waiting → completed
                  ↘ failed
                  ↘ cancelled

waiting means the flow has paused — typically on an approval step, or a wait until a timestamp. You advance it with approve or resume.

List templates

Flows are template-based. Discover the available templates and their keys:

curl https://claw-link.dev/api/flows/templates \
  -H "Authorization: Bearer cllk_live_YOUR_KEY"
{
  "templates": [
    { "key": "summarize_unread_gmail", "name": "Summarize unread Gmail", "description": "Fetch unread Gmail messages and produce a compact summary." },
    { "key": "gmail_to_notion_task_sync", "name": "Gmail to Notion task sync", "description": "Read unread Gmail messages, build task pages, pause for approval, then create Notion pages." }
  ]
}

Start a flow

POST /api/flows/start

flowTemplatestringrequired

A template key from /api/flows/templates.

inputobjectdefault: {}

Template inputs. For example, summarize_unread_gmail accepts optional query (a Gmail search, default is:unread), maxResults (1–20), and gmailConnectionId. gmail_to_notion_task_sync additionally requires notionParent.

triggerTypestringdefault: manual

One of agent, manual, webhook, schedule. Records how the flow was started.

curl -X POST https://claw-link.dev/api/flows/start \
  -H "Authorization: Bearer cllk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "flowTemplate": "summarize_unread_gmail",
    "input": { "query": "is:unread newer_than:2d", "maxResults": 10 },
    "triggerType": "manual"
  }'

The response includes the new flowId, the full flow (record + steps), and the templates list:

{
  "flowId": "flow_abc",
  "flow": {
    "flow": {
      "id": "flow_abc",
      "name": "Summarize unread Gmail",
      "templateKey": "summarize_unread_gmail",
      "status": "running",
      "triggerType": "manual",
      "input": { "query": "is:unread newer_than:2d", "maxResults": 10 },
      "context": {},
      "currentStep": "fetch_unread",
      "createdAt": "2026-06-28T10:00:00.000Z",
      "updatedAt": "2026-06-28T10:00:00.000Z",
      "completedAt": null
    },
    "steps": [
      { "stepKey": "fetch_unread", "stepType": "tool_call", "status": "running", "stepIndex": 0, "attemptCount": 1 }
    ]
  },
  "templates": [ /* … */ ]
}

Get a flow

GET /api/flows/{id} returns the current { flow, steps }. Poll it to watch progress.

curl https://claw-link.dev/api/flows/flow_abc \
  -H "Authorization: Bearer cllk_live_YOUR_KEY"

Each step record carries stepKey, stepIndex, stepType, status, input, output, error, attemptCount, and timestamps — so you can see exactly where a flow is and what each step produced.

List your flows

GET /api/flows?limit=30 (max 100) returns { flows: [...] }, most recent first.

curl "https://claw-link.dev/api/flows?limit=20" \
  -H "Authorization: Bearer cllk_live_YOUR_KEY"

Approve a step

When a flow is waiting on an approval step (e.g. gmail_to_notion_task_sync pauses before creating Notion pages), approve it to continue:

POST /api/flows/{id}/approve

stepKeystring

The approval step to approve. Optional — omit to approve the current waiting step.

curl -X POST https://claw-link.dev/api/flows/flow_xyz/approve \
  -H "Authorization: Bearer cllk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "stepKey": "approve_task_creation" }'

Returns the updated { flow, steps }.

Resume

POST /api/flows/{id}/resume re-drives a flow that is waiting (e.g. its wait timestamp has passed) or retries one that failed. Returns the updated { flow, steps }.

curl -X POST https://claw-link.dev/api/flows/flow_abc/resume \
  -H "Authorization: Bearer cllk_live_YOUR_KEY"

Cancel

POST /api/flows/{id}/cancel stops a flow and sets its status to cancelled. Returns the updated { flow, steps }.

curl -X POST https://claw-link.dev/api/flows/flow_abc/cancel \
  -H "Authorization: Bearer cllk_live_YOUR_KEY"

All flow endpoints return 404 {"error":"Flow not found"} for an unknown id or a flow that belongs to another account.

On this page