---
title: "List workflows"
method: GET
path: "/v1/projects/{project_id}/workflows"
tags: ["Workflows"]
---

# List workflows

`GET /v1/projects/{project_id}/workflows`

## Request

- Base URL: `https://api.naturali.ai`
- URL: `https://api.naturali.ai/v1/projects/{project_id}/workflows`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://api.naturali.ai/authorize`, token URL `https://api.naturali.ai/token`, scopes: `mcp:access`)

Lists workflow definitions in a project.

## Query parameters

- `limit` integer
- `offset` integer

## Response `200`

A list of workflows

- object
  - `data` Workflow[], required
    - `id` string
    - `project_id` string
    - `name` string
    - `description` string, nullable
    - `version` integer: Incremented on every write that changes the state machine; prior versions are archived. A task pins the version it entered on, so these fields are a draft for tasks created from now on rather than a live rewrite of the ones already in flight.
    - `states` WorkflowState[]
      - `name` string, required
      - `initial` boolean
      - `terminal` boolean
      - `kind` string: `human` marks a human-in-the-loop parking state: the state never dispatches (declaring `on_enter` on it is rejected at validation) and the task parks until a principal fires a transition.
      - `stalled_after` integer, nullable: Seconds a task may sit in this state before the stall sweeper emits a `tasks.stalled` event (once per stall episode, re-armed on the next transition). Must be a positive integer when set. Omit or null to never stall. The event does not move the task — route on it with a webhook/trigger.
      - `on_enter` object, nullable: What entering the state dispatches, and how the result routes. Omitted or null on a state that only parks.
        - `dispatch` object: The one thing entering the state runs. `kind` picks it and names the id it needs: `agent` → `agent_id`, `orchestration` → `orchestration_id`, `tool` → `tool_id` (with an optional `operation_id`).
          - `kind` 'agent' | 'orchestration' | 'tool': Which target is dispatched.
          - `agent_id` string, nullable: The agent a `kind: agent` dispatch generates with.
          - `orchestration_id` string, nullable: The orchestration a `kind: orchestration` dispatch starts a run of.
          - `tool_id` string, nullable: The tool a `kind: tool` dispatch calls.
          - `operation_id` string, nullable: Which operation of a multi-operation tool to invoke — the same selector an orchestration `tool` node takes.
          - `input_mapping` object, nullable: JSON Logic building the dispatch input from the task. Carried verbatim.
          - `payload_writes` object, nullable: JSON Logic expressions over `{task, result}` whose values are written into `task.payload` when the dispatch completes, one named channel per key. Carried verbatim.
        - `retry` object, nullable: Re-runs the dispatch's execution failures before `on_failure` applies. Omitted means a single attempt.
          - `max_attempts` integer: Attempts to make, 1–10.
          - `backoff_seconds` number, nullable: Delay before the second attempt.
          - `backoff_multiplier` number, nullable: Factor the delay grows by per further attempt: `backoff_seconds * backoff_multiplier^(n - 2)`.
        - `on_complete` object[], nullable: Rules evaluated in order when the dispatch completes; the first whose `when` is truthy fires its transition.
          - `when` unknown
          - `transition` string: The transition to fire, by name.
        - `on_failure` string, nullable: Transition fired when the dispatch fails after its last attempt. Omitted parks the task with `automation_status: failed`.
    - `transitions` WorkflowTransition[]
      - `name` string, required
      - `from` string[], required
      - `to` string, required
      - `guard` object, nullable
      - `requires_approval` boolean: Gate the transition behind a human approval. When `true`, firing the transition (by anyone other than the approval resolution itself) parks a pending `ApprovalItem` instead of moving the task; the task exposes `pending_transition` until the item resolves. Approval fires the transition as the `approval` principal (its guard re-evaluated at resolution time); rejection or expiry clears the gate and appends a history note.
    - `payload_schema` object, nullable
    - `created_at` string, date-time
    - `updated_at` string, date-time
  - `total` integer, required
  - `limit` integer, required
  - `offset` integer, required

## Other responses

- `401`: Unauthorized
- `403`: Forbidden

---

[API](https://skmtc.dev/naturali/apis/naturali-ai-api.md) · [All operations](https://skmtc.dev/naturali/apis/naturali-ai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/naturali/apis/naturali-ai-api/revisions/e4905b78f422?raw)
