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

# Campaigns: Create and Manage Outbound Email Sequences

> Campaigns group your outbound sequence steps, enrolled leads, and delivery settings into a single controllable unit with full lifecycle management.

A campaign is the core unit of work in Leadterra. It bundles together a multi-step email sequence, a set of enrolled leads, and your workspace's delivery settings into one object you can create, start, pause, and inspect through the API. Because campaigns are fully programmable, your AI agents and GTM workflows can spin them up, monitor their performance, and react to results without any manual intervention.

## Campaign lifecycle

Every campaign moves through three states. Understanding the transitions helps you build reliable automation around campaign control.

* **Draft** — The campaign has been created with `POST /v1/campaigns` but has not yet started sending. You can modify sequence steps and enroll leads while a campaign is in draft.
* **Running** — The campaign is actively sending messages to enrolled leads according to the sequence schedule. Trigger this state with `POST /v1/campaigns/:id/start`.
* **Paused** — Sending is suspended. No new messages go out, but the campaign retains all its data and can be restarted. Trigger this state with `POST /v1/campaigns/:id/pause`.

<Note>
  You can enroll additional leads into a running campaign at any time using the bulk upsert endpoint. Newly enrolled leads start at step one of the sequence regardless of where existing leads are in the flow.
</Note>

## Creating a campaign

Use `POST /v1/campaigns` to create a draft campaign. You can define all sequence steps up front or add them before you start the campaign.

```bash theme={null}
curl -X POST https://app.leadterra.co/v1/campaigns \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "VP Sales — AI Workflow Q1",
    "sequenceSteps": [
      {
        "stepNumber": 1,
        "delayDays": 0,
        "subject": "Quick question, {{firstName}}",
        "bodyHtml": "<p>Hi {{firstName}},</p><p>I noticed {{company}} is expanding its sales team — we help companies like yours book more qualified meetings. Worth a 15-minute call this week?</p>"
      },
      {
        "stepNumber": 2,
        "delayDays": 3,
        "subject": "Following up, {{firstName}}",
        "bodyHtml": "<p>Hi {{firstName}},</p><p>Just wanted to bump this in case it got buried. Happy to share a quick overview if that helps.</p>"
      }
    ]
  }'
```

**Sample response**

```json theme={null}
{
  "data": {
    "id": "camp_01hx4mrqpbcn7wh2gfk9yz6e3s",
    "name": "VP Sales — AI Workflow Q1",
    "status": "draft",
    "sequenceSteps": 2,
    "createdAt": "2025-01-15T09:00:00Z"
  }
}
```

The campaign is created in `draft` state. You can now enroll leads with `POST /v1/campaigns/:id/leads/bulk` and then call `POST /v1/campaigns/:id/start` to begin sending.

## Sequence steps

A sequence is an ordered list of steps, where each step is one email in the outbound thread. Every step has a `subject` and a `bodyHtml`. When you create a campaign you define all steps up front, and Leadterra spaces them according to the delay you configure on each step.

**Example sequence step object**

```json theme={null}
{
  "stepNumber": 1,
  "delayDays": 0,
  "subject": "Quick question, {{firstName}}",
  "bodyHtml": "<p>Hi {{firstName}},</p><p>I noticed that {{company}} is expanding its engineering team — we help companies like yours source qualified candidates 3x faster. Worth a 15-minute call this week?</p><p>Best,<br>James</p>"
}
```

Personalization tokens let you tailor every message to the individual lead. The following tokens are available out of the box:

| Token           | Resolved from            |
| --------------- | ------------------------ |
| `{{firstName}}` | Lead's `firstName` field |
| `{{company}}`   | Lead's `company` field   |
| `{{jobTitle}}`  | Lead's `jobTitle` field  |

You can also use any custom field you include when uploading leads — see [Leads](/concepts/leads) for details.

<Note>
  If a lead is missing the field a token references, Leadterra replaces the token with an empty string by default. Always verify your lead data is complete before starting a campaign to avoid awkward gaps like "Hi ," in your subject lines.
</Note>

## Campaign stats

Once a campaign is running, use `GET /v1/campaigns/:id/stats` to pull performance metrics:

```bash theme={null}
curl https://app.leadterra.co/v1/campaigns/camp_01hx4mrqpbcn7wh2gfk9yz6e3s/stats \
  -H "Authorization: Bearer sk_live_YOUR_KEY"
```

**Sample response**

```json theme={null}
{
  "data": {
    "campaignId": "camp_01hx4mrqpbcn7wh2gfk9yz6e3s",
    "status": "running",
    "enrolledLeads": 412,
    "metrics": {
      "delivered": 389,
      "queued": 23,
      "bounced": 8,
      "replied": 47,
      "replyRate": 0.121
    },
    "updatedAt": "2025-01-15T14:22:00Z"
  }
}
```

The four core metrics tell you the full delivery story:

* **delivered** — Messages successfully accepted by the recipient's mail server.
* **queued** — Messages waiting to send, either because of daily capacity limits or step delays.
* **bounced** — Messages permanently rejected by the recipient's mail server.
* **replied** — Leads who sent at least one reply to any step in the sequence.

You can also subscribe to the `campaign.started`, `message.sent`, and `message.bounced` webhook events to receive these signals in real time rather than polling the stats endpoint.
