Menu

API reference · Email Marketing

Campaigns

email_marketing · campaigns · 12 operations

GET/v1/email-marketing/campaigns

List email campaigns

email_marketing.campaigns.list

ReadIdempotentSince 2026-11-01

Lists the organization's email campaigns, most recently updated first, paginated by cursor: name, subject, sender, status (draft, scheduled, queued, sending, sent, paused, cancelled), audience or direct recipients, recipient and suppressed counts, delivery stats and dates. Filter by status; archived campaigns are left out unless include_archived is true (the page is completed up to limit). stalled: true marks one queued or sending with no progress for more than 6 hours: it will not go out by itself and MB Suite cancels it (send_stalled says so afterwards); send_held marks one MB Suite cancelled while it went out because it paused the account's email sending (duplicate it to send it again once sending is resumed). The HTML is not included: use email_marketing.campaigns.get. Requires view access to Email Marketing.

Scope
email_marketing:read
Permission
View the module
MCP tool
email_marketing_campaigns_listOn the full surface; on the compact one, mb_execute_operation with id: "email_marketing.campaigns.list".

Declared cost: up to 601 reads and 0 writes per call (they count against the daily quota).

Parameters

limitintegerqueryoptional

How many items this page brings at most (see the maximum and the default in the schema).

Default: 50

cursorstringqueryoptional

The next_cursor of the previous page, exactly as it came (only for the same list and filters); without it, the first page.

statusenumqueryoptional

Only campaigns in this status: draft, queued, scheduled, sending, sent, paused or cancelled.

Values: draft, queued, scheduled, sending, sent, paused, cancelled

include_archivedbooleanqueryoptional

Also bring the archived campaigns (default false).

Default: false

Response

dataarray<object>
has_moreboolean
next_cursorstring

Errors

Example

curl "https://api.mb-suite.com/v1/email-marketing/campaigns" \
  -H "Authorization: Bearer $MB_API_KEY"

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl "https://api.mb-suite.com/v1/email-marketing/campaigns" \
  -H "Authorization: Bearer $MB_TEST_KEY"
GET/v1/email-marketing/campaigns/{campaign_id}

Get one email campaign

email_marketing.campaigns.get

ReadIdempotentSince 2026-11-01

Returns a campaign with its HTML content (html_content, with the {{nombre}}, {{email}} and unsubscribe variables still unresolved), sender, recipients, status, delivery progress and stats (sent, delivered, opened, clicked, bounced, hard_bounced — addresses that do not exist or reject the email —, complained, unsubscribed), schedule_missed when a scheduled send did not happen (the campaign is back to draft), stalled: true when it is queued or sending with no progress for more than 6 hours, send_stalled once MB Suite cancelled a send that stopped moving, and send_held once MB Suite cancelled it while it went out because it paused the account's email sending (duplicate it to send it again once sending is resumed). Not found (email_campaign_not_found) if the id is not a campaign of this organization. Requires view access to Email Marketing.

Scope
email_marketing:read
Permission
View the module
MCP tool
email_marketing_campaigns_getOn the full surface; on the compact one, mb_execute_operation with id: "email_marketing.campaigns.get".

Declared cost: up to 1 reads and 0 writes per call (they count against the daily quota).

Parameters

campaign_idstringpathrequired

The campaign's id (from email_marketing.campaigns.list).

Response

idstring
namestring
statusstring
subjectstring | null
preview_textstring | null
from_emailstring | null
from_namestring | null
audience_idstring | null
audience_namestring | null
template_idstring | null
template_namestring | null
recipient_sourcestring | null
direct_recipientsobject | null
html_contentstring | null
scheduled_atnumber | null
sent_atnumber | null
completed_atnumber | null
recipient_countnumber | null
suppressed_countnumber | null
statsobject | null
archivedboolean | null
schedule_missedobject | null
send_stalledobject | null

Set when the send stopped moving for 6 hours and MB Suite cancelled it (what was left in the queue does not go out).

stalledboolean

true when it is queued or sending with no progress for more than 6 hours: it will not go out by itself (MB Suite cancels it).

send_heldobject | null

Set when MB Suite paused the account's email sending while it went out (kind bounce_rate: a campaign or flow had a hard bounce rate over 5%; manual: MB Suite decided it): it was cancelled and what was left in the queue does not go out.

dispatch_progressobject | null

While it goes out: how many emails of the queue were sent and failed, of total.

created_bystring | null
created_atnumber | null
updated_atnumber | null

Errors

Example

curl "https://api.mb-suite.com/v1/email-marketing/campaigns/{campaign_id}" \
  -H "Authorization: Bearer $MB_API_KEY"

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl "https://api.mb-suite.com/v1/email-marketing/campaigns/{campaign_id}" \
  -H "Authorization: Bearer $MB_TEST_KEY"
POST/v1/email-marketing/campaigns

Create an email campaign draft

email_marketing.campaigns.create

WriteSince 2026-11-01

Creates a campaign in draft: name, subject, sender (from_email must be an email address — or empty while it is a draft — on the account's verified sending domain by the time it is sent), recipients (recipient_source audience with audience_id, whose name is filled in when audience_name is not sent — 404 email_audience_not_found for an audience of another organization —, or direct with direct_recipients.contact_ids of Contacts and/or manual_emails) and content (html_content, usually from a template: template_id/templateName are kept as references). Supports the variables {{nombre}}, {{email}}, {{unsubscribe_url}}, {{unsubscribe_text}}, {{company_name}} and {{email_footer_address}}. Nothing is sent: use email_marketing.campaigns.send_now. Returns campaign_id. Requires full access to Email Marketing.

Scope
email_marketing:write
Permission
Edit in the module
MCP tool
email_marketing_campaigns_createOn the full surface; on the compact one, mb_execute_operation with id: "email_marketing.campaigns.create".

Declared cost: up to 1 reads and 1 writes per call (they count against the daily quota).

Parameters

namestringbodyrequired

The campaign's name (internal).

subjectstringbodyrequired

The email's subject; {{first_name}} and the contact's other fields are replaced.

from_emailstringbodyrequired

The sender's email: one of the verified senders of the organization's sending domain (branding.domains.get). Empty in a draft that has not chosen one.

from_namestringbodyrequired

The sender's display name.

preview_textstringbodyoptional

The preview line the inbox shows after the subject.

audience_idstringbodyoptional

Who gets it: an audience of email_marketing.audiences.list.

audience_namestringbodyoptional

The audience's name as shown (resolved from audience_id when missing).

template_idstringbodyoptional

A template of email_marketing.templates.list (its id).

template_namestringbodyoptional

The template's name as shown (resolved from template_id when missing).

html_contentstringbodyoptional

The email's HTML (with a template, the template's).

scheduled_atnumberbodyoptional

When it goes out (epoch ms); schedule it with email_marketing.campaigns.schedule.

recipient_sourceenumbodyoptional

audience (default) or direct (direct_recipients).

Values: audience, direct

direct_recipientsobjectbodyoptional

With recipient_source direct: contacts and loose emails.

Response

campaign_idstring

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/email-marketing/campaigns" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "NAME",
  "subject": "SUBJECT",
  "from_email": "ana@example.com",
  "from_name": "FROM_NAME"
}'

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl -X POST "https://api.mb-suite.com/v1/email-marketing/campaigns" \
  -H "Authorization: Bearer $MB_TEST_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "NAME",
  "subject": "SUBJECT",
  "from_email": "ana@example.com",
  "from_name": "FROM_NAME"
}'
PATCH/v1/email-marketing/campaigns/{campaign_id}

Update an email campaign

email_marketing.campaigns.update

WriteIdempotentSince 2026-11-01

Updates one or more fields of a draft, scheduled or cancelled campaign: name, subject, preview text, sender, recipients, template reference or HTML content (null clears a nullable field). A campaign that was already queued, is sending or was sent only accepts a new name (campaign_not_editable); the status is checked again when the edit is written, so an edit that arrives just as the scheduled send queues the campaign gets that 409 instead of changing what went out. It does not change the status or when a scheduled campaign goes out: to move the send date use email_marketing.campaigns.schedule (it re-arms the scheduled send and fires email_marketing.campaign.scheduled), to remove it use email_marketing.campaigns.unschedule, and send_now or cancel for the rest. A different scheduled_at (or null) for a scheduled campaign is rejected with 409 scheduled_at_not_editable and nothing is saved; sending the date it already has is not a change. On a draft, scheduled_at is only stored: it schedules nothing. Content edits to a scheduled campaign go out at its time. A new audience_id without audience_name gets its name filled in. Returns the updated campaign. Requires full access to Email Marketing.

Scope
email_marketing:write
Permission
Edit in the module
MCP tool
email_marketing_campaigns_updateOn the full surface; on the compact one, mb_execute_operation with id: "email_marketing.campaigns.update".

Declared cost: up to 3 reads and 1 writes per call (they count against the daily quota).

Parameters

campaign_idstringpathrequired

The campaign's id (from email_marketing.campaigns.list).

updatesobjectbodyrequired

The fields to change.

Response

campaignobject

Errors

Example

curl -X PATCH "https://api.mb-suite.com/v1/email-marketing/campaigns/{campaign_id}" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "updates": {}
}'

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl -X PATCH "https://api.mb-suite.com/v1/email-marketing/campaigns/{campaign_id}" \
  -H "Authorization: Bearer $MB_TEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "updates": {}
}'
POST/v1/email-marketing/campaigns/{campaign_id}/duplicate

Duplicate an email campaign

email_marketing.campaigns.duplicate

WriteSince 2026-11-01

Copies a campaign (subject, sender, recipients, content) into a new draft named '<name> (copia)' with empty stats, whatever the original's status: the usual way to resend a campaign to a new audience. Returns the new campaign_id. Requires full access to Email Marketing.

Scope
email_marketing:write
Permission
Edit in the module
MCP tool
email_marketing_campaigns_duplicateOn the full surface; on the compact one, mb_execute_operation with id: "email_marketing.campaigns.duplicate".

Declared cost: up to 1 reads and 1 writes per call (they count against the daily quota).

Parameters

campaign_idstringpathrequired

The campaign's id (from email_marketing.campaigns.list).

Response

campaign_idstring

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/email-marketing/campaigns/{campaign_id}/duplicate" \
  -H "Authorization: Bearer $MB_API_KEY"

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl -X POST "https://api.mb-suite.com/v1/email-marketing/campaigns/{campaign_id}/duplicate" \
  -H "Authorization: Bearer $MB_TEST_KEY"
POST/v1/email-marketing/campaigns/{campaign_id}/schedule

Schedule an email campaign

email_marketing.campaigns.schedule

WriteSince 2026-11-01

Schedules a draft campaign for scheduled_at (epoch ms, in the future and at most one year ahead), or reschedules one that is already scheduled; it needs recipients and content. At that time it goes out on its own: a job checks every 5 minutes and sends it exactly as email_marketing.campaigns.send_now does (same recipients, suppression list and monthly plan limit; email_marketing.campaign.sent fires with a system actor), so whatever the campaign says at that moment is what is sent. If it cannot go out within an hour of scheduled_at (the account cannot send or MB Suite paused its sending, the plan has no room, there are no recipients, or the send could not run), it is NOT sent: the campaign goes back to draft with schedule_missed (scheduled_at, detected_at, reason late or send_failed, code) and the people who created and scheduled it get an in-app notice. To stop it, unschedule it (email_marketing.campaigns.unschedule: back to draft) or cancel it. Outside the app it always runs in two steps, like send_now: dry_run=true runs the same checks as scheduling and says what send_now would say today (how many people it reaches, how many are suppressed, what is left of the monthly plan, the first recipients, and what would stop the send today, such as an unverified domain), with a confirm_token (10 minutes); then call it again with the same input and the confirm_token. Errors: scheduled_at_in_past, scheduled_at_too_far, campaign_not_schedulable (not a draft or scheduled campaign), campaign_incomplete. Owners and admins only, like sending.

Needs confirmation: first dry_run: true (preview and confirm_token, valid 10 minutes and for one run), then the same body with confirm_token. In a few operations only with certain data: the description says when. Why and how: Dry run and confirm_token.

Scope
email_marketing:write
Permission
Edit in the module · Only owner, admin
MCP tool
email_marketing_campaigns_scheduleOn the full surface; on the compact one, mb_execute_operation with id: "email_marketing.campaigns.schedule".

Declared cost: up to 2 reads and 2 writes per call (they count against the daily quota).

Parameters

campaign_idstringpathrequired

The campaign's id (from email_marketing.campaigns.list).

scheduled_atintegerbodyrequired

When it goes out (epoch ms, in the future).

Response

status"scheduled"
scheduled_atnumber

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/email-marketing/campaigns/{campaign_id}/schedule" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "scheduled_at": 946684800000,
  "dry_run": true
}'

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl -X POST "https://api.mb-suite.com/v1/email-marketing/campaigns/{campaign_id}/schedule" \
  -H "Authorization: Bearer $MB_TEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "scheduled_at": 946684800000,
  "dry_run": true
}'
POST/v1/email-marketing/campaigns/{campaign_id}/unschedule

Unschedule an email campaign (back to draft)

email_marketing.campaigns.unschedule

WriteIdempotentSince 2026-11-01

Takes a scheduled campaign back to draft: it no longer goes out at its time and keeps its content, sender and recipients, so it can be edited, scheduled again (email_marketing.campaigns.schedule) or sent (email_marketing.campaigns.send_now). Unscheduling a draft changes nothing (changed false). A campaign that is already queued, sending or sent cannot be unscheduled (campaign_not_unschedulable): use email_marketing.campaigns.cancel, which stops what is still in the queue. Owners and admins only, like scheduling.

Scope
email_marketing:write
Permission
Edit in the module · Only owner, admin
MCP tool
email_marketing_campaigns_unscheduleOn the full surface; on the compact one, mb_execute_operation with id: "email_marketing.campaigns.unschedule".

Declared cost: up to 2 reads and 2 writes per call (they count against the daily quota).

Parameters

campaign_idstringpathrequired

The campaign's id (from email_marketing.campaigns.list).

Response

status"draft"
changedboolean

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/email-marketing/campaigns/{campaign_id}/unschedule" \
  -H "Authorization: Bearer $MB_API_KEY"

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl -X POST "https://api.mb-suite.com/v1/email-marketing/campaigns/{campaign_id}/unschedule" \
  -H "Authorization: Bearer $MB_TEST_KEY"
POST/v1/email-marketing/campaigns/{campaign_id}/send

Send an email campaign now (real emails through Amazon SES)

email_marketing.campaigns.send_now

IrreversibleSince 2026-11-01

Sends a draft or scheduled campaign NOW to real people (a scheduled campaign also goes out on its own at its time: see email_marketing.campaigns.schedule): it resolves the recipients, removes repeated and suppressed addresses (unsubscribed, bounced, complained), checks the monthly email plan limit and queues one personalized email per recipient with a one-click unsubscribe link; they go out through Amazon SES within minutes and cannot be recalled (cancel stops what is still in the queue). Irreversible: outside the app it always runs in two steps — call it with dry_run=true to get the preview (how many people receive it, how many are suppressed, what is left of the monthly plan, the first recipients) and a confirm_token (10 minutes), then again with the same input and the confirm_token; the credential must allow irreversible operations (403 delete_not_allowed otherwise). Requires a verified sending domain, a mailing address (CAN-SPAM), content, and a sender on that domain. Not idempotent: never retry it blindly — read the campaign first (status queued or sent means it already went out). Returns enqueued, recipient_count and suppressed_count. Errors: campaign_not_sendable, campaign_without_audience, campaign_without_recipients, campaign_without_content, campaign_sender_not_on_domain, campaign_audience_missing, email_domain_not_verified, email_footer_address_missing, limit_reached (the monthly email plan has no room: details.resource emails), all_recipients_suppressed, campaign_already_sending, email_sending_paused (the dry run already answers the ones it can see). While MB Suite has the account's email sending paused (a campaign or flow had a hard bounce rate over 5%, or MB Suite decided it: see sending_paused in email_marketing.usage.get) it refuses with email_sending_paused (details.kind bounce_rate or manual, details.held_at) and nothing goes out. Owners and admins only.

Instructions for agents

Run the dry run first and tell the person the campaign name, how many people receive it and that the emails cannot be recalled; send it only after they confirm.

Needs confirmation: first dry_run: true (preview and confirm_token, valid 10 minutes and for one run), then the same body with confirm_token. In a few operations only with certain data: the description says when. Why and how: Dry run and confirm_token.

Scope
email_marketing:write and “Allow deletions” (email_marketing:delete in OAuth)
Permission
Edit in the module · Only owner, admin
MCP tool
email_marketing_campaigns_send_nowOn the full surface; on the compact one, mb_execute_operation with id: "email_marketing.campaigns.send_now".

Declared cost: up to 20002 reads and 20003 writes per call (they count against the daily quota). Touches an external platform (ses): it counts against the external operations quota.

Parameters

campaign_idstringpathrequired

The campaign's id (from email_marketing.campaigns.list).

Response

enqueuednumber
recipient_countnumber
suppressed_countnumber

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/email-marketing/campaigns/{campaign_id}/send" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "dry_run": true
}'

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset. In the practice organization this operation is not simulated (it reaches another platform): it answers 409 sandbox_external_unavailable.

POST/v1/email-marketing/campaigns/{campaign_id}/cancel

Cancel an email campaign

email_marketing.campaigns.cancel

WriteSince 2026-11-01

Cancels a scheduled, queued or sending campaign: a scheduled one no longer goes out at its time (to take it back to draft instead, use email_marketing.campaigns.unschedule), emails still in the queue are dropped (the ones already sent stay sent) and the campaign ends cancelled; a campaign that finished sending in the meantime stays sent. A cancelled campaign can be edited, duplicated or deleted. Error: campaign_not_cancellable. Owners and admins only.

Scope
email_marketing:write
Permission
Edit in the module · Only owner, admin
MCP tool
email_marketing_campaigns_cancelOn the full surface; on the compact one, mb_execute_operation with id: "email_marketing.campaigns.cancel".

Declared cost: up to 2 reads and 2 writes per call (they count against the daily quota).

Parameters

campaign_idstringpathrequired

The campaign's id (from email_marketing.campaigns.list).

Response

status"cancelled"

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/email-marketing/campaigns/{campaign_id}/cancel" \
  -H "Authorization: Bearer $MB_API_KEY"

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl -X POST "https://api.mb-suite.com/v1/email-marketing/campaigns/{campaign_id}/cancel" \
  -H "Authorization: Bearer $MB_TEST_KEY"
POST/v1/email-marketing/campaigns/{campaign_id}/archive

Archive or unarchive an email campaign

email_marketing.campaigns.archive

WriteIdempotentSince 2026-11-01

Archives (archived: true) or restores (false) a campaign: archived campaigns leave the default list but keep everything, stats included. It does not change the status. Idempotent. Requires full access to Email Marketing.

Scope
email_marketing:write
Permission
Edit in the module
MCP tool
email_marketing_campaigns_archiveOn the full surface; on the compact one, mb_execute_operation with id: "email_marketing.campaigns.archive".

Declared cost: up to 1 reads and 1 writes per call (they count against the daily quota).

Parameters

campaign_idstringpathrequired

The campaign's id (from email_marketing.campaigns.list).

archivedbooleanbodyrequired

true archives it (hidden from the list), false brings it back.

Response

changedboolean

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/email-marketing/campaigns/{campaign_id}/archive" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "archived": true
}'

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl -X POST "https://api.mb-suite.com/v1/email-marketing/campaigns/{campaign_id}/archive" \
  -H "Authorization: Bearer $MB_TEST_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "archived": true
}'
DELETE/v1/email-marketing/campaigns/{campaign_id}

Delete an email campaign

email_marketing.campaigns.delete

IrreversibleSince 2026-11-01

Deletes a draft or cancelled campaign (a scheduled one must be cancelled first; sent campaigns are kept: archive them instead). It goes to the 30-day trash. Error: campaign_not_deletable. Outside the screen it requires a dry run and a confirm_token, or a REST DELETE. Requires full access to Email Marketing.

With an API key, this DELETE runs directly: the record stays 30 days in the trash and the response carries its trash_item_id. With an OAuth token, and through the MCP, it needs dry_run → confirm_token.

Scope
email_marketing:write and “Allow deletions” (email_marketing:delete in OAuth)
Permission
Edit in the module
MCP tool
email_marketing_campaigns_deleteOn the full surface; on the compact one, mb_execute_operation with id: "email_marketing.campaigns.delete".

Declared cost: up to 1 reads and 3 writes per call (they count against the daily quota).

Parameters

campaign_idstringpathrequired

The campaign's id (from email_marketing.campaigns.list).

Response

oktrue
trash_item_idstring

The trash item this deletion left: the item_id of platform.trash.restore (POST /trash/{item_id}/restore). Missing if nothing went to the trash.

trash_item_idsarray<string>

Only when the deletion left more than one copy: all of them, the first being trash_item_id.

trash_expires_atnumber

When the copy leaves the trash for good (epoch ms): 30 days after the deletion.

Errors

Example

curl -X DELETE "https://api.mb-suite.com/v1/email-marketing/campaigns/{campaign_id}" \
  -H "Authorization: Bearer $MB_API_KEY"

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl -X DELETE "https://api.mb-suite.com/v1/email-marketing/campaigns/{campaign_id}" \
  -H "Authorization: Bearer $MB_TEST_KEY"
POST/v1/email-marketing/campaigns/render-preview

Render an email as recipients will see it

email_marketing.campaigns.render_preview

ReadIdempotentSince 2026-11-01

Renders HTML content the way a campaign is sent: wrapped in the organization's branded email layout (format html, default) or in the minimal personal-style wrapper (format text), with the organization's name, mailing address and a preview unsubscribe link resolved. {{nombre}} and {{email}} are left as they are (they change per recipient). Writes nothing and sends nothing. Returns html. Requires view access to Email Marketing.

Scope
email_marketing:read
Permission
View the module
MCP tool
email_marketing_campaigns_render_previewOn the full surface; on the compact one, mb_execute_operation with id: "email_marketing.campaigns.render_preview".

Declared cost: up to 1 reads and 0 writes per call (they count against the daily quota).

Parameters

html_contentstringbodyrequired

The email's HTML to preview.

subjectstringbodyoptional

The subject (for the preview's title).

Default: ""

formatenumbodyoptional

html (default): the brand layout; text: a minimal personal-style wrapper.

Values: html, text

Response

htmlstring

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/email-marketing/campaigns/render-preview" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "html_content": "HTML_CONTENT"
}'

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl -X POST "https://api.mb-suite.com/v1/email-marketing/campaigns/render-preview" \
  -H "Authorization: Bearer $MB_TEST_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "html_content": "HTML_CONTENT"
}'