Skip to main content

Campaigns API

Campaign lifecycle management, scheduling, and statistics.


List Campaigns

GET /campaigns

Query Parameters

ParameterTypeDescription
tenantIdstringRequired
clubIdstringFilter by club
statusstringDRAFT, SCHEDULED, ACTIVE, PAUSED, COMPLETED, CANCELLED
typestringONE_TIME, RECURRING, TRIGGERED, JOURNEY

Response: 200 OK

{
"data": [{
"id": "campaign_123",
"name": "Summer Tournament Promo",
"type": "ONE_TIME",
"status": "SCHEDULED",
"channels": ["EMAIL", "SMS"],
"segmentId": "segment_456",
"scheduledAt": "2025-12-20T09:00:00Z",
"targetCount": 500,
"sentCount": 0,
"openRate": null,
"createdAt": "2025-12-14T10:00:00Z"
}]
}

Get Campaign

GET /campaigns/:id

Response: 200 OK

{
"id": "campaign_123",
"tenantId": "tenant_123",
"clubId": "club_456",
"name": "Summer Tournament Promo",
"description": "Promotion for upcoming summer tournament",
"type": "ONE_TIME",
"status": "SCHEDULED",
"channels": ["EMAIL", "SMS"],
"segmentId": "segment_456",
"segmentName": "Active Golfers",
"emailTemplateId": "template_email_123",
"smsTemplateId": "template_sms_456",
"scheduledAt": "2025-12-20T09:00:00Z",
"timezone": "Africa/Johannesburg",
"targetCount": 500,
"sentCount": 0,
"deliveredCount": 0,
"openedCount": 0,
"clickedCount": 0,
"createdBy": "user_123",
"createdAt": "2025-12-14T10:00:00Z",
"updatedAt": "2025-12-14T10:00:00Z"
}

Create Campaign

POST /campaigns

Request Body

{
"tenantId": "tenant_123",
"clubId": "club_456",
"name": "December Newsletter",
"description": "Monthly member newsletter",
"type": "ONE_TIME",
"segmentId": "segment_123",
"channels": ["EMAIL", "SMS"],
"emailTemplateId": "template_email_123",
"smsTemplateId": "template_sms_456",
"timezone": "Africa/Johannesburg"
}

Response: 201 Created


Update Campaign

PATCH /campaigns/:id

Request Body

{
"name": "Updated Campaign Name",
"description": "Updated description",
"segmentId": "segment_789"
}

Response: 200 OK

Note: Only DRAFT campaigns can have their segment or templates changed.


Schedule Campaign

POST /campaigns/:id/schedule

Request Body

{
"scheduledAt": "2025-12-20T09:00:00Z"
}

Response: 200 OK

{
"id": "campaign_123",
"status": "SCHEDULED",
"scheduledAt": "2025-12-20T09:00:00Z",
"targetCount": 500
}

Execute Campaign Immediately

POST /campaigns/:id/execute

Response: 200 OK

{
"id": "campaign_123",
"status": "ACTIVE",
"startedAt": "2025-12-14T10:00:00Z",
"targetCount": 500
}

Pause Campaign

Pauses an active campaign.

POST /campaigns/:id/pause

Response: 200 OK

{
"id": "campaign_123",
"status": "PAUSED",
"pausedAt": "2025-12-14T10:30:00Z",
"sentCount": 250
}

Resume Campaign

Resumes a paused campaign.

POST /campaigns/:id/resume

Response: 200 OK

{
"id": "campaign_123",
"status": "ACTIVE",
"resumedAt": "2025-12-14T11:00:00Z"
}

Cancel Campaign

Cancels a scheduled or active campaign.

POST /campaigns/:id/cancel

Response: 200 OK

{
"id": "campaign_123",
"status": "CANCELLED",
"cancelledAt": "2025-12-14T10:00:00Z",
"sentCount": 0
}

Get Campaign Stats

GET /campaigns/:id/stats

Response: 200 OK

{
"campaignId": "campaign_123",
"targetCount": 500,
"sentCount": 485,
"deliveredCount": 478,
"openedCount": 215,
"clickedCount": 89,
"convertedCount": 12,
"unsubscribedCount": 3,
"bouncedCount": 7,
"deliveryRate": 0.9856,
"openRate": 0.4498,
"clickRate": 0.4140,
"conversionRate": 0.1348,
"byChannel": {
"EMAIL": {
"sent": 485,
"delivered": 478,
"opened": 215,
"clicked": 89,
"bounced": 7
},
"SMS": {
"sent": 380,
"delivered": 375,
"failed": 5
}
},
"timeline": [
{ "hour": "2025-12-14T09:00:00Z", "sent": 100, "opened": 45 },
{ "hour": "2025-12-14T10:00:00Z", "sent": 385, "opened": 120 }
]
}

Get Campaign Interactions

GET /campaigns/:id/interactions

Query Parameters

ParameterTypeDescription
typestringSENT, DELIVERED, OPENED, CLICKED, CONVERTED, UNSUBSCRIBED, BOUNCED
skipnumberOffset
takenumberLimit

Response: 200 OK

{
"data": [{
"id": "interaction_123",
"customerId": "customer_456",
"customerEmail": "john@example.com",
"customerName": "John Smith",
"type": "CLICKED",
"channel": "EMAIL",
"occurredAt": "2025-12-14T09:15:30Z",
"metadata": {
"linkId": "link_123",
"linkUrl": "https://example.com/offer"
}
}],
"meta": { "total": 89, "skip": 0, "take": 25 }
}

Campaign Types

ONE_TIME

Single send to a segment at a specific time.

{
"type": "ONE_TIME",
"segmentId": "segment_123",
"scheduledAt": "2025-12-20T09:00:00Z"
}

RECURRING

Repeating campaign on a schedule.

{
"type": "RECURRING",
"segmentId": "segment_123",
"schedule": {
"frequency": "weekly",
"dayOfWeek": 1,
"time": "09:00",
"timezone": "Africa/Johannesburg"
}
}

TRIGGERED

Sent in response to an event.

{
"type": "TRIGGERED",
"triggerEvent": "scl.member.tier.changed",
"triggerConditions": {
"reason": "upgrade"
}
}

JOURNEY

Part of a multi-step journey (managed via Journeys API).


Status Transitions

DRAFT → SCHEDULED → ACTIVE → COMPLETED
↘ PAUSED ↗
↘ CANCELLED
FromToAction
DRAFTSCHEDULEDPOST /campaigns/:id/schedule
DRAFTACTIVEPOST /campaigns/:id/execute
SCHEDULEDACTIVEAutomatic at scheduled time
SCHEDULEDCANCELLEDPOST /campaigns/:id/cancel
ACTIVEPAUSEDPOST /campaigns/:id/pause
ACTIVECOMPLETEDAutomatic when all messages sent
PAUSEDACTIVEPOST /campaigns/:id/resume
PAUSEDCANCELLEDPOST /campaigns/:id/cancel