---
title: "Work one person in a campaign"
method: PATCH
path: "/api/v1/campaigns/{id}/prospects/{pid}"
---

# Work one person in a campaign

`PATCH /api/v1/campaigns/{id}/prospects/{pid}`

## Request

- Base URL: `https://www.easeclaw.com`
- URL: `https://www.easeclaw.com/api/v1/campaigns/{id}/prospects/{pid}`
- Auth: HTTP bearer

Three instructions, never two at once: edit exactly what will go out for this person (null hands them back to the campaign template), record that a meeting was booked once their first message has gone out, or reject them before anything is committed (undoable while they have not been contacted). Editing a draft never sends it, the owner's approval, or their autopilot limits, is still the only door out. 409 when the batch was already approved. Rate-limited to 300/hour per account, shared with the dashboard. Requires an outreach-scope API key (Pro plan or higher).

## Path parameters

- `id` string, uuid, required
- `pid` string, uuid, required

## Request body

- object
  - `reject` boolean: true rejects this person from the campaign; false undoes that while they have not been contacted (answers {restored: 0|1}). Cannot be combined with the other fields.
  - `reject_reason` 'wrong_title' | 'company_not_fit' | 'existing_customer' | 'competitor' | 'other': Why they are not a fit, with reject: true. Defaults to other.
  - `reject_reason_text` string: Your own words, only with reject_reason other
  - `meeting_booked` boolean: Mark (or un-mark) a booked meeting. Only once their first message has gone out.
  - `invite_note` string, nullable: This person's invite note; null restores the campaign template
  - `first_message` string, nullable: This person's first message; null restores the campaign template

## Response `200`

The prospect as it now stands

- object
  - `prospect` CampaignProspect
    - `id` string, uuid
    - `state` 'sourced' | 'qualified' | 'rejected' | 'awaiting_approval' | 'invite_approved' | 'invite_sent' | 'accepted' | 'dm_awaiting_approval' | 'dm_approved' | 'dm_sent' | 'done' | 'stale' | 'withdrawn' | 'stopped' | 'failed': Where one person stands in a campaign.
    - `score` integer, nullable: How well this person fits the campaign's targeting
    - `signal` string, nullable
    - `intent_score` integer, nullable
    - `source_meta` object, nullable: Where this person came from
    - `invite_note` string, nullable: What will go out for this person; null means the campaign template
    - `first_message` string, nullable
    - `state_changed_at` string, date-time, nullable
    - `invite_sent_at` string, date-time, nullable
    - `replied_at` string, date-time, nullable
    - `email_handoff_at` string, date-time, nullable
    - `meeting_at` string, date-time, nullable: Marked by a human. There is no calendar integration
    - `created_at` string, date-time
    - `contact` ContactIdentity: The person, as this surface may see them. Email and phone are deliberately absent.
      - `id` string, uuid
      - `full_name` string, nullable
      - `headline` string, nullable
      - `profile_url` string, nullable
      - `platform_uid` string, nullable

## Other responses

- `400`: Error
- `401`: Error
- `402`: Error
- `403`: The key is not outreach-scoped (code outreach_scope_required). Campaign paths need a key minted with the outreach scope at https://www.easeclaw.com/leads/api. The scope cannot be widened on an existing key.
- `404`: Error
- `409`: Error
- `429`: Rate limited (300/hour per account; drafting also 30/hour + daily AI budget). Retry-After header set when known.
- `500`: Error

---

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