---
title: "Workflows · intentic sandbox API"
description: "Several agents in a fixed order, the designs and the runs. Every route in the workflows group of the intentic sandbox API, with its input, its answer and a playground."
url: "https://intentic.dev/api/workflows/"
---

Agents

# Workflows

Several agents in a fixed order, the designs and the runs

**On this page (8 sections)**

- [Saved workflows and their runs](#workflows-list)
- [Create or replace a workflow](#workflows-save)
- [Delete a workflow](#workflows-remove)
- [Start a workflow](#workflows-run)
- [Every workflow run](#workflows-runs)
- [Stop a run now](#workflows-stopRun)
- [Take a finished run off the board](#workflows-archiveRun)
- [Bring an archived run back](#workflows-unarchiveRun)

A workflow is a design: run these conversations, in this order, each handing its result to the next. These routes hold the saved designs and the run history, start a run, stop one in flight, and archive the ones you are done reading.

8 calls. Pick one to open it, or use the list on the right.

**GET`/workflows` Saved workflows and their runs**

Every workflow somebody has designed, each with its own run history, newest first. One answer rather than two, because a workflow that has never been run is the interesting case rather than a mistake.

### What you send

Nothing. Call it as it is.

### What comes back

| Field | Type |
| --- | --- |
| `workflows` Every saved design with its own… | object[] |
| `id` The workflow's id | string |
| `name` What to call it | string |
| `description` What it is for | string |
| `steps` The steps, each with what it… | object[] |
| `id` This step's own name, which other… | string |
| `title` What to call it on screen | string |
| `goal` What done means for this step,… | string |
| `prompt` What the step is told to… | string |
| `needs` Which steps must finish first | string[] |
| `handoff` How it meets what came before:… | "fresh" | "continue" |
| `output` What it has to produce for… | object |
| `kind` It produces nothing but its work | "none" |
| `checks` What has to pass before it… | object[] |
| `kind` Run something and see if it… | "command" |
| `command` The command to run in the… | string |
| `context` How the step's own repeats meet… | "fresh" | "continue" |
| `maxSpendUsd` A ceiling on what this step… | number |
| `agent` Which provider runs it | string |
| `harness` Which agentic loop runs it | "native" | "claude-code" |
| `account` Which account pays for it | string |
| `model` Which model runs it | string |
| `actsAs` Which persona it acts as | string |
| `gate` Present means a machine can run… | object |
| `step` Which step's answer carries the decision | string |
| `field` Which of that step's declared answers… | string |
| `pass` Which values mean ship it | string[] |
| `token` The credential the calling pipeline presents | string |
| `dailyMax` How many runs a day, across… | integer |
| `maxParallel` How many steps may run at… | integer |
| `runs` Its runs, newest first | object[] |
| `runId` This run's id | string |
| `workflow` The design as it stood when… | object |
| `id` The workflow's id | string |
| `name` What to call it | string |
| `description` What it is for | string |
| `steps` The steps, each with what it… | object[] |
| `gate` Present means a machine can run… | object |
| `maxParallel` How many steps may run at… | integer |
| `repos` The workspace as this run began,… | object[] |
| `repo` | string |
| `base` | string |
| `request` What this run was asked to… | string |
| `state` How the run is going | "running" | "done" | "failed" | "stopped" … (6) |
| `startedAt` When it began, in milliseconds | number |
| `endedAt` When it ended, in milliseconds | number |
| `resumed` How many times the sandbox restarted… | integer |
| `detail` What went wrong, when something did | string |
| `steps` One entry per step, in the… | object[] |
| `stepId` Which step this is | string |
| `state` How it went | "pending" | "running" | "done" | "failed" … (6) |
| `conversationId` The conversation it ran on, and… | string |
| `startedAt` When it began, in milliseconds | number |
| `endedAt` When it ended, in milliseconds | number |
| `iterations` How many rounds it took | integer |
| `costUsd` What it cost, in dollars | number |
| `loopState` How its repeating ended | "running" | "done" | "exhausted" | "stalled" … (7) |
| `detail` What went wrong, when something did | string |
| `document` What it produced, once it has… | object |
| `report` The start of its closing words | string |
| `reportPath` Where the whole answer is, as… | string |
| `archivedAt` When it was put away, in… | number |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/workflows" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workflows.list();
```

**POST`/workflows` Create or replace a workflow**

Writes a workflow design. Say which of the two you mean, so an id that happens to collide cannot silently overwrite somebody's work. A design that could never run is refused, in the same words the editor shows while you type: a loop in the steps, a step waiting on one that is not there, a step with no way of knowing it is finished.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `workflow` required The design to write | object | body |
| `id` required The workflow's id | string | body |
| `name` required What to call it | string | body |
| `description` What it is for | string | body |
| `steps` required The steps, each with what it… | object[] | body |
| `id` required This step's own name, which other… | string | body |
| `title` required What to call it on screen | string | body |
| `goal` What done means for this step,… | string | body |
| `prompt` What the step is told to… | string | body |
| `needs` required Which steps must finish first | string[] | body |
| `handoff` required How it meets what came before:… | "fresh" | "continue" | body |
| `output` required What it has to produce for… | object | body |
| `kind` required It produces nothing but its work | "none" | body |
| `checks` required What has to pass before it… | object[] | body |
| `kind` required Run something and see if it… | "command" | body |
| `command` required The command to run in the… | string | body |
| `context` required How the step's own repeats meet… | "fresh" | "continue" | body |
| `maxSpendUsd` A ceiling on what this step… | number | body |
| `agent` Which provider runs it | string | body |
| `harness` Which agentic loop runs it | "native" | "claude-code" | body |
| `account` Which account pays for it | string | body |
| `model` Which model runs it | string | body |
| `actsAs` Which persona it acts as | string | body |
| `gate` Present means a machine can run… | object | body |
| `step` required Which step's answer carries the decision | string | body |
| `field` required Which of that step's declared answers… | string | body |
| `pass` required Which values mean ship it | string[] | body |
| `token` The credential the calling pipeline presents | string | body |
| `dailyMax` How many runs a day, across… | integer | body |
| `maxParallel` required How many steps may run at… | integer | body |
| `create` required Whether you mean to make a… | boolean | body |

### What comes back

| Field | Type |
| --- | --- |
| `id` The workflow's id | string |
| `name` What to call it | string |
| `description` What it is for | string |
| `steps` The steps, each with what it… | object[] |
| `id` This step's own name, which other… | string |
| `title` What to call it on screen | string |
| `goal` What done means for this step,… | string |
| `prompt` What the step is told to… | string |
| `needs` Which steps must finish first | string[] |
| `handoff` How it meets what came before:… | "fresh" | "continue" |
| `output` What it has to produce for… | object |
| `when kind is "none"` | shape |
| `when kind is "claim"` | shape |
| `when kind is "json"` | shape |
| `fields` The shape that answer has to… | object[] |
| `checks` What has to pass before it… | object[] |
| `when kind is "command"` | shape |
| `command` The command to run in the… | string |
| `when kind is "judge"` | shape |
| `rubric` What that judge is asked | string |
| `model` Which model judges | string |
| `context` How the step's own repeats meet… | "fresh" | "continue" |
| `maxSpendUsd` A ceiling on what this step… | number |
| `agent` Which provider runs it | string |
| `harness` Which agentic loop runs it | "native" | "claude-code" |
| `account` Which account pays for it | string |
| `model` Which model runs it | string |
| `actsAs` Which persona it acts as | string |
| `gate` Present means a machine can run… | object |
| `step` Which step's answer carries the decision | string |
| `field` Which of that step's declared answers… | string |
| `pass` Which values mean ship it | string[] |
| `token` The credential the calling pipeline presents | string |
| `dailyMax` How many runs a day, across… | integer |
| `maxParallel` How many steps may run at… | integer |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/workflows" \
 -H "x-intentic-control: $INTENTIC_TOKEN" \
 -H "content-type: application/json" \
 -d '{"workflow":{"id":"a1b2c3d4","name":"nightly changelog","description":"Runs every night and opens a pull request when anything changed.","steps":[{"id":"a1b2c3d4","title":"Update the changelog","goal":"…","prompt":"Update the changelog for the last five commits.","needs":["…","…"],"handoff":"fresh","output":{},"checks":[],"context":"fresh","maxSpendUsd":1,"agent":"…","harness":"native","account":"work","model":"claude-sonnet-4-6","actsAs":"…"},{"id":"e5f6a7b8","title":"Draft the release notes","goal":"…","prompt":"Update the changelog for the last five commits.","needs":["…","…"],"handoff":"continue","output":{},"checks":[],"context":"continue","maxSpendUsd":1,"agent":"…","harness":"claude-code","account":"work","model":"claude-haiku-4-6","actsAs":"…"}],"gate":{"step":"…","field":"…","pass":["…","…"],"token":"ict_9wQ4rTz8kLmN3pXbV7hJ","dailyMax":1},"maxParallel":1},"create":true}'
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workflows.save({
 "workflow": {
 "id": "a1b2c3d4",
 "name": "nightly changelog",
 "description": "Runs every night and opens a pull request when anything changed.",
 "steps": [
 {
 "id": "a1b2c3d4",
 "title": "Update the changelog",
 "goal": "…",
 "prompt": "Update the changelog for the last five commits.",
 "needs": [
 "…",
 "…"
 ],
 "handoff": "fresh",
 "output": {},
 "checks": [],
 "context": "fresh",
 "maxSpendUsd": 1,
 "agent": "…",
 "harness": "native",
 "account": "work",
 "model": "claude-sonnet-4-6",
 "actsAs": "…"
 },
 {
 "id": "e5f6a7b8",
 "title": "Draft the release notes",
 "goal": "…",
 "prompt": "Update the changelog for the last five commits.",
 "needs": [
 "…",
 "…"
 ],
 "handoff": "continue",
 "output": {},
 "checks": [],
 "context": "continue",
 "maxSpendUsd": 1,
 "agent": "…",
 "harness": "claude-code",
 "account": "work",
 "model": "claude-haiku-4-6",
 "actsAs": "…"
 }
 ],
 "gate": {
 "step": "…",
 "field": "…",
 "pass": [
 "…",
 "…"
 ],
 "token": "ict_9wQ4rTz8kLmN3pXbV7hJ",
 "dailyMax": 1
 },
 "maxParallel": 1
 },
 "create": true
});
```

**DELETE`/workflows/{id}` Delete a workflow**

Removes the design. A run of it that is already going keeps going and stays readable and stoppable, because a run takes its own copy of the design when it starts.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `id` required Which workflow | string | address |

### What comes back

| Field | Type |
| --- | --- |
| `ok` Always true | true |

Try it answered in this tab

curl

```bash
curl -X DELETE "$SANDBOX/workflows/a1b2c3d4" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workflows.remove({
 "id": "a1b2c3d4"
});
```

**POST`/workflows/{id}/run` Start a workflow**

Kicks a workflow off and answers immediately with the run as recorded; the work carries on without you. Point it at a question and every step gets that on top of its own instructions. Every step is written down as waiting up front, so the picture is complete from the first frame. Several runs of one design can be in flight at once without colliding.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `id` required Which workflow | string | address |
| `request` What to point it at | string | body |

### What comes back

| Field | Type |
| --- | --- |
| `runId` This run's id | string |
| `workflow` The design as it stood when… | object |
| `id` The workflow's id | string |
| `name` What to call it | string |
| `description` What it is for | string |
| `steps` The steps, each with what it… | object[] |
| `id` This step's own name, which other… | string |
| `title` What to call it on screen | string |
| `goal` What done means for this step,… | string |
| `prompt` What the step is told to… | string |
| `needs` Which steps must finish first | string[] |
| `handoff` How it meets what came before:… | "fresh" | "continue" |
| `output` What it has to produce for… | object |
| `kind` It produces nothing but its work | "none" |
| `checks` What has to pass before it… | object[] |
| `kind` Run something and see if it… | "command" |
| `command` The command to run in the… | string |
| `context` How the step's own repeats meet… | "fresh" | "continue" |
| `maxSpendUsd` A ceiling on what this step… | number |
| `agent` Which provider runs it | string |
| `harness` Which agentic loop runs it | "native" | "claude-code" |
| `account` Which account pays for it | string |
| `model` Which model runs it | string |
| `actsAs` Which persona it acts as | string |
| `gate` Present means a machine can run… | object |
| `step` Which step's answer carries the decision | string |
| `field` Which of that step's declared answers… | string |
| `pass` Which values mean ship it | string[] |
| `token` The credential the calling pipeline presents | string |
| `dailyMax` How many runs a day, across… | integer |
| `maxParallel` How many steps may run at… | integer |
| `repos` The workspace as this run began,… | object[] |
| `repo` | string |
| `base` | string |
| `request` What this run was asked to… | string |
| `state` How the run is going | "running" | "done" | "failed" | "stopped" … (6) |
| `startedAt` When it began, in milliseconds | number |
| `endedAt` When it ended, in milliseconds | number |
| `resumed` How many times the sandbox restarted… | integer |
| `detail` What went wrong, when something did | string |
| `steps` One entry per step, in the… | object[] |
| `stepId` Which step this is | string |
| `state` How it went | "pending" | "running" | "done" | "failed" … (6) |
| `conversationId` The conversation it ran on, and… | string |
| `startedAt` When it began, in milliseconds | number |
| `endedAt` When it ended, in milliseconds | number |
| `iterations` How many rounds it took | integer |
| `costUsd` What it cost, in dollars | number |
| `loopState` How its repeating ended | "running" | "done" | "exhausted" | "stalled" … (7) |
| `detail` What went wrong, when something did | string |
| `document` What it produced, once it has… | object |
| `done` Whether the goal is met | boolean |
| `reason` Why, in one line | string |
| `evidence` What was checked to know that | string |
| `data` The declared answer, for a loop… | object |
| `report` The start of its closing words | string |
| `reportPath` Where the whole answer is, as… | string |
| `archivedAt` When it was put away, in… | number |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/workflows/a1b2c3d4/run" \
 -H "x-intentic-control: $INTENTIC_TOKEN" \
 -H "content-type: application/json" \
 -d '{"request":"…"}'
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workflows.run({
 "id": "a1b2c3d4",
 "request": "…"
});
```

**GET`/workflows/runs` Every workflow run**

All runs across all workflows, newest first. This is also the only place the runs of a deleted workflow are still reachable.

### What you send

Nothing. Call it as it is.

### What comes back

| Field | Type |
| --- | --- |
| `runs` Every run across every workflow, newest… | object[] |
| `runId` This run's id | string |
| `workflow` The design as it stood when… | object |
| `id` The workflow's id | string |
| `name` What to call it | string |
| `description` What it is for | string |
| `steps` The steps, each with what it… | object[] |
| `id` This step's own name, which other… | string |
| `title` What to call it on screen | string |
| `goal` What done means for this step,… | string |
| `prompt` What the step is told to… | string |
| `needs` Which steps must finish first | string[] |
| `handoff` How it meets what came before:… | "fresh" | "continue" |
| `output` What it has to produce for… | object |
| `checks` What has to pass before it… | object[] |
| `context` How the step's own repeats meet… | "fresh" | "continue" |
| `maxSpendUsd` A ceiling on what this step… | number |
| `agent` Which provider runs it | string |
| `harness` Which agentic loop runs it | "native" | "claude-code" |
| `account` Which account pays for it | string |
| `model` Which model runs it | string |
| `actsAs` Which persona it acts as | string |
| `gate` Present means a machine can run… | object |
| `step` Which step's answer carries the decision | string |
| `field` Which of that step's declared answers… | string |
| `pass` Which values mean ship it | string[] |
| `token` The credential the calling pipeline presents | string |
| `dailyMax` How many runs a day, across… | integer |
| `maxParallel` How many steps may run at… | integer |
| `repos` The workspace as this run began,… | object[] |
| `repo` | string |
| `base` | string |
| `request` What this run was asked to… | string |
| `state` How the run is going | "running" | "done" | "failed" | "stopped" … (6) |
| `startedAt` When it began, in milliseconds | number |
| `endedAt` When it ended, in milliseconds | number |
| `resumed` How many times the sandbox restarted… | integer |
| `detail` What went wrong, when something did | string |
| `steps` One entry per step, in the… | object[] |
| `stepId` Which step this is | string |
| `state` How it went | "pending" | "running" | "done" | "failed" … (6) |
| `conversationId` The conversation it ran on, and… | string |
| `startedAt` When it began, in milliseconds | number |
| `endedAt` When it ended, in milliseconds | number |
| `iterations` How many rounds it took | integer |
| `costUsd` What it cost, in dollars | number |
| `loopState` How its repeating ended | "running" | "done" | "exhausted" | "stalled" … (7) |
| `detail` What went wrong, when something did | string |
| `document` What it produced, once it has… | object |
| `done` Whether the goal is met | boolean |
| `reason` Why, in one line | string |
| `evidence` What was checked to know that | string |
| `data` The declared answer, for a loop… | object |
| `report` The start of its closing words | string |
| `reportPath` Where the whole answer is, as… | string |
| `archivedAt` When it was put away, in… | number |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/workflows/runs" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workflows.runs();
```

**POST`/workflows/runs/{runId}/stop` Stop a run now**

Nothing further starts, and the steps already going are cut off where they stand. Whatever they had written stays on their branches. Deliberately abrupt rather than letting the current step finish: a step is a whole agent turn, and a stop that kept spending for minutes afterwards is indistinguishable from a button that does nothing. It always ends the run, including one left stranded by a daemon that was replaced mid-flight.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `runId` required Which run | string | address |

### What comes back

| Field | Type |
| --- | --- |
| `ok` Always true | true |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/workflows/runs/run_8c2f41d9/stop" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workflows.stopRun({
 "runId": "run_8c2f41d9"
});
```

**POST`/workflows/runs/{runId}/archive` Take a finished run off the board**

Nothing is lost and the working copies are reclaimed. Every conversation the run started is put away with it, which is what makes this an archive rather than a dismissal: a step has no card of its own, so merely dropping the run would spill its conversations onto the board at the moment somebody said they were done. Refused while the run is still going.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `runId` required Which run | string | address |

### What comes back

| Field | Type |
| --- | --- |
| `ok` Always true | true |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/workflows/runs/run_8c2f41d9/archive" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workflows.archiveRun({
 "runId": "run_8c2f41d9"
});
```

**POST`/workflows/runs/{runId}/unarchive` Bring an archived run back**

Puts a run and every conversation it started back on the board.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `runId` required Which run | string | address |

### What comes back

| Field | Type |
| --- | --- |
| `ok` Always true | true |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/workflows/runs/run_8c2f41d9/unarchive" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workflows.unarchiveRun({
 "runId": "run_8c2f41d9"
});
```

More in Agents

[Previous ← Past sessions](https://intentic.dev/api/sessions/)[Next Loops →](https://intentic.dev/api/loops/)
