---
title: "Get Campaign Sequence"
method: GET
path: "/api/v1/campaigns/{campaign_id}/sequence"
tags: ["Campaigns"]
---

# Get Campaign Sequence

`GET /api/v1/campaigns/{campaign_id}/sequence`

## Request

- Base URL: `http://localhost:3009`
- URL: `http://localhost:3009/api/v1/campaigns/{campaign_id}/sequence`
- Auth: HTTP bearer

Returns the campaign's sequence steps in execution order, starting at the `start` step and following `next_node_id`. Returns the draft by default; pass `published=true` for the live graph. Only the published graph is executed.

`source` says which copy you got; `has_published_sequence` says whether a published copy exists; `has_unpublished_changes` says whether a publish is pending.

## Path parameters

- `campaign_id` string, required

## Query parameters

- `published` 'true' | 'false'

## Response `200`

Default Response

- object
  - `status` integer
  - `data` object
    - `nodes` CampaignSequenceNode[]
      - `node_id` string: Node ID — stable for the life of the node
      - `type` 'start' | 'wait' | 'send' | 'manual_task' | 'phone_call_task' | 'linkedin_message_task' | 'note': Persisted node type. A `manual_email` added via the catalog persists as `send` with `config.send_mode = "manual"`.
      - `display_name` string, nullable: Custom step name; falls back to the type label
      - `config` object: Step configuration, stored and returned verbatim in the sending engine's own vocabulary — so key casing is mixed (`sender_mode` next to `trackOpens`) and it is passed through rather than renamed, because these are the exact keys the sender reads. **send**: `subject`, `body` (required), plus `send_mode` (`manual`), `thread_mode` (`reply`|`new`), `cc`, `bcc`, `trackOpens`, `sender_mode` (`pool`|`mailbox`|`member`), `sender_mailbox_id`, `sender_member_email`, `replyTaskPriority`. **wait**: `delay`, `unit` (`minutes`|`hours`|`days`). **task steps**: `priority`, `note`, `assignee_mode` (`mailbox_owner`|`member`), `assignee_email`. **start**: `leadFields` — the campaign's lead schema, in the same shape as `lead_schema` on Get Campaign.
      - `next_node_id` string, nullable: The next step in the chain; null on the final step
    - `source` 'draft' | 'published': Which copy these steps came from — echoes the `published` query param
    - `has_published_sequence` boolean: Whether this campaign has a published sequence at all
    - `has_unpublished_changes` boolean: The draft has moved ahead of the published graph

## Other responses

- `401`: Unauthorized — missing or invalid API key
- `403`: Forbidden. `code` says which permission refused: ROLE_FORBIDDEN (your role), INSUFFICIENT_SCOPE (the API key's scopes), WORKFLOW_FORBIDDEN (no access to the workflow), KEY_WORKFLOW_FORBIDDEN (the API key's workflow restriction).
- `429`: Too Many Requests — rate limit exceeded. Check `Retry-After` header for seconds until the limit resets.

---

[API](https://skmtc.dev/floqer/apis/floqer-public-api.md) - [All operations](https://skmtc.dev/floqer/apis/floqer-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/floqer/apis/floqer-public-api/revisions/fce50dc07b20?raw)
