> ## Documentation Index
> Fetch the complete documentation index at: https://docs.claw-link.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# 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](#approve-a-step) or [resume](#resume).

## List templates

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

```bash theme={null}
curl https://claw-link.dev/api/flows/templates \
  -H "Authorization: Bearer cllk_live_YOUR_KEY"
```

```json theme={null}
{
  "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`

<ParamField body="flowTemplate" type="string" required>
  A template `key` from `/api/flows/templates`.
</ParamField>

<ParamField body="input" type="object" default="{}">
  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`.
</ParamField>

<ParamField body="triggerType" type="string" default="manual">
  One of `agent`, `manual`, `webhook`, `schedule`. Records how the flow was started.
</ParamField>

```bash theme={null}
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:

```json theme={null}
{
  "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.

```bash theme={null}
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.

```bash theme={null}
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`

<ParamField body="stepKey" type="string">
  The approval step to approve. Optional — omit to approve the current waiting step.
</ParamField>

```bash theme={null}
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 }`.

```bash theme={null}
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 }`.

```bash theme={null}
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.
