---
title: "List the people in a campaign (keyset-paginated, filtered)"
method: GET
path: "/campaigns/{campaignId}/people"
tags: ["Campaigns"]
---

# List the people in a campaign (keyset-paginated, filtered)

`GET /campaigns/{campaignId}/people`

## Request

- Base URL: `https://origami.chat/api/v2`
- URL: `https://origami.chat/api/v2/campaigns/{campaignId}/people`
- Auth: HTTP bearer

The people enrolled in the campaign: one row per enrolled sequence
(recipient), with send status, fit score / explanation, and identity
profile. Keyset-paginated via an opaque `cursor`; the list envelope
additionally carries a top-level `total`.
`GET /campaigns/{campaignId}/sequences` is a synonym (same shape);
in the campaign model a person IS a sequence.

## Query parameters

- `cursor` string
- `limit` integer
- `search` string
- `status` string

## Response `200`

A page of campaign people in the list envelope (with top-level `total`).

- object: The canonical v2 list envelope. Every list endpoint returns this shape; per-endpoint `items` element types (and documented extras like `total`) are declared on each operation.
  - `object` 'list', required
  - `items` CampaignPerson[], required: The page of objects. Element type is per-endpoint.
    - `object` 'campaign_person', required
    - `sequenceId` string, uuid, required
    - `rowId` string, uuid, nullable, required
    - `recipient` string, nullable, required
    - `sendStatus` string, required: Aggregate send-status pill (draft / scheduled / sent / replied / …).
    - `stopReason` string, nullable, required
    - `senderId` string, uuid, nullable, required: Stable id of the primary bound sender (email wins on mixed sequences) - joinable against `GET /senders` and webhook `sender.id`. Null until a sender is bound (senders bind per sequence, not per campaign).
    - `senders` SequenceSenderRef[], required: Every sender bound to this person's sequence, one per channel.
      - `id` string, uuid, required
      - `channel` 'email' | 'linkedin', required
      - `label` string, required
      - `status` string, required
    - `profile` unknown, required
    - `fitExplanation` string, nullable, required: Agent-authored "why this person fits" write-up (markdown).
    - `fitScore` integer, nullable, required: 0-100 fit score of the source row, or null.
    - `addedAt` string, date-time, nullable, required
  - `nextCursor` string, nullable, required: Cursor for the next page; `null` means this is the last page.
  - `url` string, required: The path this list was fetched from (query string excluded).
  - `total` integer, required: Total enrolled people matching the filters (across all pages).

## Other responses

- `404`: CAMPAIGN_NOT_FOUND.

## Changes

- **2026-11-03** `8c6b16fe0a3b`: 2 info
  - added the required property `allOf[subschema #2]/items/items/senderId` to the response with the `200` status
  - added the required property `allOf[subschema #2]/items/items/senders` to the response with the `200` status

[Operation history](https://skmtc.dev/origami/apis/origami-agent-api/changes/campaigns/:campaignId/people/get.md)

---

[API](https://skmtc.dev/origami/apis/origami-agent-api.md) - [All operations](https://skmtc.dev/origami/apis/origami-agent-api/llms.txt) - [OpenAPI document](https://skmtc.dev/origami/apis/origami-agent-api/revisions/8c6b16fe0a3b?raw)
