Campaigns API

The Campaigns API manages one-time email broadcasts to a marketing list or saved view. Create a campaign, give it content + an audience + a sending integration, then schedule or send it. The campaign-scheduler cron performs the actual delivery.

REST API. Authenticated with Authorization: Bearer rk_live_…. Successful responses are wrapped in { "data": … }.

Required Scopes

ScopeGrants
campaigns:readList/view campaigns and stats
campaigns:writeCreate, update, schedule, send, cancel, and test campaigns

Campaign Object

{
  id: string;
  organization_id: string;
  name: string;
  subject?: string | null;
  body_html?: string | null;
  body_text?: string | null;
  view_id?: string | null;        // saved-view audience
  list_id?: string | null;        // marketing-list audience
  integration_id?: string | null; // sending integration (channel_integrations)
  from_name?: string | null;
  from_email?: string | null;
  reply_to_email?: string | null;
  status: 'draft' | 'scheduled' | 'sending' | 'sent' | 'cancelled' | 'failed';
  scheduled_at?: string | null;
  total_recipients: number;
  total_sent: number;
  total_opened: number;
  total_clicked: number;
  total_bounced: number;
  total_failed: number;
  created_at: string;
}

List / Get Campaigns

GET /api/v1/campaigns — query params status, limit, offset. Scope: campaigns:read.

GET /api/v1/campaigns/:id — single campaign. Scope: campaigns:read.

curl "https://crm.switchlabs.dev/api/v1/campaigns?status=draft" \
  -H "Authorization: Bearer rk_live_xxx"

Create Campaign

POST /api/v1/campaigns

Scope: campaigns:write

Created as a draft. Provide an audience (list_id or view_id) and integration_id before scheduling/sending.

Body:

{
  name: string;                  // required
  subject?: string;
  body_html?: string;
  body_text?: string;
  body_json?: any;
  template_id?: string;          // UUID
  view_id?: string;              // saved-view audience
  list_id?: string;              // marketing-list audience
  integration_id?: string;       // sending integration
  from_name?: string;
  from_email?: string;
  reply_to_email?: string;
}
curl -X POST "https://crm.switchlabs.dev/api/v1/campaigns" \
  -H "Authorization: Bearer rk_live_xxx" -H "Content-Type: application/json" \
  -d '{ "name": "Launch announcement", "subject": "We just shipped", "body_html": "<p>Hi {{first_name}}</p>", "list_id": "LIST_ID", "integration_id": "INT_ID" }'

Update / Delete Campaign

PATCH /api/v1/campaigns/:id — update content/audience/integration fields. Only draft or scheduled campaigns are editable (400 otherwise). Scope: campaigns:write.

DELETE /api/v1/campaigns/:id — delete. Only draft campaigns can be deleted (400 otherwise). Returns 204. Scope: campaigns:write.


Schedule / Send / Cancel

POST /api/v1/campaigns/:id/schedule — body { "scheduled_at": "2026-07-01T15:00:00Z" }. Schedules for a future time. Scope: campaigns:write.

POST /api/v1/campaigns/:id/send — send immediately (hands off to the scheduler cron now). Scope: campaigns:write.

POST /api/v1/campaigns/:id/cancel — cancel a scheduled or sending campaign; deletes still-queued messages (already-sent messages are left alone). Scope: campaigns:write.

Before scheduling/sending, a campaign must have: a subject + HTML body, an audience (list_id or view_id), and a integration_id that resolves to a from-address. Otherwise these return 400 with the specific reason.

curl -X POST "https://crm.switchlabs.dev/api/v1/campaigns/CAMPAIGN_ID/send" \
  -H "Authorization: Bearer rk_live_xxx"
# -> { "data": { "queued": 0, "scheduled": true, "total_recipients": 240 } }

Test Send

POST /api/v1/campaigns/:id/test — body { "test_email": "you@example.com" }. Sends a single [TEST] copy with sample merge data ({{first_name}}, {{company}}, etc.) substituted. Scope: campaigns:write.


Stats

GET /api/v1/campaigns/:id/stats — delivery/engagement counters. Scope: campaigns:read.

{ "data": { "total_recipients": 240, "total_sent": 240, "total_opened": 96, "total_clicked": 31, "total_bounced": 2, "total_failed": 0 } }

See also: Sequences · Marketing Lists