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

# List Outbound Campaigns

> A project's outbound campaigns, newest first

List the outbound campaigns under a project, newest created first. Use it to find the campaign you want to pull dispatches for. Read-only.

## Request

```bash theme={null}
GET https://api.pathors.com/v1/campaigns?project_id={project_id}
```

### Headers

<ParamField header="Authorization" type="string" required>
  Bearer token authentication with your Developer Key (`dk_...`).
</ParamField>

### Query parameters

<ParamField query="project_id" type="string" required>
  The project whose campaigns to list. The Developer Key must have access to it.
</ParamField>

<ParamField query="status" type="string">
  Filter by campaign status, comma-separated (e.g. `active,completed`). An unrecognized value returns `400` rather than silently matching nothing.
</ParamField>

<ParamField query="limit" type="integer">
  Campaigns to return. Defaults to `20`, capped at `100`. For just the latest campaign, pass `limit=1`.
</ParamField>

### Example

```bash theme={null}
curl -H "Authorization: Bearer dk_your_key" \
  "https://api.pathors.com/v1/campaigns?project_id=proj_your_project_id&limit=1"
```

## Response

<ResponseField name="data" type="array">
  <Expandable title="properties">
    <ResponseField name="campaign_id" type="string">Pass this to the dispatches endpoint</ResponseField>
    <ResponseField name="name" type="string">Campaign display name, as set in the dashboard</ResponseField>
    <ResponseField name="status" type="string">`draft` (not dialing yet), `active` (scheduler is dialing), or `completed`</ResponseField>
    <ResponseField name="stopped_reason" type="string | null">Why dialing stopped early, e.g. `insufficient_credits`. `null` when it did not stop early</ResponseField>
    <ResponseField name="created_at" type="string">When the campaign was created (ISO 8601, UTC) — the sort key</ResponseField>
    <ResponseField name="updated_at" type="string">Last update to the campaign</ResponseField>
    <ResponseField name="total_contacts" type="integer">Contacts on the call list</ResponseField>
    <ResponseField name="dispatched_contacts" type="integer">Contacts handed to the dialer</ResponseField>
    <ResponseField name="completed_contacts" type="integer">Contacts whose dispatch finished</ResponseField>
    <ResponseField name="connected_contacts" type="integer">Contacts who answered — the pickup count</ResponseField>
  </Expandable>
</ResponseField>

### Example

```json theme={null}
{
  "data": [
    {
      "campaign_id": "cmp_example001",
      "name": "August member callback",
      "status": "completed",
      "stopped_reason": null,
      "created_at": "2026-08-14T08:00:00.000Z",
      "updated_at": "2026-08-14T10:30:00.000Z",
      "total_contacts": 500,
      "dispatched_contacts": 500,
      "completed_contacts": 487,
      "connected_contacts": 312
    }
  ]
}
```

## Errors

| Status | When                                                                 |
| ------ | -------------------------------------------------------------------- |
| 400    | Missing `project_id`, unrecognized `status`, or `limit` out of range |
| 401    | Missing or invalid Developer Key                                     |
| 403    | The Developer Key has no access to the project                       |
| 500    | Internal server error                                                |

## Notes

* **Ordering**: by `created_at`, newest first — not by `updated_at`. The scheduler rewrites a campaign throughout a run, so ordering by last update would let an older campaign that is still dialing outrank one created today.
* **Deciding what to pull**: compare `completed_contacts` against `total_contacts` to tell whether a campaign has finished before fetching its [dispatches](/en/api-reference/v1/campaigns/list-dispatches).
* **No pagination**: campaigns per project run to the tens, so `limit` alone covers it. There is no cursor.
* **Scope**: only campaigns under projects the Developer Key can access. There is no cross-project listing.
