API referenceCampaigns

Campaigns

11 operations. Every schema and example on this page is generated from the platform contract.

List email campaigns.

The store’s campaigns, newest first, with the deliverability-suspension flag the composer must surface.

Parameters

store_idstring · uuidqueryrequired

Authorises the merchant; campaigns are store-scoped.

Response, 200

campaignsarray of objectrequired
14 child fields
idstringrequired
namestringrequired
subjectstringrequired
template_typestringrequired
target_typeenumrequired
allsegmentmanual
statusstringrequired
scheduled_atstring, nullablerequired
sent_atstring, nullablerequired
total_recipientsnumberrequired
total_sentnumberrequired
total_deliverednumberrequired
total_openednumberrequired
total_clickednumberrequired
created_atstringrequired
email_sending_suspendedbooleanrequired

True when deliverability protection has paused this store’s marketing sends.

curl -G "https://www.membber.com/api/v1/campaigns" \
  -H "Authorization: Bearer $MEMBBER_TOKEN" \
  --data-urlencode "store_id=6659c139-0000-4000-8000-d0c500000066"
Response, 200
{
  "campaigns": [
    {
      "id": "00000d1b-0000-4000-8000-d0c500000000",
      "name": "Example name",
      "subject": "<subject>",
      "template_type": "<template_type>",
      "target_type": "all",
      "status": "<status>",
      "scheduled_at": "<scheduled_at>",
      "sent_at": "<sent_at>",
      "total_recipients": 1,
      "total_sent": 1,
      "total_delivered": 1,
      "total_opened": 1,
      "total_clicked": 1,
      "created_at": "<created_at>"
    }
  ],
  "email_sending_suspended": true
}

Create a draft campaign.

Creates a draft. Nothing sends until the send endpoint is called.

Request body

store_idstring · uuidrequired
namestringrequired
subjectstringoptional
preview_textstringoptional
template_typeenumoptional
custompromowe_miss_youeventupdate
html_contentstringoptional

Custom template only; branded templates render server-side.

target_typeenumoptional
allsegmentmanual
target_filterobjectoptional

Ad-hoc audience filter (there are no stored segments); resolved live at send time.

5 child fields
engagement_tiersarray of enumoptional
championloyalregularcasualnew
churn_risksarray of enumoptional
nonelowmediumhigh
min_stampsintegeroptional
max_stampsintegeroptional
days_inactiveintegeroptional
target_customer_idsarray of string · uuidoptional
headlinestring, nullableoptional

The merchant’s own headline. Replaces the hardcoded ‘Special Offer’.

body_textstring, nullableoptional

The merchant’s own message. One paragraph per line; {{first_name}}/{{store_name}} survive to send time.

offer_detailstring, nullableoptional

WHAT THE OFFER IS, in their words: “2 for 1 on all pastries”. The only thing the highlighted box may contain.

promo_codestring, nullableoptional

The code a member shows or types. Rendered in its own block.

offer_expires_atstring · date-time, nullableoptional

When it ends. Printed in the STORE’s timezone, never UTC. Empty string clears it.

image_urlstring · uri, nullableoptional

The merchant’s own photo of what is on offer. https only; missing means no image, never a grey box. Empty string clears it.

cta_labelstring, nullableoptional

The button’s words. Omit for the template’s own default.

cta_urlstring · uri, nullableoptional

Where the button goes. Omit for the store’s own page, then their website. NEVER the platform homepage. Empty string clears it.

Response, 200

campaignobjectrequired
28 child fields
idstringrequired
namestringrequired
subjectstringrequired
template_typestringrequired
target_typeenumrequired
allsegmentmanual
statusstringrequired
scheduled_atstring, nullablerequired
sent_atstring, nullablerequired
total_recipientsnumberrequired
total_sentnumberrequired
total_deliverednumberrequired
total_openednumberrequired
total_clickednumberrequired
created_atstringrequired
preview_textstringrequired
html_contentstringrequired
target_filterobjectrequired
target_customer_idsarray of stringrequired
total_bouncednumberrequired
total_unsubscribednumberrequired
headlinestring, nullableoptional

The merchant’s own headline. Replaces the hardcoded ‘Special Offer’.

body_textstring, nullableoptional

The merchant’s own message. One paragraph per line; {{first_name}}/{{store_name}} survive to send time.

offer_detailstring, nullableoptional

WHAT THE OFFER IS, in their words: “2 for 1 on all pastries”. The only thing the highlighted box may contain.

promo_codestring, nullableoptional

The code a member shows or types. Rendered in its own block.

offer_expires_atstring · date-time, nullableoptional

When it ends. Printed in the STORE’s timezone, never UTC. Empty string clears it.

image_urlstring · uri, nullableoptional

The merchant’s own photo of what is on offer. https only; missing means no image, never a grey box. Empty string clears it.

cta_labelstring, nullableoptional

The button’s words. Omit for the template’s own default.

cta_urlstring · uri, nullableoptional

Where the button goes. Omit for the store’s own page, then their website. NEVER the platform homepage. Empty string clears it.

curl -X POST "https://www.membber.com/api/v1/campaigns" \
  -H "Authorization: Bearer $MEMBBER_TOKEN" \
  -H "Idempotency-Key: 1f0e2d3c-4b5a-4678-9abc-def012345678" \
  -H "Content-Type: application/json" \
  -d '{
    "store_id": "6659c139-0000-4000-8000-d0c500000066",
    "name": "Example name"
  }'
Response, 200
{
  "campaign": {
    "id": "00000d1b-0000-4000-8000-d0c500000000",
    "name": "Example name",
    "subject": "<subject>",
    "template_type": "<template_type>",
    "target_type": "all",
    "status": "<status>",
    "scheduled_at": "<scheduled_at>",
    "sent_at": "<sent_at>",
    "total_recipients": 1,
    "total_sent": 1,
    "total_delivered": 1,
    "total_opened": 1,
    "total_clicked": 1,
    "created_at": "<created_at>",
    "preview_text": "<preview_text>",
    "html_content": "<html_content>",
    "target_filter": {},
    "target_customer_ids": [
      "dde07b6e-0000-4000-8000-d0c5000000dd"
    ],
    "total_bounced": 1,
    "total_unsubscribed": 1,
    "headline": "<headline>",
    "body_text": "<body_text>",
    "offer_detail": "<offer_detail>",
    "promo_code": "EXAMPLE10",
    "offer_expires_at": "2026-07-01T09:00:00Z",
    "image_url": "https://example.com",
    "cta_label": "<cta_label>",
    "cta_url": "https://example.com"
  }
}

Live audience count for a filter.

Matched vs reachable (consent-filtered) counts. Requires the segmentation entitlement for filters.

Request body

store_idstring · uuidrequired
target_typeenumrequired
allsegment
target_filterobjectoptional

Ad-hoc audience filter (there are no stored segments); resolved live at send time.

5 child fields
engagement_tiersarray of enumoptional
championloyalregularcasualnew
churn_risksarray of enumoptional
nonelowmediumhigh
min_stampsintegeroptional
max_stampsintegeroptional
days_inactiveintegeroptional

Response, 200

matchednumberrequired

Members matching the filter.

reachablenumberrequired

The REAL sendable number after consent/bounce/suppression filtering, show this one.

curl -X POST "https://www.membber.com/api/v1/campaigns/audience-preview" \
  -H "Authorization: Bearer $MEMBBER_TOKEN" \
  -H "Idempotency-Key: 1f0e2d3c-4b5a-4678-9abc-def012345678" \
  -H "Content-Type: application/json" \
  -d '{
    "store_id": "6659c139-0000-4000-8000-d0c500000066",
    "target_type": "all"
  }'
Response, 200
{
  "matched": 1,
  "reachable": 1
}

Cancel a scheduled campaign.

Scheduled → cancelled before the cron picks it up. Sent campaigns cannot be cancelled.

Request body

store_idstring · uuidrequired
campaign_idstring · uuidrequired

Response, 200

statusstringrequired
curl -X POST "https://www.membber.com/api/v1/campaigns/cancel" \
  -H "Authorization: Bearer $MEMBBER_TOKEN" \
  -H "Idempotency-Key: 1f0e2d3c-4b5a-4678-9abc-def012345678" \
  -H "Content-Type: application/json" \
  -d '{
    "store_id": "6659c139-0000-4000-8000-d0c500000066",
    "campaign_id": "7c3416aa-0000-4000-8000-d0c50000007c"
  }'
Response, 200
{
  "status": "<status>"
}

Delete a draft or cancelled campaign.

Drafts and cancelled campaigns only. A sent campaign keeps its delivery record and can never be deleted; a scheduled one must be cancelled first.

Request body

store_idstring · uuidrequired
campaign_idstring · uuidrequired

Response, 200

okbooleanrequired
curl -X POST "https://www.membber.com/api/v1/campaigns/delete" \
  -H "Authorization: Bearer $MEMBBER_TOKEN" \
  -H "Idempotency-Key: 1f0e2d3c-4b5a-4678-9abc-def012345678" \
  -H "Content-Type: application/json" \
  -d '{
    "store_id": "6659c139-0000-4000-8000-d0c500000066",
    "campaign_id": "7c3416aa-0000-4000-8000-d0c50000007c"
  }'
Response, 200
{
  "ok": true
}

Campaign detail + live stats.

Full campaign row including delivery/open/click rollups.

Parameters

store_idstring · uuidqueryrequired
campaign_idstring · uuidqueryrequired

Response, 200

campaignobjectrequired
28 child fields
idstringrequired
namestringrequired
subjectstringrequired
template_typestringrequired
target_typeenumrequired
allsegmentmanual
statusstringrequired
scheduled_atstring, nullablerequired
sent_atstring, nullablerequired
total_recipientsnumberrequired
total_sentnumberrequired
total_deliverednumberrequired
total_openednumberrequired
total_clickednumberrequired
created_atstringrequired
preview_textstringrequired
html_contentstringrequired
target_filterobjectrequired
target_customer_idsarray of stringrequired
total_bouncednumberrequired
total_unsubscribednumberrequired
headlinestring, nullableoptional

The merchant’s own headline. Replaces the hardcoded ‘Special Offer’.

body_textstring, nullableoptional

The merchant’s own message. One paragraph per line; {{first_name}}/{{store_name}} survive to send time.

offer_detailstring, nullableoptional

WHAT THE OFFER IS, in their words: “2 for 1 on all pastries”. The only thing the highlighted box may contain.

promo_codestring, nullableoptional

The code a member shows or types. Rendered in its own block.

offer_expires_atstring · date-time, nullableoptional

When it ends. Printed in the STORE’s timezone, never UTC. Empty string clears it.

image_urlstring · uri, nullableoptional

The merchant’s own photo of what is on offer. https only; missing means no image, never a grey box. Empty string clears it.

cta_labelstring, nullableoptional

The button’s words. Omit for the template’s own default.

cta_urlstring · uri, nullableoptional

Where the button goes. Omit for the store’s own page, then their website. NEVER the platform homepage. Empty string clears it.

email_sending_suspendedbooleanrequired
curl -G "https://www.membber.com/api/v1/campaigns/detail" \
  -H "Authorization: Bearer $MEMBBER_TOKEN" \
  --data-urlencode "store_id=6659c139-0000-4000-8000-d0c500000066" \
  --data-urlencode "campaign_id=7c3416aa-0000-4000-8000-d0c50000007c"
Response, 200
{
  "campaign": {
    "id": "00000d1b-0000-4000-8000-d0c500000000",
    "name": "Example name",
    "subject": "<subject>",
    "template_type": "<template_type>",
    "target_type": "all",
    "status": "<status>",
    "scheduled_at": "<scheduled_at>",
    "sent_at": "<sent_at>",
    "total_recipients": 1,
    "total_sent": 1,
    "total_delivered": 1,
    "total_opened": 1,
    "total_clicked": 1,
    "created_at": "<created_at>",
    "preview_text": "<preview_text>",
    "html_content": "<html_content>",
    "target_filter": {},
    "target_customer_ids": [
      "dde07b6e-0000-4000-8000-d0c5000000dd"
    ],
    "total_bounced": 1,
    "total_unsubscribed": 1,
    "headline": "<headline>",
    "body_text": "<body_text>",
    "offer_detail": "<offer_detail>",
    "promo_code": "EXAMPLE10",
    "offer_expires_at": "2026-07-01T09:00:00Z",
    "image_url": "https://example.com",
    "cta_label": "<cta_label>",
    "cta_url": "https://example.com"
  },
  "email_sending_suspended": true
}

Rendered HTML preview.

Server-rendered branded HTML with sample personalisation tokens, the composer shows this in a web view.

Parameters

store_idstring · uuidqueryrequired
campaign_idstring · uuidqueryrequired

Response, 200

htmlstringrequired
curl -G "https://www.membber.com/api/v1/campaigns/preview" \
  -H "Authorization: Bearer $MEMBBER_TOKEN" \
  --data-urlencode "store_id=6659c139-0000-4000-8000-d0c500000066" \
  --data-urlencode "campaign_id=7c3416aa-0000-4000-8000-d0c50000007c"
Response, 200
{
  "html": "<html>"
}

Send now or schedule.

Queues the campaign to the consent-filtered marketable audience (unsubscribed, withdrawn, bounced and anonymized members are always excluded). Suspended stores queue nothing, check the suspension flag first.

Request body

store_idstring · uuidrequired
campaign_idstring · uuidrequired
scheduled_atstring · date-timeoptional

Omit to send now; ISO datetime to schedule.

Response, 200

statusstringrequired
total_recipientsnumber, nullablerequired
curl -X POST "https://www.membber.com/api/v1/campaigns/send" \
  -H "Authorization: Bearer $MEMBBER_TOKEN" \
  -H "Idempotency-Key: 1f0e2d3c-4b5a-4678-9abc-def012345678" \
  -H "Content-Type: application/json" \
  -d '{
    "store_id": "6659c139-0000-4000-8000-d0c500000066",
    "campaign_id": "7c3416aa-0000-4000-8000-d0c50000007c"
  }'
Response, 200
{
  "status": "<status>",
  "total_recipients": 1
}

Available campaign templates.

The branded template pick-list (promo, win-back, event, update, custom).

Parameters

store_idstring · uuidqueryrequired

Response, 200

templatesarray of objectrequired
3 child fields
typestringrequired
namestringrequired
descriptionstringrequired
curl -G "https://www.membber.com/api/v1/campaigns/templates" \
  -H "Authorization: Bearer $MEMBBER_TOKEN" \
  --data-urlencode "store_id=6659c139-0000-4000-8000-d0c500000066"
Response, 200
{
  "templates": [
    {
      "type": "<type>",
      "name": "Example name",
      "description": "Added at the front desk"
    }
  ]
}

Send a test to the merchant.

Renders with sample tokens and sends to the signed-in merchant’s own email, subject-prefixed [TEST].

Request body

store_idstring · uuidrequired
campaign_idstring · uuidrequired

Response, 200

sent_tostringrequired
curl -X POST "https://www.membber.com/api/v1/campaigns/test" \
  -H "Authorization: Bearer $MEMBBER_TOKEN" \
  -H "Idempotency-Key: 1f0e2d3c-4b5a-4678-9abc-def012345678" \
  -H "Content-Type: application/json" \
  -d '{
    "store_id": "6659c139-0000-4000-8000-d0c500000066",
    "campaign_id": "7c3416aa-0000-4000-8000-d0c50000007c"
  }'
Response, 200
{
  "sent_to": "<sent_to>"
}

Edit a draft campaign.

Drafts only, scheduled/sent campaigns are immutable (cancel first).

Request body

store_idstring · uuidrequired
campaign_idstring · uuidrequired
namestringoptional
subjectstringoptional
preview_textstringoptional
template_typeenumoptional
custompromowe_miss_youeventupdate
html_contentstringoptional
target_typeenumoptional
allsegmentmanual
target_filterobjectoptional

Ad-hoc audience filter (there are no stored segments); resolved live at send time.

5 child fields
engagement_tiersarray of enumoptional
championloyalregularcasualnew
churn_risksarray of enumoptional
nonelowmediumhigh
min_stampsintegeroptional
max_stampsintegeroptional
days_inactiveintegeroptional
target_customer_idsarray of string · uuidoptional
headlinestring, nullableoptional

The merchant’s own headline. Replaces the hardcoded ‘Special Offer’.

body_textstring, nullableoptional

The merchant’s own message. One paragraph per line; {{first_name}}/{{store_name}} survive to send time.

offer_detailstring, nullableoptional

WHAT THE OFFER IS, in their words: “2 for 1 on all pastries”. The only thing the highlighted box may contain.

promo_codestring, nullableoptional

The code a member shows or types. Rendered in its own block.

offer_expires_atstring · date-time, nullableoptional

When it ends. Printed in the STORE’s timezone, never UTC. Empty string clears it.

image_urlstring · uri, nullableoptional

The merchant’s own photo of what is on offer. https only; missing means no image, never a grey box. Empty string clears it.

cta_labelstring, nullableoptional

The button’s words. Omit for the template’s own default.

cta_urlstring · uri, nullableoptional

Where the button goes. Omit for the store’s own page, then their website. NEVER the platform homepage. Empty string clears it.

Response, 200

campaignobjectrequired
28 child fields
idstringrequired
namestringrequired
subjectstringrequired
template_typestringrequired
target_typeenumrequired
allsegmentmanual
statusstringrequired
scheduled_atstring, nullablerequired
sent_atstring, nullablerequired
total_recipientsnumberrequired
total_sentnumberrequired
total_deliverednumberrequired
total_openednumberrequired
total_clickednumberrequired
created_atstringrequired
preview_textstringrequired
html_contentstringrequired
target_filterobjectrequired
target_customer_idsarray of stringrequired
total_bouncednumberrequired
total_unsubscribednumberrequired
headlinestring, nullableoptional

The merchant’s own headline. Replaces the hardcoded ‘Special Offer’.

body_textstring, nullableoptional

The merchant’s own message. One paragraph per line; {{first_name}}/{{store_name}} survive to send time.

offer_detailstring, nullableoptional

WHAT THE OFFER IS, in their words: “2 for 1 on all pastries”. The only thing the highlighted box may contain.

promo_codestring, nullableoptional

The code a member shows or types. Rendered in its own block.

offer_expires_atstring · date-time, nullableoptional

When it ends. Printed in the STORE’s timezone, never UTC. Empty string clears it.

image_urlstring · uri, nullableoptional

The merchant’s own photo of what is on offer. https only; missing means no image, never a grey box. Empty string clears it.

cta_labelstring, nullableoptional

The button’s words. Omit for the template’s own default.

cta_urlstring · uri, nullableoptional

Where the button goes. Omit for the store’s own page, then their website. NEVER the platform homepage. Empty string clears it.

curl -X POST "https://www.membber.com/api/v1/campaigns/update" \
  -H "Authorization: Bearer $MEMBBER_TOKEN" \
  -H "Idempotency-Key: 1f0e2d3c-4b5a-4678-9abc-def012345678" \
  -H "Content-Type: application/json" \
  -d '{
    "store_id": "6659c139-0000-4000-8000-d0c500000066",
    "campaign_id": "7c3416aa-0000-4000-8000-d0c50000007c"
  }'
Response, 200
{
  "campaign": {
    "id": "00000d1b-0000-4000-8000-d0c500000000",
    "name": "Example name",
    "subject": "<subject>",
    "template_type": "<template_type>",
    "target_type": "all",
    "status": "<status>",
    "scheduled_at": "<scheduled_at>",
    "sent_at": "<sent_at>",
    "total_recipients": 1,
    "total_sent": 1,
    "total_delivered": 1,
    "total_opened": 1,
    "total_clicked": 1,
    "created_at": "<created_at>",
    "preview_text": "<preview_text>",
    "html_content": "<html_content>",
    "target_filter": {},
    "target_customer_ids": [
      "dde07b6e-0000-4000-8000-d0c5000000dd"
    ],
    "total_bounced": 1,
    "total_unsubscribed": 1,
    "headline": "<headline>",
    "body_text": "<body_text>",
    "offer_detail": "<offer_detail>",
    "promo_code": "EXAMPLE10",
    "offer_expires_at": "2026-07-01T09:00:00Z",
    "image_url": "https://example.com",
    "cta_label": "<cta_label>",
    "cta_url": "https://example.com"
  }
}
WhatsApp
Book a Call
Start Free