# Set up a campaign by API

Create a campaign, write its sequence, add AI fields and senders, check the activation preflight, and activate it, all from the REST API.

Everything the Victoria AI app does to take a campaign from draft to sending is available by API. This guide runs the steps in the order the activation preflight expects them. You need a key with `campaigns:write`, `leads:write` and, to connect a sender, `accounts:write`.

## 1. Create the campaign

[`POST /v1/campaigns`](https://docs.versionseven.ai/api-reference/campaigns/create-campaign) creates a campaign in draft, with `is_active: false`. Nothing sends until you activate it.

```bash
curl -X POST https://api.versionseven.ai/v1/campaigns \
  -H "Authorization: Bearer $VICTORIA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"name": "Q3 outbound: heads of sales"}'
```

Keep the campaign's `id` from the response; every call below takes it in the path.

## 2. Write the sequence

[`PUT /v1/campaigns/{campaign_id}/sequence`](https://docs.versionseven.ai/api-reference/campaigns/replace-sequence) replaces the campaign's whole sequence. Start from a blank template from [`GET /v1/sequence-templates`](https://docs.versionseven.ai/api-reference/reference/list-sequence-templates) and fill in each step's `message`, or `subject` and `content` for email. The sequence is validated before it's saved; a rule that fails answers `400 SEQUENCE_VALIDATION_FAILED` with every failing rule in the message.

Step copy can use lead fields such as `{first_name}` and `{company}`, and any AI field you add in the next step.

## 3. Add AI fields

An AI field is a variable written for each lead before its first message, from the lead's LinkedIn profile or company website. [`POST /v1/campaigns/{campaign_id}/ai-fields`](https://docs.versionseven.ai/api-reference/campaigns/create-ai-field) creates one; use it in the sequence as `{field_name}`.

```bash
curl -X POST https://api.versionseven.ai/v1/campaigns/$CAMPAIGN_ID/ai-fields \
  -H "Authorization: Bearer $VICTORIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "field_name": "recent_news",
    "ai_instructions": "In one short sentence, name something specific the company announced or shipped recently, from its website.",
    "fallback_value": "the work your team is doing",
    "data_sources": ["website"]
  }'
```

`fallback_value` is required: it's what a lead gets when personalization fails. The preflight fails a sequence that uses a variable no AI field or lead field provides. [`PATCH /v1/campaigns/{campaign_id}/ai-fields/{field_id}`](https://docs.versionseven.ai/api-reference/campaigns/update-ai-field) changes a field later, or sets `is_active: false` to stop generating it.

## 4. Assign senders

[`PUT /v1/campaigns/{campaign_id}/senders`](https://docs.versionseven.ai/api-reference/campaigns/assign-senders) sets the accounts that send for the campaign, from the `id` values in [`GET /v1/accounts`](https://docs.versionseven.ai/api-reference/accounts/list-accounts). Each must be connected and not already sending for another active campaign.

```bash
curl -X PUT https://api.versionseven.ai/v1/campaigns/$CAMPAIGN_ID/senders \
  -H "Authorization: Bearer $VICTORIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"account_ids": ["0f2f5b9e-8d3a-4c6b-9a2e-1c5d8e7f9a0b"]}'
```

If the account you need isn't connected yet, or shows `is_active: false`, [`POST /v1/accounts/connect-link`](https://docs.versionseven.ai/api-reference/accounts/create-connect-link) mints a hosted sign-in link. Send its `url` to the person whose LinkedIn or mailbox it is; the account appears in [`GET /v1/accounts`](https://docs.versionseven.ai/api-reference/accounts/list-accounts) once they've signed in. Pass `reconnect_account_id` to re-authenticate an existing account instead of adding one.

## 5. Add leads

Enrol leads with [`POST /v1/leads`](https://docs.versionseven.ai/api-reference/leads/create-lead) and a `campaign_id`, as in the [Quickstart](https://docs.versionseven.ai/guides/quickstart#4-add-a-lead-to-the-campaign). The preflight blocks activation of a campaign with no enrolled leads.

## 6. Check the preflight

[`GET /v1/campaigns/{campaign_id}/preflight`](https://docs.versionseven.ai/api-reference/campaigns/get-campaign-preflight) runs the readiness checks without activating. `ok: true` means nothing blocks; each entry in `checks` is `pass`, `warn` or `fail`, and `issues` says what to fix.

```bash
curl https://api.versionseven.ai/v1/campaigns/$CAMPAIGN_ID/preflight \
  -H "Authorization: Bearer $VICTORIA_API_KEY"
```

[`POST /v1/campaigns/{campaign_id}/preview`](https://docs.versionseven.ai/api-reference/campaigns/preview-campaign) renders variation A for a few enrolled leads, with every AI field at its fallback value, so you can read the worst-case message before it goes out. It spends no credits.

## 7. Activate

[`PATCH /v1/campaigns/{campaign_id}`](https://docs.versionseven.ai/api-reference/campaigns/update-campaign) with `is_active: true` runs the same preflight and activates when it passes. A blocking check answers `409 CAMPAIGN_NOT_READY`; warnings alone answer `409 CAMPAIGN_ACTIVATION_WARNINGS` until you repeat the request with `ack_warnings: true`.

```bash
curl -X PATCH https://api.versionseven.ai/v1/campaigns/$CAMPAIGN_ID \
  -H "Authorization: Bearer $VICTORIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"is_active": true}'
```

Pause with `is_active: false`; pausing never runs the preflight.

## Optional: the reply agent and A/B tests

- [`PATCH /v1/campaigns/{campaign_id}/responder`](https://docs.versionseven.ai/api-reference/campaigns/update-responder) turns the AI Appointment Setter on and sets where it sends interested prospects (`goal_link`), the links it may share and its instructions. [`GET /v1/campaigns/{campaign_id}/bookings`](https://docs.versionseven.ai/api-reference/campaigns/list-bookings) then lists the meetings it books.
- To test two versions of the sequence, write a `variation_b` in the sequence, turn the test on with [`POST /v1/campaigns/{campaign_id}/ab-testing`](https://docs.versionseven.ai/api-reference/campaigns/set-ab-testing), compare the arms with [`GET /v1/campaigns/{campaign_id}/ab-cohorts`](https://docs.versionseven.ai/api-reference/campaigns/get-ab-cohorts), and end the test with [`POST /v1/campaigns/{campaign_id}/ab-testing/promote`](https://docs.versionseven.ai/api-reference/campaigns/promote-ab-winner).
