Skip to main content

Campaigns

Base path: /api/campaigns

GET /campaigns

List all campaigns.

Auth: Admin

Query parameters: page, limit

Response: Array of campaign objects.


POST /campaigns

Create a new campaign.

Auth: Admin

Request body:

FieldTypeRequiredDescription
namestringYesInternal campaign name
subjectstringYesEmail subject line
blocksarrayYesEmail builder block array
segment_filtersobjectNoAudience filter criteria

GET /campaigns/:id

Get a single campaign with details.


PUT /campaigns/:id

Update a campaign.


DELETE /campaigns/:id

Delete a campaign.


POST /campaigns/:id/send

Send the campaign to all matching recipients.

Auth: Admin

Builds the recipient list from segment_filters, then enqueues one email job per recipient in the job_queue for background processing by the worker. The worker renders the blocks array via MJML before sending.


Segments

GET /campaigns/segments

List saved audience segments.

POST /campaigns/segments

Save an audience segment for reuse.

FieldTypeRequired
namestringYes
filtersobjectYes

DELETE /campaigns/segments/:id

Delete a saved segment.


Templates

GET /campaigns/templates

List saved email templates.

POST /campaigns/templates

Save an email template.

FieldTypeRequired
namestringYes
blocksarrayYes

DELETE /campaigns/templates/:id

Delete a template.


POST /campaigns/render-mjml

Render MJML email to HTML for preview.

Auth: Admin

Request body:

{
"mjml": "<mjml><mj-body>...</mj-body></mjml>"
}

Response:

{
"html": "<html>...</html>"
}

Segment Filter Fields

The segment_filters object (and filters in saved segments) supports the following fields. All fields are optional and combined with AND logic.

FieldTypeDescription
has_emailbooleanOnly clients with a non-empty email address
has_phonebooleanOnly clients with a non-empty phone number
labelsarray of stringsClients assigned any of the given label names
last_visit_days_agointegerClients whose last completed booking was more than N days ago (or who have no bookings)
min_total_spentnumberMinimum lifetime spend across all POS orders
max_total_spentnumberMaximum lifetime spend across all POS orders
birthday_monthsarray of integersClients whose birthday falls in any of the given months (1=January, 12=December)
service_category_idintegerClients who have booked a service in this category
min_visitsintegerMinimum number of completed bookings
max_visitsintegerMaximum number of completed bookings
genderstringFilter by client gender value (e.g. male, female)
note

The segment filter is applied at send time. The field names used in the actual server code (last_visit_days_ago, min_total_spent, birthday_months, etc.) are what you must use in API requests. The UI may show friendlier labels.