# Campaigns

> Multi-step outreach sequences — connection requests and follow-ups with delays and personalization.

A campaign runs an outreach sequence for you: it sends connection requests and follow‑up messages across one or more accounts, spacing activity within safe daily limits so accounts stay healthy.

## Create a campaign

```http
POST /v1/campaigns
```

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes | A name for the campaign. |
| `account_ids` | string[] | yes | Accounts that will send. Work is spread across them. |
| `lead_list_id` | string | yes | The [lead list](/search#save-a-lead-list) to target. |
| `steps` | array | yes | Ordered steps (see below). |

Each **step** is one of:

| `type` | Fields | Description |
| --- | --- | --- |
| `invite` | `message`, `delay_days` | Send a connection request with an optional note. |
| `message` | `message`, `delay_days` | Send a message (requires an accepted connection). |

Messages support personalization tokens: `{{first_name}}`, `{{name}}`, `{{company}}`.

```bash
curl -X POST https://api.correctinbox.com/v1/campaigns \
  -H "X-API-KEY: $CORRECTINBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Q1 founders",
    "account_ids": ["acc_8f21c0"],
    "lead_list_id": "lst_77aa",
    "steps": [
      { "type": "invite",  "delay_days": 0, "message": "Hi {{first_name}}, love what {{company}} is building." },
      { "type": "message", "delay_days": 2, "message": "Thanks for connecting, {{first_name}}! Quick question —" }
    ]
  }'
```

```js
const campaign = await (
  await fetch("https://api.correctinbox.com/v1/campaigns", {
    method: "POST",
    headers: {
      "X-API-KEY": process.env.CORRECTINBOX_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      name: "Q1 founders",
      account_ids: ["acc_8f21c0"],
      lead_list_id: "lst_77aa",
      steps: [
        { type: "invite", delay_days: 0, message: "Hi {{first_name}}, love what {{company}} is building." },
        { type: "message", delay_days: 2, message: "Thanks for connecting, {{first_name}}!" },
      ],
    }),
  })
).json();
```

```python
campaign = requests.post(
    "https://api.correctinbox.com/v1/campaigns",
    headers={"X-API-KEY": os.environ["CORRECTINBOX_API_KEY"]},
    json={
        "name": "Q1 founders",
        "account_ids": ["acc_8f21c0"],
        "lead_list_id": "lst_77aa",
        "steps": [
            {"type": "invite", "delay_days": 0, "message": "Hi {{first_name}}, love what {{company}} is building."},
            {"type": "message", "delay_days": 2, "message": "Thanks for connecting, {{first_name}}!"},
        ],
    },
).json()
```

A campaign is created in `draft`. It does nothing until you start it.

## Start, pause, inspect

```http
POST   /v1/campaigns/{campaign_id}/start   # begin sending
POST   /v1/campaigns/{campaign_id}/pause   # stop sending; resume later
GET    /v1/campaigns                       # list campaigns
GET    /v1/campaigns/{campaign_id}         # status + per-step progress
DELETE /v1/campaigns/{campaign_id}         # delete
```

```bash
curl -X POST https://api.correctinbox.com/v1/campaigns/cmp_5kd2/start \
  -H "X-API-KEY: $CORRECTINBOX_API_KEY"
```

**Response (status)**

```json
{
  "id": "cmp_5kd2",
  "name": "Q1 founders",
  "status": "running",
  "stats": { "invites_sent": 24, "messages_sent": 11, "replies": 3, "pending": 61 }
}
```

## Safe sending

CorrectInbox enforces conservative per‑account daily limits and adds natural spacing and jitter between actions, so a running campaign never bursts. Add more `account_ids` to a campaign to raise total throughput without pushing any single account past its limit.
