Campaigns
Create campaigns, choose their audiences and segments, and send or schedule them.
Create a campaign
Creates a campaign in draft status. Requires an API key with the full scope. Emits a campaign.created event.
A new campaign has no recipients. Choose its audiences and segments with Update a campaign, then send or schedule it. Credits are charged when the campaign sends: 2 credits per email.
/campaignsBody parameters
namestringrequiredsubjectstring{{first_name}}.from_emailstringnews@acme.com.from_namestringAcme. The message is sent from Acme <news@acme.com>.reply_tostringfrom_email when the campaign sends.htmlstring{{first_name}}, {{last_name}}, {{email}}, {{unsubscribe_url}} and {{cf.<key>}} for custom fields, with fallbacks and {{#if}} blocks. Set the body when you create the campaign.textstringhtml.preview_textstring<mj-preview>).contentstringhtml nor text and content_type is html or text, Emailit sends content as the HTML or plain-text body.content_typestringdefault: htmlcontent: html, text or mjml. For the Emailit team, Emailit compiles mjml content into html (alpha). For everyone else mjml is a label: send the compiled HTML in html.utm_trackingbooleandefault: falsetrue to add UTM parameters to every http and https link when the campaign sends, so your web analytics credit the campaign. Parameters a link already has are kept, and unsubscribe and web version links aren’t changed. See Sending options.utm_paramsobject | nullUTM values to use when utm_tracking is on. Each key sets one utm_ parameter:
source(defaultemailit),medium(defaultemail) andcampaign(default{campaign_name}).content,termandid, not added by default.
Values are text up to 191 characters and can contain the tokens {campaign_name} (the campaign name in lowercase, with dashes), {campaign_id}, {subject}, {variant} (the A/B test variant name) and {send_date} (YYYY-MM-DD). Unknown keys and tokens return 422. Keys you don’t set keep their defaults; null or {} resets all of them.
smart_sending_hoursinteger | nullnull (default) turns smart sending off. Checked when the campaign starts sending. Emails from automations and the Email API don’t count.exclude_unengagedbooleandefault: falsetrue to skip contacts who were sent 3 or more campaign emails in the last 90 days and opened or clicked none of them.tagsstring[]tags replaces the list.send_strategystringdefault: immediateimmediate, throttled, local_time or smart_time. Stored with the campaign and used when you send it without a strategy.send_optionsobject | nullsend_strategy, stored as given and checked in full when the campaign is sent. See Send or schedule a campaign.ab_testobject | nullAn A/B test of 2 to 5 variants. A random share of the recipients is split evenly across the variants. After duration_hours, the rest of the recipients get the variant with the best result. While the test runs, the campaign’s status is testing. A/B tests send with the immediate strategy, now or at a scheduled time.
enabled(boolean, defaulttrue):falseturns the test off.winner_metric(string, defaultopened):opened,clicked,orders(credited orders per email sent) orrevenue(credited revenue per email sent).ordersandrevenueare part of Commerce, which is in alpha: other requests return403witherror: "commerce_alpha".test_size_percent(integer, default20): share of the recipients in the test, from 10 to 100. At 100, everyone is in the test and no winner is sent.duration_hours(integer, default4): how long the test runs before the winner is sent, from 1 to 168.variants(object[], required): 2 to 5 variants. Each can setname(up to 100 characters, defaults toA,B,Cand so on),subject,preview_text,from_name,from_email,reply_to,htmlandtext. Fields a variant leaves out come from the campaign. At least one variant must set a subject, preview text, sender name or address, or body.
Returns
Returns 201 Created with the campaign object. status is draft. The response doesn’t echo html, text or content. It includes the settings above, send_completes_at and send_summary (both null until the campaign sends), and ab_test with the variants and their IDs (cvr_…). See Retrieve a campaign.
Returns 400 if name is missing, 403 if the API key doesn’t have the full scope, and 422 if a setting or the A/B test is invalid.
{
"object": "campaign",
"id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
"name": "October newsletter",
"status": "draft",
"subject": "October news for {{first_name}}",
"from_email": "news@acme.com",
"from_name": "Acme",
"reply_to": "support@acme.com",
"preview_text": null,
"content_type": "html",
"created_at": "2026-10-01T09:30:12.482193Z",
"updated_at": "2026-10-01T09:30:12.482193Z",
"utm_tracking": false,
"utm_params": null,
"smart_sending_hours": null,
"exclude_unengaged": false,
"tags": [],
"send_strategy": "immediate",
"send_options": null,
"send_completes_at": null,
"send_summary": null,
"ab_test": {
"enabled": false,
"variants": []
}
}{
"error": "Bad Request"
}{
"statusCode": 403,
"error": "Forbidden",
"message": "Permission denied: campaigns:create"
}{
"message": "Validation failed. ab_test.variants: Send 2 to 5 variants.",
"errors": {
"ab_test.variants": ["Send 2 to 5 variants."]
}
}Retrieve a campaign
Retrieves a campaign by its ID or name. Requires an API key with the full scope.
/campaigns/{id}Path parameters
idstringrequiredcmp_…) or the campaign name. URL-encode names that contain spaces or special characters.Returns
Returns the campaign object.
objectstringcampaign.idstringcmp_.statusstringdraft, scheduled, queued, sending, testing, sent, canceled or archived. queued means a scheduled campaign has reached its send time and is waiting for a worker. testing means an A/B test is running and the winner hasn’t been sent yet. A send spread over time stays sending until its last batch is due.namestringsubjectstringfrom_emailstring"" until set.from_namestring"" until set.reply_tostring"" means replies go to from_email.preview_textstring | nullcontent_typestringhtml, text or mjml for campaigns created through the API. Campaigns whose MJML Emailit compiled (alpha) also return an mjml object with the document’s versions.scheduled_atstring | nullsent_atstring | nullutm_trackingbooleanutm_paramsobject | nullnull. See Create a campaign.smart_sending_hoursinteger | nullnull when smart sending is off.exclude_unengagedbooleantagsstring[]send_strategystringimmediate, throttled, local_time or smart_time.send_optionsobject | nullsend_completes_atstring | nullsent after that.send_summaryobject | nullWhat the last send did, or null before the campaign sends:
recipients: contacts in the audiences and segments, once per address.suppressed: skipped because the address is suppressed.smart_sending_skipped: skipped bysmart_sending_hours.unengaged_skipped: skipped byexclude_unengaged.sent: contacts the campaign was sent to. For an A/B test, the test group only.batches: number of sending batches.completes_at: same assend_completes_at.
ab_testobjectThe A/B test. Without a test: { "enabled": false, "variants": [] }. With a test: enabled, winner_metric, test_size_percent, duration_hours and variants. Each variant has id (cvr_…), name, subject, preview_text, from_name, from_email, reply_to, html, text (null when the variant uses the campaign’s value) and is_winner. See Create a campaign.
recipientsobject[]audience_id (aud_…) or segment_id (seg_…), and exclude (true for an exclusion).The body (html, text and content) isn’t included in the response. For engagement and revenue, use Retrieve campaign statistics or the report in the dashboard under Email MarketingCampaigns.
Returns 404 if no campaign in the workspace matches id.
{
"object": "campaign",
"id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
"name": "October newsletter",
"status": "scheduled",
"subject": "October news for {{first_name}}",
"from_email": "news@acme.com",
"from_name": "Acme",
"reply_to": "support@acme.com",
"preview_text": null,
"content_type": "html",
"sent_at": null,
"scheduled_at": "2026-10-08 09:00:00+00",
"created_at": "2026-10-01 09:30:12.482193+00",
"updated_at": "2026-10-01 10:02:47.118204+00",
"utm_tracking": true,
"utm_params": {
"campaign": "{campaign_name}-{send_date}"
},
"smart_sending_hours": 16,
"exclude_unengaged": true,
"tags": ["newsletter", "q4"],
"send_strategy": "throttled",
"send_options": {
"per_hour": 5000
},
"send_completes_at": null,
"send_summary": null,
"ab_test": {
"enabled": false,
"variants": []
},
"recipients": [
{ "audience_id": "aud_3Cz7WJ9GpvD7P0PQez50xOmkZSV", "exclude": false },
{ "segment_id": "seg_3Kq8VbN2xYt5Lm9Pw1Rc7Hd4Zf0", "exclude": true }
]
}{
"error": "Campaign not found"
}Update a campaign
Updates the fields you pass and leaves the others unchanged. Use it to choose the campaign’s audiences and segments before you send it. Requires an API key with the full scope. Emits a campaign.updated event.
A scheduled campaign sends whatever is saved at its send time, so you can still edit it after scheduling.
/campaigns/{id}Path parameters
idstringrequiredcmp_…) or the campaign name.Body parameters
namestringsubjectstringfrom_emailstringfrom_namestringreply_tostringfrom_email.preview_textstringcontentstringcontent or content_type and the format is html or text, Emailit sends content as the new HTML or plain-text body.content_typestringcontent: html, text or mjml. For the Emailit team, Emailit compiles mjml content into html (alpha). For everyone else mjml is a label.utm_trackingbooleanutm_paramsobject | nullsource, medium, campaign, content, term and id. Replaces the stored object; null restores the defaults. See Create a campaign.smart_sending_hoursinteger | nullnull turns it off.exclude_unengagedbooleantagsstring[]send_strategystringsend_optionsobject | nullsend_strategy, checked in full when the campaign is sent. See Send or schedule a campaign.ab_testobject | nullThe A/B test, with the fields described in Create a campaign. Sending ab_test replaces the test and its variants. To keep a variant’s ID, and with it the variant’s results, include its id (cvr_…) in the variant. null or "enabled": false turns the test off and deletes the variants.
recipientsobject[]The audiences and segments to target, up to 100 items. Replaces the current list. Include at least one item with exclude set to false. Each item has either audience_id or segment_id, not both:
audience_id(string): an audience ID (aud_…) in this workspace.segment_id(string): a segment ID (seg_…) in this workspace. Segments are in alpha: only the Emailit team can add one, and other requests return403witherror: "segments_alpha". Segments the campaign already has can be kept.exclude(boolean, defaultfalse):trueleaves out the audience’s subscribers or the segment’s contacts, even if they’re also in an included item.
Duplicate items are ignored. At send time, Emailit emails each contact once if it’s subscribed to an included audience or matches an included segment, isn’t in an excluded one, isn’t globally unsubscribed, is subscribed to at least one audience, and isn’t suppressed. Segments are evaluated at send time. If an excluded audience or segment no longer exists by then, the campaign isn’t sent.
The HTML and text body are set when you create the campaign. Unknown body fields are ignored.
Returns
Returns the updated campaign object, including recipients and ab_test. See Retrieve a campaign.
Returns 422 if recipients has no included audience or segment, has more than 100 items, has an item with both IDs, or references an audience or segment outside the workspace. Also returns 422 when a setting or the A/B test is invalid, or when you send ab_test for a campaign that isn’t a draft or scheduled, and 404 if the campaign doesn’t exist.
{
"object": "campaign",
"id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
"name": "October newsletter",
"status": "draft",
"subject": "Your October update, {{first_name}}",
"from_email": "news@acme.com",
"from_name": "Acme",
"reply_to": "support@acme.com",
"preview_text": null,
"content_type": "html",
"scheduled_at": null,
"created_at": "2026-10-01 09:30:12.482193+00",
"updated_at": "2026-10-01 10:02:47.118204+00",
"utm_tracking": false,
"utm_params": null,
"smart_sending_hours": null,
"exclude_unengaged": false,
"tags": [],
"send_strategy": "immediate",
"send_options": null,
"send_completes_at": null,
"send_summary": null,
"ab_test": {
"enabled": false,
"variants": []
},
"recipients": [
{ "audience_id": "aud_3Cz7WJ9GpvD7P0PQez50xOmkZSV", "exclude": false },
{ "segment_id": "seg_3Kq8VbN2xYt5Lm9Pw1Rc7Hd4Zf0", "exclude": true }
]
}{
"message": "Validation failed.",
"errors": {
"recipients": ["One or more segments are invalid."]
}
}{
"error": "Campaign not found"
}List campaigns
Returns the workspace’s campaigns, newest first. Requires an API key with the full scope.
/campaignsQuery parameters
pageintegerdefault: 1limitintegerdefault: 10searchstringstatusstringdraft, scheduled, sending (also matches queued), sent, canceled, archived or all.matchstringall (default) requires every filter. or matches any filter. See Filtering.
orderstringSort key for this list. See the sort keys below.
directionstringasc or desc.
Filter keys
Filters use key.condition=value query parameters, for example status.exact=sent or created_at.after=2026-09-01. See Filtering for the conditions per type.
| Key | Type | Notes |
|---|---|---|
name |
string | |
subject |
string | |
status |
enum | draft, scheduled, queued, sending, sent, archived |
created_at |
date | |
sent_at |
date |
Sort keys for order: name, subject, status, created_at, sent_at.
Returns
Returns a page of campaign objects without reply_to, preview_text, content_type and recipients, and with only tags, send_strategy and send_completes_at of the sending options. Use Retrieve a campaign for the rest.
dataobject[]total_recordsintegernext_page_urlstring | nullnull on the last page. It carries only page and limit, so add your search and filters again when you follow it.previous_page_urlstring | nullnull on the first page.{
"data": [
{
"object": "campaign",
"id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
"name": "October newsletter",
"status": "sent",
"subject": "Your October update, {{first_name}}",
"from_email": "news@acme.com",
"from_name": "Acme",
"sent_at": "2026-10-08 09:00:04+00",
"scheduled_at": "2026-10-08 09:00:00+00",
"created_at": "2026-10-01 09:30:12.482193+00",
"updated_at": "2026-10-08 09:00:31+00",
"tags": ["newsletter"],
"send_strategy": "immediate",
"send_completes_at": null
}
],
"total_records": 34,
"next_page_url": "/v2/campaigns?page=2&limit=20",
"previous_page_url": null
}Send or schedule a campaign
Sends the campaign now, or schedules it when you pass a future scheduled_at. Requires an API key with the full scope and a verified workspace: unverified workspaces can’t send campaigns and get 403. Only drafts and scheduled campaigns can be sent: a campaign that is sending or was sent returns 422, so a retried request doesn’t email everyone again.
Before you send, make sure the campaign has a from_email on a verified domain, a subject, an html or text body, and at least one included audience or segment (set with Update a campaign). Each email costs 2 credits.
/campaigns/{id}/sendPath parameters
idstringrequiredcmp_…) or the campaign name.Body parameters
scheduled_atstringWhen to send. Accepts ISO 8601 (2026-10-08T09:00:00Z), a Unix timestamp in seconds, or natural language such as tomorrow at 9am (interpreted in UTC). The time must be in the future and the campaign must be a draft.
Omit it to send now. To send a scheduled campaign early, call this endpoint without scheduled_at.
send_strategystringHow to spread the send over time. Defaults to the strategy saved on the campaign, else immediate. The strategy and its options are saved on the campaign. See Sending options.
immediate: everyone at once, now or atscheduled_at.throttled: an even pace ofper_houremails, starting now or atscheduled_at.local_time: a wall-clock time in each contact’s time zone.scheduled_atis ignored.smart_time: each contact at the hour they usually open or click, within a window from the start.
Campaigns with an A/B test only send with immediate.
send_optionsobjectOptions of the strategy. Defaults to the options saved on the campaign.
throttled:per_hour(integer, required), from 100 to 1,000,000 emails per hour.local_time:local_time(string, required), the time asYYYY-MM-DDTHH:mm, for example2026-10-08T09:00, andtimezone(string, defaultUTC), the IANA time zone for contacts whose time zone isn’t known. Contacts’ time zones come from the tracking script. Sending starts when the earliest time zone (UTC+14) reaches the time; contacts in zones already past it get the email right away. Until then the campaign isscheduled, so it must be a draft. Returns422when the time has passed in every time zone.smart_time:window_hours(integer, default24), from 1 to 48. Each contact gets the email at the hour of day (UTC) they opened or clicked most in the last 90 days, with a click counting three times as much as an open, when that hour comes within the window. Contacts without that history get the hour most common among the other recipients. Contacts with neither, or whose hour falls outside the window, get it at the start.
timezone is accepted with every strategy and must be a valid IANA time zone, but only local_time uses it.
Returns
Send now: the status changes to sending and Emailit emits campaign.sending. Emailit then resolves the recipients: every subscribed contact of the included audiences and every contact matching the included segments, once per address, without contacts in excluded audiences or segments, contacts that are globally unsubscribed or on no audience, and suppressed addresses. Segments are evaluated at this moment. It also skips contacts left out by smart_sending_hours and exclude_unengaged. The emails are created at the times the send strategy sets. Once every recipient has been handed to the sending pipeline, the status changes to sent and Emailit emits campaign.sent. A send spread over time stays sending until its last batch is due (send_completes_at). The campaign’s send_summary shows how many contacts were sent the campaign and how many were skipped. Track delivery in the dashboard, with Retrieve campaign statistics or with email events.
A/B test: the test group gets the variants and the status changes to testing. After duration_hours, the rest of the recipients get the winning variant and the status changes to sent.
Schedule: the status changes to scheduled and Emailit emits campaign.scheduled. At the scheduled time the campaign becomes queued (campaign.queued) and then sends as above. If an excluded audience or segment was deleted in the meantime, the campaign goes back to draft instead of sending.
The response contains object, id, name and the new status, plus scheduled_at when you schedule.
| Status | When |
|---|---|
403 |
The workspace isn’t verified, or the API key doesn’t have the full scope. |
404 |
No campaign matches id. |
422 |
The campaign is neither a draft nor scheduled (for example, it’s sending or was sent), scheduled_at can’t be parsed or isn’t in the future, you tried to schedule a campaign that isn’t a draft, the campaign has no html or text body, it has no recipients (set them with Update a campaign), it excludes an audience or segment that no longer exists, or send_strategy and send_options are invalid. The error for the strategy names the field in message. |
{
"object": "campaign",
"id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
"name": "October newsletter",
"status": "scheduled",
"scheduled_at": "2026-10-08T09:00:00.000000Z"
}{
"object": "campaign",
"id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
"name": "October newsletter",
"status": "sending"
}{
"code": "unverified_workspace_recipient",
"error": "Workspace not verified",
"message": "Unverified workspaces cannot send campaigns. You can send individual emails only to workspace members' account emails."
}{
"error": "Campaign cannot be sent",
"message": "Campaign status is 'sent'. Only draft or scheduled campaigns can be sent."
}{
"error": "Campaign excludes a deleted audience or segment",
"message": "This campaign excludes an audience or segment that no longer exists. Update its recipients before sending."
}{
"error": "Invalid send strategy",
"message": "send_options.per_hour: Send between 100 and 1,000,000 emails per hour."
}Cancel a campaign
Sets the campaign’s status to canceled and emits a campaign.canceled event. Requires an API key with the full scope.
Only campaigns in draft or sending status can be canceled; any other status returns 422. Canceling a campaign that is sending doesn’t recall emails that are already queued for delivery.
/campaigns/{id}/cancelPath parameters
idstringrequiredcmp_…) or the campaign name.Returns
Returns object, id, name and status (canceled).
Returns 422 if the campaign’s status isn’t draft or sending, and 404 if the campaign doesn’t exist.
{
"object": "campaign",
"id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
"name": "October newsletter",
"status": "canceled"
}{
"error": "Campaign cannot be canceled",
"message": "Campaign status is 'scheduled'. Only 'draft' or 'sending' campaigns can be canceled."
}{
"error": "Campaign not found"
}Retrieve campaign statistics
Retrieve the report of a campaign: how many emails were sent, delivered, opened and clicked, the results per mailbox provider, the revenue of the orders credited to the campaign (Commerce, alpha) and, for A/B tests, the results per variant. The dashboard report under Email MarketingCampaigns shows the same numbers. Requires an API key with the full scope.
Every count is a number of emails: an email that was opened three times counts once in opened. Percentages are relative to sent unless noted, with two decimal places.
/campaigns/{id}/statsPath parameters
idstringRequiredThe campaign ID (cmp_...) or the campaign name. URL-encode names that contain spaces or special characters.
Query parameters
fromstringOnly count emails created at or after this time, an ISO 8601 date or date-time.
tostringOnly count emails created at or before this time.
statusstringOnly count emails whose current status is this one: accepted, scheduled, delivered, loaded, clicked, attempted, bounced, failed, rejected, suppressed or complained. Other values are ignored.
The filters apply to the email counts, the providers and the A/B test counts, and from and to also apply to unsubscribed. Revenue, orders and buyers always cover every order credited to the campaign, and their rates use all of the campaign’s delivered emails.
Returns
objectstringAlways campaign_stats.
campaign_idstringThe campaign ID (cmp_...).
sentintegerEmails created for the campaign. sent_percent is 100, or 0 before anything is sent.
delivered, delivered_percentinteger, numberEmails whose status is delivered, loaded or clicked.
opened, opened_percentinteger, numberEmails opened at least once.
clicked, clicked_percentinteger, numberEmails with at least one tracked click.
click_through_percentnumberclicked as a percentage of opened.
bounced, suppressed, complained, attemptedintegerEmails whose status is bounced, suppressed, complained or attempted (waiting for a retry). Each has a _percent field too.
not_processed, not_processed_percentinteger, numberEmails still accepted or scheduled.
unsubscribed, unsubscribed_percentinteger, numberUnsubscribes from the campaign’s emails.
providersobject[]Results per mailbox provider of the recipients, for providers with at least one email. key is gmail, outlook.com, live.com, hotmail.com, yahoo, icloud or other, and label is its display name. Each has sent, delivered, opened, clicked and bounced with their _percent fields. sent_percent is the provider’s share of all emails; the other percentages are relative to the provider’s sent.
commerceobjectOnly for the Emailit team while Commerce is in alpha: other requests don’t get this field, and their A/B variants leave out orders, revenue and revenue_per_recipient. Orders credited to the campaign. Revenue is the order total minus refunds, and canceled orders don’t count. Amounts in different currencies aren’t added up: the main currency is the one with the most revenue.
-
currency(string or null): the main currency. -
revenue(number): revenue in the main currency. -
orders(integer): credited orders in all currencies. -
buyers(integer): distinct buyers in all currencies. A buyer who paid in two currencies counts once. -
average_order_value(number): in the main currency. -
conversion_percent(number):buyersas a percentage of the campaign’s delivered emails. -
revenue_per_recipient(number):revenuedivided by the campaign’s delivered emails. -
by_currency(object[]):currency,orders,revenue,buyersandaverage_order_valuefor each currency, highest revenue first.
ab_testobjectOnly for campaigns with an A/B test.
-
winner_metric(string):opened,clicked,ordersorrevenue. -
leader_variant_id(string or null): the variant with the best rate so far: opens, clicks or orders per email sent, or revenue per email sent. -
win_probability(number or null): the chance, in percent, that the leader really beats the runner-up. -
significance(string):significant(90% or more, with at least 50 emails per variant),promising(75% or more, same minimum),not_significant(under 75% with at least 1,800 emails per variant) orinconclusive. Forrevenue, the probability is based on orders. -
variants(object[]): per variantvariant_id,name,subject,is_winner,sent,delivered,opened,opened_percent,clicked,clicked_percent,orders,revenueandrevenue_per_recipient. Once the winner is sent to the rest of the audience, the winning variant’s counts include those emails.
Returns 404 if no campaign matches id, and 503 when the analytics store isn’t available.
{
"object": "campaign_stats",
"campaign_id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
"sent": 12480,
"sent_percent": 100,
"delivered": 12302,
"delivered_percent": 98.57,
"opened": 5021,
"opened_percent": 40.23,
"clicked": 1187,
"clicked_percent": 9.51,
"click_through_percent": 23.64,
"bounced": 98,
"bounced_percent": 0.79,
"suppressed": 42,
"suppressed_percent": 0.34,
"complained": 3,
"complained_percent": 0.02,
"attempted": 0,
"attempted_percent": 0,
"not_processed": 38,
"not_processed_percent": 0.3,
"unsubscribed": 27,
"unsubscribed_percent": 0.22,
"providers": [
{
"key": "gmail",
"label": "Gmail",
"sent": 7310,
"sent_percent": 58.57,
"delivered": 7236,
"delivered_percent": 98.99,
"opened": 3102,
"opened_percent": 42.44,
"clicked": 741,
"clicked_percent": 10.14,
"bounced": 41,
"bounced_percent": 0.56
},
{
"key": "other",
"label": "Other",
"sent": 5170,
"sent_percent": 41.43,
"delivered": 5066,
"delivered_percent": 97.99,
"opened": 1919,
"opened_percent": 37.12,
"clicked": 446,
"clicked_percent": 8.63,
"bounced": 57,
"bounced_percent": 1.1
}
],
"commerce": {
"currency": "USD",
"revenue": 17311.9,
"orders": 214,
"buyers": 198,
"average_order_value": 86.13,
"conversion_percent": 1.61,
"revenue_per_recipient": 1.41,
"by_currency": [
{
"currency": "USD",
"orders": 201,
"revenue": 17311.9,
"buyers": 186,
"average_order_value": 86.13
},
{
"currency": "EUR",
"orders": 13,
"revenue": 1052.4,
"buyers": 12,
"average_order_value": 80.95
}
]
}
}{
"object": "campaign_stats",
"campaign_id": "cmp_37WtKnTZIi4ZbdQ8057IgW0Pbjk",
"sent": 2496,
"sent_percent": 100,
"delivered": 2461,
"delivered_percent": 98.6,
"opened": 1004,
"opened_percent": 40.22,
"clicked": 231,
"clicked_percent": 9.25,
"click_through_percent": 23.01,
"bounced": 21,
"bounced_percent": 0.84,
"suppressed": 9,
"suppressed_percent": 0.36,
"complained": 1,
"complained_percent": 0.04,
"attempted": 0,
"attempted_percent": 0,
"not_processed": 5,
"not_processed_percent": 0.2,
"unsubscribed": 6,
"unsubscribed_percent": 0.24,
"providers": [
{
"key": "gmail",
"label": "Gmail",
"sent": 1460,
"sent_percent": 58.49,
"delivered": 1447,
"delivered_percent": 99.11,
"opened": 612,
"opened_percent": 41.92,
"clicked": 139,
"clicked_percent": 9.52,
"bounced": 9,
"bounced_percent": 0.62
},
{
"key": "other",
"label": "Other",
"sent": 1036,
"sent_percent": 41.51,
"delivered": 1014,
"delivered_percent": 97.88,
"opened": 392,
"opened_percent": 37.84,
"clicked": 92,
"clicked_percent": 8.88,
"bounced": 12,
"bounced_percent": 1.16
}
],
"commerce": {
"currency": "USD",
"revenue": 3297.4,
"orders": 38,
"buyers": 36,
"average_order_value": 86.77,
"conversion_percent": 1.46,
"revenue_per_recipient": 1.34,
"by_currency": [
{
"currency": "USD",
"orders": 38,
"revenue": 3297.4,
"buyers": 36,
"average_order_value": 86.77
}
]
},
"ab_test": {
"winner_metric": "clicked",
"leader_variant_id": "cvr_3uzJsNMbJopoPIZCgLl7zcXxALw",
"win_probability": 99.5,
"significance": "significant",
"variants": [
{
"variant_id": "cvr_3qM7nyKvTUlnBLzE9vtnG03baRV",
"name": "A",
"subject": "New trail shoes are here",
"is_winner": false,
"sent": 1248,
"delivered": 1231,
"opened": 468,
"opened_percent": 37.5,
"clicked": 97,
"clicked_percent": 7.77,
"orders": 14,
"revenue": 1188.6,
"revenue_per_recipient": 0.97
},
{
"variant_id": "cvr_3uzJsNMbJopoPIZCgLl7zcXxALw",
"name": "B",
"subject": "Your next trail shoe is 25% off",
"is_winner": false,
"sent": 1248,
"delivered": 1230,
"opened": 536,
"opened_percent": 42.95,
"clicked": 134,
"clicked_percent": 10.74,
"orders": 24,
"revenue": 2108.8,
"revenue_per_recipient": 1.71
}
]
}
}{
"error": "Campaign not found"
}{
"error": "analytics unavailable"
}Delete a campaign
Permanently deletes a campaign. Requires an API key with the full scope. Emits a campaign.deleted event.
Deleting a campaign doesn’t affect emails that were already sent or queued. To stop a campaign that is sending, cancel it first.
/campaigns/{id}Path parameters
idstringrequiredcmp_…) or the campaign name.Returns
Returns object, id, name and deleted: true. Returns 404 if the campaign doesn’t exist.
{
"object": "campaign",
"id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
"name": "October newsletter",
"deleted": true
}{
"error": "Campaign not found"
}