> ## Documentation Index
> Fetch the complete documentation index at: https://docs.goyappr.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get a campaign

Returns one campaign with `agent`, `from_phone_number` and `stop_dispositions` expanded to the full objects they reference. Archived campaigns return 404.

For progress counters (how many contacts are pending, dialing, exhausted) use `GET /campaigns/{id}/stats` instead — this endpoint returns configuration and engine state, not a per-contact breakdown.

Required scope: `campaigns:read`.

## Path parameters

| Parameter | Type | Notes                                                |
| --------- | ---- | ---------------------------------------------------- |
| `id`      | uuid | Campaign ID. Must belong to the API key's workspace. |

## Configuration fields

Every field below is writable via `POST /campaigns` and `PATCH /campaigns/{id}`. See the create page for ranges, defaults and guidance.

| Field                                                                                                                                                                                                   | Type      |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- |
| `name`, `description`, `regulatory_basis`                                                                                                                                                               | string    |
| `agent_id`, `from_phone_number_id`                                                                                                                                                                      | uuid      |
| `stop_disposition_ids`                                                                                                                                                                                  | uuid\[]   |
| `stop_on_no_answer`, `stop_on_voicemail`, `stop_on_unclassified`, `randomize_retry_time`, `double_dial_enabled`                                                                                         | boolean   |
| `max_attempts`, `max_infra_retries`, `retry_no_answer_seconds`, `retry_completed_seconds`, `double_dial_gap_seconds`, `max_calls_per_day`, `min_seconds_between_calls`, `max_in_flight`, `budget_cents` | integer   |
| `calling_window`                                                                                                                                                                                        | object    |
| `starts_at`, `ends_at`                                                                                                                                                                                  | timestamp |

## Read-only fields

Engine-owned. Sending any of these to `POST` or `PATCH` is a 400.

| Field                                             | Type           | Meaning                                                                                               |
| ------------------------------------------------- | -------------- | ----------------------------------------------------------------------------------------------------- |
| `status`                                          | string         | Lifecycle state. See `GET /campaigns` for the full vocabulary.                                        |
| `from_number`                                     | string         | Audit snapshot of the number this campaign dials from.                                                |
| `daily_admitted_count`                            | integer        | Calls this campaign has started today.                                                                |
| `daily_window_date`                               | date           | The day `daily_admitted_count` refers to, in your workspace timezone.                                 |
| `last_admitted_at`                                | timestamp      | When this campaign last started a call. Drives `min_seconds_between_calls`.                           |
| `spent_cents`                                     | integer        | Settled spend.                                                                                        |
| `reserved_cents`                                  | integer        | Worst-case cost of calls currently in flight. Counted against `budget_cents` alongside `spent_cents`. |
| `estimate_cents`                                  | integer        | Pre-launch cost estimate, when one was computed.                                                      |
| `last_tick_at`                                    | timestamp      | Last time this campaign was evaluated (roughly once a minute while active).                           |
| `last_tick_result`                                | string         | Why the last evaluation did or did not start a call. Values are listed on the stats page.             |
| `last_error`                                      | string         | Last internal error message, truncated.                                                               |
| `started_at`                                      | timestamp      | First launch. Preserved across pause/resume.                                                          |
| `completed_at`                                    | timestamp      | When every contact reached a terminal state.                                                          |
| `total_leads`                                     | integer        | Contacts enrolled, refreshed on enrollment.                                                           |
| `stats`                                           | object         | Cached counters for the dashboard. Prefer `GET /campaigns/{id}/stats`.                                |
| `created_at`, `updated_at`, `created_by`          | —              | Audit fields.                                                                                         |
| `agent`, `from_phone_number`, `stop_dispositions` | object / array | Expanded references. Always the complete objects, never a summary subset.                             |

## Example request

```bash theme={null}
curl "https://api.goyappr.com/campaigns/CAMPAIGN_ID" \
  -H "Authorization: Bearer $YAPPR_API_KEY"
```

## Example response

```json theme={null}
{
  "id": "b3f1c0d2-5a44-4f0e-9c11-7a2e8d3f0001",
  "company_id": "fe493f11-0000-0000-0000-000000000001",
  "name": "July renewals",
  "description": "One call per renewal lead, up to three tries.",
  "status": "running",
  "agent_id": "7e8a91c1-0000-4c11-9a00-000000000001",
  "from_phone_number_id": "2d9f4b6a-0000-4a3c-8b21-000000000002",
  "from_number": null,
  "calling_window": {},
  "stop_disposition_ids": [
    "5c1d9a2e-0000-4b10-9f31-000000000010",
    "5c1d9a2e-0000-4b10-9f31-000000000011"
  ],
  "stop_on_no_answer": false,
  "stop_on_voicemail": false,
  "randomize_retry_time": true,
  "stop_on_unclassified": false,
  "max_attempts": 3,
  "max_infra_retries": 5,
  "retry_no_answer_seconds": 60,
  "retry_completed_seconds": 14400,
  "double_dial_enabled": false,
  "double_dial_gap_seconds": 90,
  "max_calls_per_day": 150,
  "min_seconds_between_calls": 45,
  "max_in_flight": 2,
  "daily_admitted_count": 37,
  "daily_window_date": "2026-07-28",
  "last_admitted_at": "2026-07-28T11:58:04.010Z",
  "budget_cents": 50000,
  "estimate_cents": 41200,
  "spent_cents": 8140,
  "reserved_cents": 1000,
  "regulatory_basis": "existing_customer",
  "last_tick_at": "2026-07-28T11:59:00.412Z",
  "last_tick_result": "spacing",
  "last_error": null,
  "starts_at": null,
  "ends_at": null,
  "started_at": "2026-07-27T06:00:11.900Z",
  "completed_at": null,
  "total_leads": 412,
  "stats": {},
  "created_at": "2026-07-26T09:14:22.123Z",
  "updated_at": "2026-07-28T11:59:00.412Z",
  "created_by": "9a1b2c3d-0000-4e5f-8a90-000000000003",
  "agent": {
    "id": "7e8a91c1-0000-4c11-9a00-000000000001",
    "name": "Renewals agent",
    "max_call_duration_secs": 300
  },
  "from_phone_number": {
    "id": "2d9f4b6a-0000-4a3c-8b21-000000000002",
    "phone_number": "+972737000000",
    "is_active": true,
    "status": "active"
  },
  "stop_dispositions": [
    { "id": "5c1d9a2e-0000-4b10-9f31-000000000010", "label": "Do Not Call" },
    { "id": "5c1d9a2e-0000-4b10-9f31-000000000011", "label": "Not Interested" }
  ]
}
```

`agent`, `from_phone_number` and `stop_dispositions` are abbreviated above; in a real response each is the complete object.

Deleting a disposition that is a stop rule on an **active** campaign is refused — take it out of that campaign's `stop_disposition_ids` first. Once a campaign is finished, deleting the disposition also drops its ID from `stop_disposition_ids`, so a historical campaign can show fewer stop rules than it actually ran with.

## Errors

| HTTP | Code                 | When                                                                 |
| ---- | -------------------- | -------------------------------------------------------------------- |
| 401  | `INSUFFICIENT_SCOPE` | API key lacks `campaigns:read`.                                      |
| 404  | —                    | No campaign with that ID in this workspace, or it has been archived. |
