# Campaigns API
Create and manage email campaigns, templates, steps, and participants programmatically. The Campaign API requires the **Campaigns add-on** to be enabled for your team.
> [!quote] Automate Campaign Management
> Build integrations that create campaigns, design email templates, enroll contacts, and activate drip sequences - ==all through the API.==
## Requirements
- **Team API key** (created from Team Dashboard > API & Webhooks)
- **X-Book-ID header** on every request
- **Campaigns add-on** enabled for the team
If the add-on is not active, all campaign endpoints return:
```json
{
"error": {
"code": "ADDON_REQUIRED",
"message": "Campaign add-on is required"
}
}
```
---
## Campaign Templates
Email templates are reusable email designs used in campaign steps. Each template has a name, subject line, and HTML body that can include [[Campaigns Overview#Merge Fields|merge fields]].
### Template Object
| Field | Type | Description |
|-------|------|-------------|
| `id` | UUID | Unique template identifier |
| `book_id` | UUID | The book this template belongs to |
| `name` | string | Internal template name |
| `subject` | string | Email subject line (supports merge fields) |
| `body_html` | string | HTML email body (supports merge fields) |
| `created_by` | UUID | User who created the template |
| `created_at` | timestamp | When the template was created |
| `updated_at` | timestamp | When the template was last modified |
### List Templates
Retrieve all email templates for the book, sorted by name.
```
GET /api/v1/campaign-templates
```
#### Headers
| Header | Required | Description |
|--------|----------|-------------|
| `Authorization` | Yes | `Bearer rlb_your_key` |
| `X-Book-ID` | Yes | UUID of the book |
#### Example Request
```bash
curl -X GET "https://app.relaybook.io/api/v1/campaign-templates" \
-H "Authorization: Bearer rlb_your_key" \
-H "X-Book-ID: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
```
#### Response
```
HTTP/1.1 200 OK
```
```json
{
"data": [
{
"id": "t1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c",
"book_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"name": "Welcome Email",
"subject": "Welcome aboard, {{first_name}}!",
"body_html": "<p>Hi {{first_name}},</p><p>Thanks for joining {{company}}.</p>",
"created_by": "5e1c820d-b605-4f9e-ae4f-47be164176ca",
"created_at": "2026-03-23T10:00:00Z",
"updated_at": "2026-03-23T10:00:00Z"
}
]
}
```
#### Errors
| Status | Code | Cause |
|--------|------|-------|
| 400 | `MISSING_BOOK` | `X-Book-ID` header is missing |
| 403 | `FORBIDDEN` | Book doesn't belong to your team |
| 403 | `ADDON_REQUIRED` | Campaign add-on is not active |
---
### Get Template
Retrieve a single template by its ID.
```
GET /api/v1/campaign-templates/{id}
```
#### Path Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| `id` | UUID | The template's unique ID |
#### Headers
| Header | Required | Description |
|--------|----------|-------------|
| `Authorization` | Yes | `Bearer rlb_your_key` |
| `X-Book-ID` | Yes | UUID of the book |
#### Example Request
```bash
curl -X GET "https://app.relaybook.io/api/v1/campaign-templates/t1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c" \
-H "Authorization: Bearer rlb_your_key" \
-H "X-Book-ID: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
```
#### Response
```
HTTP/1.1 200 OK
```
```json
{
"data": {
"id": "t1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c",
"book_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"name": "Welcome Email",
"subject": "Welcome aboard, {{first_name}}!",
"body_html": "<p>Hi {{first_name}},</p><p>Thanks for joining {{company}}.</p>",
"created_by": "5e1c820d-b605-4f9e-ae4f-47be164176ca",
"created_at": "2026-03-23T10:00:00Z",
"updated_at": "2026-03-23T10:00:00Z"
}
}
```
#### Errors
| Status | Code | Cause |
|--------|------|-------|
| 404 | `NOT_FOUND` | Template doesn't exist in this book |
---
### Create Template
Create a new email template.
```
POST /api/v1/campaign-templates
```
#### Headers
| Header | Required | Description |
|--------|----------|-------------|
| `Authorization` | Yes | `Bearer rlb_your_key` |
| `Content-Type` | Yes | `application/json` |
| `X-Book-ID` | Yes | UUID of the book |
#### Request Body
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Internal template name |
| `subject` | string | No | Email subject line |
| `body_html` | string | No | HTML email body |
#### Example Request
```bash
curl -X POST "https://app.relaybook.io/api/v1/campaign-templates" \
-H "Authorization: Bearer rlb_your_key" \
-H "Content-Type: application/json" \
-H "X-Book-ID: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d" \
-d '{
"name": "Welcome Email",
"subject": "Welcome to {{company}}, {{first_name}}!",
"body_html": "<p>Hi {{first_name}},</p><p>We are glad to have you on board.</p>"
}'
```
#### Response
```
HTTP/1.1 200 OK
```
```json
{
"data": {
"id": "t1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c",
"book_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"name": "Welcome Email",
"subject": "Welcome to {{company}}, {{first_name}}!",
"body_html": "<p>Hi {{first_name}},</p><p>We are glad to have you on board.</p>",
"created_by": "5e1c820d-b605-4f9e-ae4f-47be164176ca",
"created_at": "2026-03-25T14:00:00Z",
"updated_at": "2026-03-25T14:00:00Z"
}
}
```
#### Errors
| Status | Code | Cause |
|--------|------|-------|
| 400 | `INVALID_INPUT` | Request body is not valid JSON or name is missing |
| 403 | `ADDON_REQUIRED` | Campaign add-on is not active |
| 500 | `SERVER_ERROR` | Database error |
---
### Update Template
Update one or more fields on a template. Only include the fields you want to change.
```
PATCH /api/v1/campaign-templates/{id}
```
#### Path Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| `id` | UUID | The template's unique ID |
#### Headers
| Header | Required | Description |
|--------|----------|-------------|
| `Authorization` | Yes | `Bearer rlb_your_key` |
| `Content-Type` | Yes | `application/json` |
| `X-Book-ID` | Yes | UUID of the book |
#### Request Body
All fields are optional. Only provided fields are updated.
| Field | Type | Description |
|-------|------|-------------|
| `name` | string | Internal template name |
| `subject` | string | Email subject line |
| `body_html` | string | HTML email body |
#### Example Request
```bash
curl -X PATCH "https://app.relaybook.io/api/v1/campaign-templates/t1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c" \
-H "Authorization: Bearer rlb_your_key" \
-H "Content-Type: application/json" \
-H "X-Book-ID: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d" \
-d '{
"subject": "Updated subject line for {{first_name}}"
}'
```
#### Response
```
HTTP/1.1 200 OK
```
Returns the full updated template object.
#### Errors
| Status | Code | Cause |
|--------|------|-------|
| 400 | `INVALID_INPUT` | No fields provided to update |
| 404 | `NOT_FOUND` | Template doesn't exist in this book |
---
### Delete Template
Permanently delete a template.
```
DELETE /api/v1/campaign-templates/{id}
```
#### Path Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| `id` | UUID | The template's unique ID |
#### Headers
| Header | Required | Description |
|--------|----------|-------------|
| `Authorization` | Yes | `Bearer rlb_your_key` |
| `X-Book-ID` | Yes | UUID of the book |
#### Example Request
```bash
curl -X DELETE "https://app.relaybook.io/api/v1/campaign-templates/t1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c" \
-H "Authorization: Bearer rlb_your_key" \
-H "X-Book-ID: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
```
#### Response
```
HTTP/1.1 200 OK
```
```json
{
"data": {
"message": "Template deleted"
}
}
```
#### Errors
| Status | Code | Cause |
|--------|------|-------|
| 404 | `NOT_FOUND` | Template doesn't exist in this book |
---
## Campaigns
### Campaign Object
| Field | Type | Description |
|-------|------|-------------|
| `id` | UUID | Unique campaign identifier |
| `book_id` | UUID | The book this campaign belongs to |
| `name` | string | Campaign name |
| `description` | string | Campaign description |
| `status` | string | `draft`, `active`, `paused`, or `archived` |
| `step_count` | integer | Number of steps in the campaign (list only) |
| `participant_count` | integer | Number of active participants (list only) |
| `created_by` | UUID | User who created the campaign |
| `created_at` | timestamp | When the campaign was created |
| `updated_at` | timestamp | When the campaign was last modified |
### List Campaigns
Retrieve all campaigns for the book with step and participant counts.
```
GET /api/v1/campaigns
```
#### Headers
| Header | Required | Description |
|--------|----------|-------------|
| `Authorization` | Yes | `Bearer rlb_your_key` |
| `X-Book-ID` | Yes | UUID of the book |
#### Example Request
```bash
curl -X GET "https://app.relaybook.io/api/v1/campaigns" \
-H "Authorization: Bearer rlb_your_key" \
-H "X-Book-ID: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
```
#### Response
```
HTTP/1.1 200 OK
```
```json
{
"data": [
{
"id": "c1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c",
"book_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"name": "Onboarding Sequence",
"description": "Welcome new users with a 3-step drip",
"status": "active",
"step_count": 3,
"participant_count": 150,
"created_by": "5e1c820d-b605-4f9e-ae4f-47be164176ca",
"created_at": "2026-03-20T10:00:00Z",
"updated_at": "2026-03-23T14:30:00Z"
}
]
}
```
#### Errors
| Status | Code | Cause |
|--------|------|-------|
| 400 | `MISSING_BOOK` | `X-Book-ID` header is missing |
| 403 | `ADDON_REQUIRED` | Campaign add-on is not active |
---
### Get Campaign
Retrieve a single campaign with its full step list.
```
GET /api/v1/campaigns/{id}
```
#### Path Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| `id` | UUID | The campaign's unique ID |
#### Headers
| Header | Required | Description |
|--------|----------|-------------|
| `Authorization` | Yes | `Bearer rlb_your_key` |
| `X-Book-ID` | Yes | UUID of the book |
#### Example Request
```bash
curl -X GET "https://app.relaybook.io/api/v1/campaigns/c1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c" \
-H "Authorization: Bearer rlb_your_key" \
-H "X-Book-ID: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
```
#### Response
```
HTTP/1.1 200 OK
```
```json
{
"data": {
"id": "c1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c",
"book_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"name": "Onboarding Sequence",
"description": "Welcome new users with a 3-step drip",
"status": "active",
"created_by": "5e1c820d-b605-4f9e-ae4f-47be164176ca",
"created_at": "2026-03-20T10:00:00Z",
"updated_at": "2026-03-23T14:30:00Z"
}
}
```
#### Errors
| Status | Code | Cause |
|--------|------|-------|
| 404 | `NOT_FOUND` | Campaign doesn't exist in this book |
---
### Create Campaign
Create a new campaign. Campaigns are created in **draft** status by default.
```
POST /api/v1/campaigns
```
#### Headers
| Header | Required | Description |
|--------|----------|-------------|
| `Authorization` | Yes | `Bearer rlb_your_key` |
| `Content-Type` | Yes | `application/json` |
| `X-Book-ID` | Yes | UUID of the book |
#### Request Body
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Campaign name |
| `description` | string | No | Campaign description |
#### Example Request
```bash
curl -X POST "https://app.relaybook.io/api/v1/campaigns" \
-H "Authorization: Bearer rlb_your_key" \
-H "Content-Type: application/json" \
-H "X-Book-ID: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d" \
-d '{
"name": "Onboarding Sequence",
"description": "Welcome new users with a 3-step drip"
}'
```
#### Response
```
HTTP/1.1 200 OK
```
```json
{
"data": {
"id": "c1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c",
"book_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"name": "Onboarding Sequence",
"description": "Welcome new users with a 3-step drip",
"status": "draft",
"created_by": "5e1c820d-b605-4f9e-ae4f-47be164176ca",
"created_at": "2026-03-25T14:00:00Z",
"updated_at": "2026-03-25T14:00:00Z"
}
}
```
#### Errors
| Status | Code | Cause |
|--------|------|-------|
| 400 | `INVALID_INPUT` | Request body is not valid JSON or name is missing |
| 403 | `ADDON_REQUIRED` | Campaign add-on is not active |
---
### Update Campaign
Update a campaign's name, description, or status.
```
PATCH /api/v1/campaigns/{id}
```
#### Path Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| `id` | UUID | The campaign's unique ID |
#### Headers
| Header | Required | Description |
|--------|----------|-------------|
| `Authorization` | Yes | `Bearer rlb_your_key` |
| `Content-Type` | Yes | `application/json` |
| `X-Book-ID` | Yes | UUID of the book |
#### Request Body
All fields are optional. Only provided fields are updated.
| Field | Type | Description |
|-------|------|-------------|
| `name` | string | Campaign name |
| `description` | string | Campaign description |
| `status` | string | `draft`, `active`, `paused`, or `archived` |
#### Example Request
```bash
curl -X PATCH "https://app.relaybook.io/api/v1/campaigns/c1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c" \
-H "Authorization: Bearer rlb_your_key" \
-H "Content-Type: application/json" \
-H "X-Book-ID: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d" \
-d '{"status": "active"}'
```
#### Response
```
HTTP/1.1 200 OK
```
Returns the full updated campaign object.
#### Errors
| Status | Code | Cause |
|--------|------|-------|
| 400 | `INVALID_INPUT` | Invalid status value or no fields to update |
| 404 | `NOT_FOUND` | Campaign doesn't exist in this book |
---
### Delete Campaign
Permanently delete a campaign and all associated data.
```
DELETE /api/v1/campaigns/{id}
```
#### Path Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| `id` | UUID | The campaign's unique ID |
#### Headers
| Header | Required | Description |
|--------|----------|-------------|
| `Authorization` | Yes | `Bearer rlb_your_key` |
| `X-Book-ID` | Yes | UUID of the book |
#### Example Request
```bash
curl -X DELETE "https://app.relaybook.io/api/v1/campaigns/c1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c" \
-H "Authorization: Bearer rlb_your_key" \
-H "X-Book-ID: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
```
#### Response
```
HTTP/1.1 200 OK
```
```json
{
"data": {
"message": "Campaign deleted"
}
}
```
> [!note] Deleting a campaign
> Deleting a campaign removes all steps, participants, and completion records. This cannot be undone.
#### Errors
| Status | Code | Cause |
|--------|------|-------|
| 404 | `NOT_FOUND` | Campaign doesn't exist in this book |
---
## Campaign Steps
Steps define the actions in a campaign sequence. Each step has a type (email or trigger), a schedule, and configuration for what happens when it executes.
### Step Object
| Field | Type | Description |
|-------|------|-------------|
| `id` | UUID | Unique step identifier |
| `campaign_id` | UUID | The campaign this step belongs to |
| `step_type` | string | `email` or `trigger` |
| `name` | string | Step name |
| `sort_order` | integer | Position in the sequence (0-based) |
| `active` | boolean | Whether the step is enabled |
| `schedule_type` | string | `immediate`, `delay`, or `fixed_date` |
| `delay_days` | integer | Days to wait (when schedule_type is `delay`) |
| `fixed_date` | string or null | Target date in YYYY-MM-DD (when schedule_type is `fixed_date`) |
| `email_template_id` | UUID or null | Template to send (for email steps) |
| `sender_name` | string | From name override |
| `sender_email` | string | From email override |
| `trigger_campaign_id` | UUID or null | Campaign to enroll into (for trigger steps) |
| `created_at` | timestamp | When the step was created |
| `updated_at` | timestamp | When the step was last modified |
### Create Step
Add a new step to a campaign. Steps are automatically appended to the end of the sequence.
```
POST /api/v1/campaigns/{id}/steps
```
#### Path Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| `id` | UUID | The campaign's unique ID |
#### Headers
| Header | Required | Description |
|--------|----------|-------------|
| `Authorization` | Yes | `Bearer rlb_your_key` |
| `Content-Type` | Yes | `application/json` |
| `X-Book-ID` | Yes | UUID of the book |
#### Request Body
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `step_type` | string | Yes | `email` or `trigger` |
| `name` | string | Yes | Step name |
| `schedule_type` | string | Yes | `immediate`, `delay`, or `fixed_date` |
| `delay_days` | integer | Conditional | Required when schedule_type is `delay` |
| `fixed_date` | string | Conditional | Required when schedule_type is `fixed_date` (YYYY-MM-DD) |
| `email_template_id` | UUID | Conditional | Required for email steps |
| `sender_name` | string | No | From name override for this step |
| `sender_email` | string | No | From email override for this step |
| `trigger_campaign_id` | UUID | Conditional | Required for trigger steps |
#### Example Request (email step)
```bash
curl -X POST "https://app.relaybook.io/api/v1/campaigns/c1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c/steps" \
-H "Authorization: Bearer rlb_your_key" \
-H "Content-Type: application/json" \
-H "X-Book-ID: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d" \
-d '{
"step_type": "email",
"name": "Welcome Email",
"schedule_type": "immediate",
"email_template_id": "t1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c",
"sender_name": "Acme Team",
"sender_email": "
[email protected]"
}'
```
#### Example Request (delay step)
```bash
curl -X POST "https://app.relaybook.io/api/v1/campaigns/c1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c/steps" \
-H "Authorization: Bearer rlb_your_key" \
-H "Content-Type: application/json" \
-H "X-Book-ID: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d" \
-d '{
"step_type": "email",
"name": "Follow-Up Tips",
"schedule_type": "delay",
"delay_days": 3,
"email_template_id": "t2b3c4d5-e6f7-4a8b-9c0d-1e2f3a4b5c6d"
}'
```
#### Example Request (campaign trigger step)
```bash
curl -X POST "https://app.relaybook.io/api/v1/campaigns/c1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c/steps" \
-H "Authorization: Bearer rlb_your_key" \
-H "Content-Type: application/json" \
-H "X-Book-ID: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d" \
-d '{
"step_type": "trigger",
"name": "Move to Advanced Sequence",
"schedule_type": "delay",
"delay_days": 30,
"trigger_campaign_id": "c2b3c4d5-e6f7-4a8b-9c0d-1e2f3a4b5c6d"
}'
```
#### Response
```
HTTP/1.1 200 OK
```
Returns the full step object with `sort_order` automatically set.
#### Errors
| Status | Code | Cause |
|--------|------|-------|
| 400 | `INVALID_INPUT` | Invalid request body |
| 404 | `NOT_FOUND` | Campaign doesn't exist in this book |
| 500 | `SERVER_ERROR` | Database error |
### Schedule Types
| Type | Description | Required Fields |
|------|-------------|-----------------|
| `immediate` | Executes as soon as the contact is enrolled | None |
| `delay` | Executes X days after enrollment | `delay_days` |
| `fixed_date` | Executes on a specific calendar date | `fixed_date` (YYYY-MM-DD) |
---
## Campaign Participants
### Enroll Contacts
Enroll one or more contacts into a campaign by their contact IDs.
```
POST /api/v1/campaigns/{id}/participants
```
#### Path Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| `id` | UUID | The campaign's unique ID |
#### Headers
| Header | Required | Description |
|--------|----------|-------------|
| `Authorization` | Yes | `Bearer rlb_your_key` |
| `Content-Type` | Yes | `application/json` |
| `X-Book-ID` | Yes | UUID of the book |
#### Request Body
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `contact_ids` | array of UUIDs | Yes | Contact IDs to enroll |
#### Example Request
```bash
curl -X POST "https://app.relaybook.io/api/v1/campaigns/c1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c/participants" \
-H "Authorization: Bearer rlb_your_key" \
-H "Content-Type: application/json" \
-H "X-Book-ID: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d" \
-d '{
"contact_ids": [
"f47ac10b-58cc-4372-a567-0e02b2c3d479",
"b23dc4e5-6789-4abc-def0-123456789abc"
]
}'
```
#### Response
```
HTTP/1.1 200 OK
```
```json
{
"data": {
"enrolled": 2
}
}
```
> [!tip] Duplicate enrollment
> Contacts already enrolled in a campaign are silently skipped. The `enrolled` count reflects only newly added contacts.
#### Errors
| Status | Code | Cause |
|--------|------|-------|
| 400 | `INVALID_INPUT` | Invalid request body or empty contact_ids |
| 404 | `NOT_FOUND` | Campaign doesn't exist in this book |
| 500 | `SERVER_ERROR` | Database error |
---
## Full Example: Create a Campaign via API
Here's a complete workflow to set up a 3-step onboarding campaign:
```bash
# 1. Create the email template
curl -X POST https://app.relaybook.io/api/v1/campaign-templates \
-H "Authorization: Bearer rlb_your_key" \
-H "X-Book-ID: your-book-id" \
-H "Content-Type: application/json" \
-d '{
"name": "Welcome Email",
"subject": "Welcome to {{company}}!",
"body_html": "<p>Hi {{first_name}}, thanks for joining.</p>"
}'
# 2. Create the campaign
curl -X POST https://app.relaybook.io/api/v1/campaigns \
-H "Authorization: Bearer rlb_your_key" \
-H "X-Book-ID: your-book-id" \
-H "Content-Type: application/json" \
-d '{
"name": "Onboarding Sequence",
"description": "3-step welcome drip"
}'
# 3. Add an immediate welcome step
curl -X POST https://app.relaybook.io/api/v1/campaigns/CAMPAIGN_ID/steps \
-H "Authorization: Bearer rlb_your_key" \
-H "X-Book-ID: your-book-id" \
-H "Content-Type: application/json" \
-d '{
"step_type": "email",
"name": "Welcome",
"schedule_type": "immediate",
"email_template_id": "TEMPLATE_ID"
}'
# 4. Add a delayed follow-up step
curl -X POST https://app.relaybook.io/api/v1/campaigns/CAMPAIGN_ID/steps \
-H "Authorization: Bearer rlb_your_key" \
-H "X-Book-ID: your-book-id" \
-H "Content-Type: application/json" \
-d '{
"step_type": "email",
"name": "Getting Started Tips",
"schedule_type": "delay",
"delay_days": 3,
"email_template_id": "TIPS_TEMPLATE_ID"
}'
# 5. Activate the campaign
curl -X PATCH https://app.relaybook.io/api/v1/campaigns/CAMPAIGN_ID \
-H "Authorization: Bearer rlb_your_key" \
-H "X-Book-ID: your-book-id" \
-H "Content-Type: application/json" \
-d '{"status": "active"}'
# 6. Enroll contacts
curl -X POST https://app.relaybook.io/api/v1/campaigns/CAMPAIGN_ID/participants \
-H "Authorization: Bearer rlb_your_key" \
-H "X-Book-ID: your-book-id" \
-H "Content-Type: application/json" \
-d '{"contact_ids": ["CONTACT_ID_1", "CONTACT_ID_2"]}'
```
---
**Next:** Learn about [[Bulk Operations]] for managing contacts at scale, or [[Webhooks]] for real-time event notifications.