APRESMAIL API & MCP

API reference

Every ApresMail REST API endpoint with parameters and a curl example, including canonical Subscriber and newsletter subscription actions alongside legacy aliases.

Added to the help center: November 5, 2026

On this page

Base URL https://mail.apresly.com/api/v1. Bodies are JSON; GET and DELETE take their parameters in the query string. Each endpoint is also the MCP tool named under it. The same reference as OpenAPI 3.1.

Audience v2 uses one Subscriber profile with a separate subscription and consent for each newsletter. Use the Subscribers actions for profiles; a legacy contact ID identifies a newsletter subscription, and legacy recipient reads apply only to v1 accounts. On v2, groups require a newsletter parent and cannot grant consent. The CSV preview is read-only. For the current import workflow, see Importing contacts.

Campaigns

Drafts, test emails, scheduling, sending, sending in steps and reports.

List countdown campaigns

GET /api/v1/native-campaigns

Lists owned published Apresly campaigns for native email countdown blocks. No recipient is registered.

MCP tool list_native_campaigns Key content:read Read-only Safe to repeat Reaches outside ApresMail

Request

curl "https://mail.apresly.com/api/v1/native-campaigns" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Validate a countdown destination

POST /api/v1/native-campaigns/validate

Checks an owned campaign and optional published checkout destination without registering a recipient.

MCP tool validate_native_countdown Key content:read Read-only Safe to repeat Reaches outside ApresMail

Parameter Description
capabilityrequiredbody · string Owned campaign capability returned by list_native_campaigns
checkoutPublicIdrequiredbody · string null

Request

curl -X POST "https://mail.apresly.com/api/v1/native-campaigns/validate" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"capability":"…","checkoutPublicId":"…"}'

List campaigns

GET /api/v1/campaigns

Lists campaigns, newest activity first: sent issues by send date, scheduled ones by send time, drafts by last edit. Email content is left out; get_campaign has it. Filter channel sms to list pilot campaigns without an email plan.

MCP tool list_campaigns Key content:read Read-only Safe to repeat

Parameter Description
newsletterquery · string Only this newsletter’s: its ID or slug. Default: every newsletter.
channelquery · “email” “sms”
statusquery · “draft” “scheduled”
limitquery · integer How many, 50 by default, 200 at most

Request

curl "https://mail.apresly.com/api/v1/campaigns?status=sent&limit=10" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Get a campaign

GET /api/v1/campaigns/ {id}

Gets a campaign with its content, stats and, for drafts, what would block sending it now.

MCP tool get_campaign Key content:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string The campaign’s ID

Request

curl "https://mail.apresly.com/api/v1/campaigns/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Get a campaign’s report

GET /api/v1/campaigns/ {id} /report

Delivery, open, click, bounce, complaint and unsubscribe rates of a sent campaign, its list cleanup emails, results by inbox provider, and remaining contacts. SMS returns delivery status counts and reserved, committed and released USD caps without email engagement metrics.

MCP tool get_campaign_report Key content:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string The campaign’s ID

Request

curl "https://mail.apresly.com/api/v1/campaigns/6650f1c2e9b1d4a012345678/report" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Create a draft campaign

POST /api/v1/campaigns

Creates an email draft by default, or an SMS draft with channel sms, name, sms.senderId, sms.template and a stable requestId. SMS rejects email content, archive and segments; at most 100 newsletter groups. Prepare and approve a review before sending.

MCP tool create_campaign Key content:write

Parameter Description
channelbody · “email” “sms”
namebody · string Private SMS campaign name, at most 200 characters
smsbody · object SMS sender and plain text; only {{first_name}} personalization is supported
sms.senderIdrequiredbody · string
sms.templaterequiredbody · string
requestIdbody · string Required for SMS: stable UUID reused with identical input after a timeout
newsletterbody · string The newsletter’s ID or slug. Default: the account’s first newsletter, the one it has had longest.
groupIdsbody · string[] SMS: union of up to 100 newsletter groups; empty selects the newsletter
subjectbody · string Subject line, 200 characters at most
previewTextbody · string Text inbox apps show after the subject, 300 characters at most
formatbody · “markdown” “rich”
contentbody · string The body in that format, 500 KB at most
archiveSlugbody · string The issue’s page path once sent. Default: made from the subject; a taken slug gets a number.
segmentbody · string null
audienceRulesbody · object null

Request

curl -X POST "https://mail.apresly.com/api/v1/campaigns" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"subject":"This week","previewText":"Three links worth your time","content":"# This week\n\nThree links worth your time."}'

Update a draft campaign

PATCH /api/v1/campaigns/ {id}

Changes an unapproved draft using its expectedRevision. Content, segment and organizational group selection share one revision. Stale edits conflict without overwriting text. Scheduled or approved campaigns cannot be edited.

MCP tool update_campaign Key content:write Safe to repeat

Parameter Description
channelbody · “email” “sms”
namebody · string Private SMS campaign name, at most 200 characters
smsbody · object SMS sender and plain text; only {{first_name}} personalization is supported
sms.senderIdrequiredbody · string
sms.templaterequiredbody · string
requestIdbody · string Required for SMS: stable UUID reused with identical input after a timeout
idrequiredpath · string The campaign’s ID
expectedRevisionrequiredbody · integer The revision last read by this editor; stale edits return conflict
groupIdsbody · string[] SMS: union of up to 100 newsletter groups; empty selects the newsletter
audienceLimitbody · integer null
subjectbody · string Subject line, 200 characters at most
previewTextbody · string Text inbox apps show after the subject, 300 characters at most
formatbody · “markdown” “rich”
contentbody · string The body in that format, 500 KB at most
segmentbody · string null
audienceRulesbody · object null

Request

curl -X PATCH "https://mail.apresly.com/api/v1/campaigns/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"expectedRevision":"…","subject":"This week, and one more link"}'

Delete a draft campaign

DELETE /api/v1/campaigns/ {id}

Deletes a draft or scheduled campaign: it leaves every list and a scheduled send never goes out. Sent campaigns can’t be deleted.

MCP tool delete_campaign Key content:write Can’t be undone Safe to repeat

Parameter Description
idrequiredpath · string The campaign’s ID

Request

curl -X DELETE "https://mail.apresly.com/api/v1/campaigns/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Duplicate a campaign

POST /api/v1/campaigns/ {id} /duplicate

Copies a campaign’s subject, preview text and content into a new draft.

MCP tool duplicate_campaign Key content:write

Parameter Description
idrequiredpath · string The campaign’s ID

Request

curl -X POST "https://mail.apresly.com/api/v1/campaigns/6650f1c2e9b1d4a012345678/duplicate" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Send a test email

POST /api/v1/campaigns/ {id} /test

Sends the saved campaign to the specified test address, or the signed-in user/account owner when omitted, with [Test] in the subject. It counts toward the account’s email allowance.

MCP tool send_test_email Key messages:send Reaches outside ApresMail

Parameter Description
idrequiredpath · string The campaign’s ID
tobody · string The test email destination; omitted uses the signed-in user or account owner

Request

curl -X POST "https://mail.apresly.com/api/v1/campaigns/6650f1c2e9b1d4a012345678/test" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Schedule a reviewed campaign

POST /api/v1/campaigns/ {id} /schedule

Approves a retained review for a future schedule. Sending can’t be undone: messages can’t be recalled once they go out. Ask the user to confirm first. Requires review ID, revision, digest and stable request UUID; no live audience is selected here.

MCP tool schedule_campaign Key messages:send Can’t be undone Safe to repeat Reaches outside ApresMail

Parameter Description
idrequiredpath · string The campaign’s ID
expectedCapMicrousdbody · string SMS only: exact maximum micro-USD cost returned by the ready review
reviewIdbody · string Retained ready review ID belonging to this campaign
expectedRevisionbody · integer Draft revision captured by this review
snapshotDigestbody · string Exact snapshot digest returned by the ready review
requestIdbody · string Stable approval UUID; reuse the same value and input after a timeout
validityHoursbody · integer Execution validity after its due time, 1 to 72 hours; default 24
audienceLimitbody · integer Maximum contacts to include in this preview
segmentbody · string null
scheduledAtbody · string Scheduled ISO instant
timezonebody · string IANA timezone
localDateTimebody · string Local wall-clock time

Request

curl -X POST "https://mail.apresly.com/api/v1/campaigns/6650f1c2e9b1d4a012345678/schedule" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Cancel a reviewed schedule

POST /api/v1/campaigns/ {id} /unschedule

Changes only the specified approved execution. Requires its current lifecycle revision and a stable request UUID. Unknown deliveries are never retried.

MCP tool unschedule_campaign Key content:write Safe to repeat

Parameter Description
idrequiredpath · string The campaign’s ID
reviewIdrequiredbody · string The review’s ID
requestIdrequiredbody · string Stable UUID for this lifecycle request; reuse after a timeout
expectedLifecycleRevisionrequiredbody · integer Lifecycle revision returned by the latest review read
expectedUnknownGenerationbody · integer Unknown-outcome generation explicitly acknowledged on resume; zero for a clean execution

Request

curl -X POST "https://mail.apresly.com/api/v1/campaigns/6650f1c2e9b1d4a012345678/unschedule" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"reviewId":"…","requestId":"…","expectedLifecycleRevision":"…"}'

Send a reviewed campaign now

POST /api/v1/campaigns/ {id} /send

Approves exactly the retained review for sending now. Sending can’t be undone: messages can’t be recalled once they go out. Ask the user to confirm first. Requires review ID, revision, digest and stable request UUID; no live audience is selected here.

MCP tool send_campaign Key messages:send Can’t be undone Safe to repeat Reaches outside ApresMail

Parameter Description
idrequiredpath · string The campaign’s ID
expectedCapMicrousdbody · string SMS only: exact maximum micro-USD cost returned by the ready review
reviewIdbody · string Retained ready review ID belonging to this campaign
expectedRevisionbody · integer Draft revision captured by this review
snapshotDigestbody · string Exact snapshot digest returned by the ready review
requestIdbody · string Stable approval UUID; reuse the same value and input after a timeout
validityHoursbody · integer Execution validity after its due time, 1 to 72 hours; default 24
audienceLimitbody · integer Maximum contacts to include in this preview
segmentbody · string null

Request

curl -X POST "https://mail.apresly.com/api/v1/campaigns/6650f1c2e9b1d4a012345678/send" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Send a campaign to more contacts

POST /api/v1/campaigns/ {id} /send-more

Disabled: duplicate the campaign and prepare a new review for another intentional send. Sending can’t be undone: messages can’t be recalled once they go out. Ask the user to confirm first.

MCP tool send_campaign_to_more Key messages:send Can’t be undone Reaches outside ApresMail

Parameter Description
idrequiredpath · string The campaign’s ID
additionalbody · integer Legacy input; this operation always conflicts

Request

curl -X POST "https://mail.apresly.com/api/v1/campaigns/6650f1c2e9b1d4a012345678/send-more" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Pause a reviewed campaign

POST /api/v1/campaigns/ {id} /pause

Changes only the specified approved execution. Requires its current lifecycle revision and a stable request UUID. Unknown deliveries are never retried.

MCP tool pause_campaign Key content:write Safe to repeat

Parameter Description
idrequiredpath · string The campaign’s ID
reviewIdrequiredbody · string The review’s ID
requestIdrequiredbody · string Stable UUID for this lifecycle request; reuse after a timeout
expectedLifecycleRevisionrequiredbody · integer Lifecycle revision returned by the latest review read
expectedUnknownGenerationbody · integer Unknown-outcome generation explicitly acknowledged on resume; zero for a clean execution

Request

curl -X POST "https://mail.apresly.com/api/v1/campaigns/6650f1c2e9b1d4a012345678/pause" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"reviewId":"…","requestId":"…","expectedLifecycleRevision":"…"}'

Resume a reviewed campaign

POST /api/v1/campaigns/ {id} /resume

Changes only the specified approved execution. Sending can’t be undone: messages can’t be recalled once they go out. Ask the user to confirm first. Requires its current lifecycle revision and a stable request UUID. Unknown deliveries are never retried.

MCP tool resume_campaign Key messages:send Can’t be undone Safe to repeat Reaches outside ApresMail

Parameter Description
idrequiredpath · string The campaign’s ID
reviewIdrequiredbody · string The review’s ID
requestIdrequiredbody · string Stable UUID for this lifecycle request; reuse after a timeout
expectedLifecycleRevisionrequiredbody · integer Lifecycle revision returned by the latest review read
expectedUnknownGenerationbody · integer Unknown-outcome generation explicitly acknowledged on resume; zero for a clean execution

Request

curl -X POST "https://mail.apresly.com/api/v1/campaigns/6650f1c2e9b1d4a012345678/resume" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"reviewId":"…","requestId":"…","expectedLifecycleRevision":"…"}'

Cancel an approved campaign

POST /api/v1/campaigns/ {id} /cancel

Permanently cancels this approved execution and suppresses unstarted queued/held work in bounded batches. Provider-started and unknown deliveries remain unchanged.

MCP tool cancel_campaign Key content:write Can’t be undone Safe to repeat

Parameter Description
idrequiredpath · string The campaign’s ID
reviewIdrequiredbody · string The review’s ID
requestIdrequiredbody · string Stable UUID for this lifecycle request; reuse after a timeout
expectedLifecycleRevisionrequiredbody · integer Lifecycle revision returned by the latest review read
expectedUnknownGenerationbody · integer Unknown-outcome generation explicitly acknowledged on resume; zero for a clean execution

Request

curl -X POST "https://mail.apresly.com/api/v1/campaigns/6650f1c2e9b1d4a012345678/cancel" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"reviewId":"…","requestId":"…","expectedLifecycleRevision":"…"}'

Update a campaign’s archive page

PATCH /api/v1/campaigns/ {id} /archive

Changes the path of a campaign’s archive page (/p/), or pins a sent issue to the top of the archive. Works on sent campaigns too.

MCP tool update_campaign_archive Key settings:manage Safe to repeat

Parameter Description
idrequiredpath · string The campaign’s ID
expectedRevisionbody · integer Required when changing the archive slug; the revision last read by this editor
slugbody · string Lowercase letters, digits and dashes. Empty removes it from a draft.
pinnedbody · boolean Pinned issues lead the archive

Request

curl -X PATCH "https://mail.apresly.com/api/v1/campaigns/6650f1c2e9b1d4a012345678/archive" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"pinned":true}'

Preview the list cleanup of a send

GET /api/v1/campaigns/ {id} /cleanup-preview

Counts what the newsletter’s list cleanup would do if the campaign went out now: issues sent, last-chance emails instead, contacts still waiting to answer one, and contacts made dormant. Reads the whole list, so it can take a few seconds.

MCP tool preview_campaign_cleanup Key content:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string The campaign’s ID
audienceLimitquery · integer Count for a send capped at this many contacts
includeRanksquery · boolean Also return, for each cold contact, how many issue recipients come before it, to recount any limit without asking again

Request

curl "https://mail.apresly.com/api/v1/campaigns/6650f1c2e9b1d4a012345678/cleanup-preview" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Preview campaign audience

GET /api/v1/campaigns/ {id} /audience-preview

Counts current eligible recipients in a saved v2 email draft using its groups, segment and additional conditions. The dashboard can preview validated unsaved selection changes without writing them. Read-only; no review, schedule or email is created. Counts are a live observation and can change before sending.

MCP tool preview_campaign_audience Key content:read + audience:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string The campaign’s ID
expectedRevisionrequiredquery · integer The revision last read by this editor; stale edits return conflict

Request

curl "https://mail.apresly.com/api/v1/campaigns/6650f1c2e9b1d4a012345678/audience-preview" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Prepare a campaign review

POST /api/v1/campaigns/ {id} /reviews

Freezes this draft’s content and audience selection for a bounded background review. Does not approve or send messages. The same request ID and input returns its original review, including a terminal result; different input conflicts.

MCP tool prepare_campaign_review Key content:write Safe to repeat

Parameter Description
idrequiredpath · string Campaign ID in this account
expectedRevisionrequiredbody · integer Draft revision that the operator reviewed
requestIdrequiredbody · string Stable UUID for this preparation request; reuse it after a timeout

Request

curl -X POST "https://mail.apresly.com/api/v1/campaigns/6650f1c2e9b1d4a012345678/reviews" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"expectedRevision":"…","requestId":"…"}'

Get a campaign review

GET /api/v1/campaigns/ {id} /reviews/ {reviewId}

Reads an explicit summary of retained campaign review content, selection, counters and lifecycle. Preparation diagnostics may be stale and do not grant permission to send. Historical reads remain available while review preparation is disabled.

MCP tool get_campaign_review Key content:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string Campaign ID in this account
reviewIdrequiredpath · string Review ID belonging to this campaign and account

Request

curl "https://mail.apresly.com/api/v1/campaigns/6650f1c2e9b1d4a012345678/reviews/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

List campaign review recipients

GET /api/v1/campaigns/ {id} /reviews/ {reviewId} /recipients

Reads a bounded retained audience snapshot, not current sending permission. Building reviews conflict. Erased or missing canonical recipients are omitted immediately; an empty page may still have nextCursor. Historical reads remain available while preparation is disabled.

MCP tool list_campaign_review_recipients Key audience:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string Campaign ID in this account
reviewIdrequiredpath · string Review ID belonging to this campaign and account
cursorquery · string Previous page nextCursor for this exact review
limitquery · integer Raw snapshot rows per page, 1 to 100; defaults to 50

Request

curl "https://mail.apresly.com/api/v1/campaigns/6650f1c2e9b1d4a012345678/reviews/6650f1c2e9b1d4a012345678/recipients" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Preview frozen campaign content

GET /api/v1/campaigns/ {id} /reviews/ {reviewId} /preview

Reads the retained email preview or a synthetic SMS example including its complete unsubscribe-link length. Links are disabled and no tracking or unsubscribe credentials are generated. Never renders mutable newsletter defaults.

MCP tool get_campaign_review_preview Key content:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string Campaign ID in this account
reviewIdrequiredpath · string Review ID belonging to this campaign and account

Request

curl "https://mail.apresly.com/api/v1/campaigns/6650f1c2e9b1d4a012345678/reviews/6650f1c2e9b1d4a012345678/preview" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Approve a campaign review

POST /api/v1/campaigns/ {id} /reviews/ {reviewId} /approve

Approves exactly the retained content and audience snapshot. Sending can’t be undone. Reuse the same request UUID and input after a timeout; changed input conflicts.

MCP tool approve_campaign_review Key messages:send Can’t be undone Safe to repeat Reaches outside ApresMail

Parameter Description
expectedCapMicrousdbody · string SMS only: exact maximum micro-USD cost returned by the ready review
reviewIdrequiredpath · string Retained ready review ID belonging to this campaign
expectedRevisionrequiredbody · integer Draft revision captured by this review
snapshotDigestrequiredbody · string Exact snapshot digest returned by the ready review
requestIdrequiredbody · string Stable approval UUID; reuse the same value and input after a timeout
validityHoursbody · integer Execution validity after its due time, 1 to 72 hours; default 24
moderequiredbody · “now” “scheduled”
scheduledAtbody · string Scheduled ISO instant; required only for scheduled mode
timezonebody · string IANA timezone of the schedule
localDateTimebody · string Local wall-clock time represented by scheduledAt
idrequiredpath · string Campaign ID in this account

Request

curl -X POST "https://mail.apresly.com/api/v1/campaigns/6650f1c2e9b1d4a012345678/reviews/6650f1c2e9b1d4a012345678/approve" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"expectedRevision":"…","snapshotDigest":"…","requestId":"…","mode":"…"}'

Overview

Subscribers, email results and sends per hour, as on the dashboard’s first page.

Get the overview

GET /api/v1/overview

The dashboard’s overview for one newsletter: subscribers each day of the last 30 days, email results of the last 30 days against the 30 before, emails sent per hour today and yesterday, and the plan’s usage this month, which the account’s newsletters share.

MCP tool get_overview Key content:read Read-only Safe to repeat

Parameter Description
newsletterquery · string The newsletter’s ID or slug. Default: the account’s first newsletter, the one it has had longest.
timeZonequery · string IANA time zone for days and hours, e.g. Europe/Paris. Default: UTC.

Request

curl "https://mail.apresly.com/api/v1/overview?timeZone=Europe%2FParis" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Newsletters

Sender, postal address, welcome and confirmation emails, list cleanup, archive and theme.

List newsletters

GET /api/v1/newsletters

Lists the account’s newsletters, 3 at most, first created first, with their settings and active contacts. Actions that take a newsletter use the first one when it’s left out.

MCP tool list_newsletters Key content:read Read-only Safe to repeat

Request

curl "https://mail.apresly.com/api/v1/newsletters" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Get a newsletter

GET /api/v1/newsletters/ {id}

Gets a newsletter’s settings: sender, postal address, welcome and confirmation emails, list cleanup, archive and theme.

MCP tool get_newsletter Key content:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string The newsletter’s ID or slug

Request

curl "https://mail.apresly.com/api/v1/newsletters/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Create a newsletter

POST /api/v1/newsletters

Creates a newsletter. An account has up to 3, sharing its account’s assigned email and subscriber limits; one more answers conflict. Without a fromEmail it sends from the shared address hello@., which ApresMail sets up in a few minutes. List cleanup is on unless cleanup.enabled is false. Without a postalAddress, its emails print the server’s default if it has one: the administrator-configured address.

MCP tool create_newsletter Key settings:manage + messages:send

Parameter Description
namerequiredbody · string The newsletter’s name, shown in emails and on the archive
slugbody · string Lowercase letters, digits and dashes. Default: made from the name, numbered when another newsletter has it.
imageUrlbody · string Square logo, 128×128 or larger: an https:// link
fromNamebody · string Name in the From field
fromEmailbody · string The shared address (hello@., set automatically) or an address on a domain added to this account
replyTobody · string Where replies go. Empty: replies to the shared address go to the account owner.
postalAddressbody · string Printed in the footer of every email. Never set, it uses the configured default; saved empty, there is none and sending waits for one.
archiveEnabledbody · boolean A public page for each sent issue, with a signup form. On for new newsletters: the website goes live after the first issue.
descriptionbody · string One sentence under the name on the archive, 200 characters at most
authorbody · object The archive’s author page; the author’s name is fromName
author.biobody · string Under the author’s name on the archive, 160 characters at most
author.imageUrlbody · string Author photo: an https:// link. The newsletter image otherwise.
socialLinksbody · string[] https:// links shown on the archive, 8 at most
requireConfirmationbody · boolean Confirmed opt-in: new signups get an email with a button and only join once they click it. On for new newsletters. New subscribers get the confirmation email or the welcome email: turning it on while the welcome email is on needs welcome.enabled false in the same request.
cleanupbody · object List cleanup at each send: contacts who ignored several issues get a last-chance email instead, and become dormant if they don’t answer
cleanup.enabledbody · boolean On for new newsletters
cleanup.issuesbody · number null
cleanup.daysbody · number null
welcomebody · object Email sent to each new subscriber, while signups don’t need confirming: turning it on while requireConfirmation is on needs requireConfirmation false in the same request.
welcome.enabledbody · boolean
welcome.subjectbody · string
welcome.previewTextbody · string
welcome.markdownbody · string Markdown
confirmationbody · object The confirmation email for confirmed opt-in. Sent back unchanged, the built-in one stays built-in and follows the name and description.
confirmation.subjectbody · string
confirmation.previewTextbody · string
confirmation.markdownbody · string Markdown that keeps the button: an HTML link like <a href="{{confirm_url}}">Confirm</a>
themebody · object Its look on its website and in its emails: a preset from list_themes and what’s changed on top of it. Send only what changes; null takes a choice back to the preset’s.
theme.presetbody · “mailcheap” “broadsheet”
theme.colorsbody · object null
theme.fontsbody · object null
theme.headingWeightbody · integer null
theme.radiusbody · string null
theme.shadowbody · string null
theme.spacingbody · string null

Request

curl -X POST "https://mail.apresly.com/api/v1/newsletters" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Field notes","postalAddress":"Field Notes Ltd, 1 Main St, Paris, France"}'

Update a newsletter

PATCH /api/v1/newsletters/ {id}

Changes a newsletter’s settings. Send only the fields to change; nested groups (welcome, confirmation, cleanup, author) keep the fields you leave out. An account changes slugs 3 times a day at most: one more answers rate_limited.

MCP tool update_newsletter Key settings:manage + messages:send Safe to repeat

Parameter Description
idrequiredpath · string The newsletter’s ID or slug
namebody · string The newsletter’s name, shown in emails and on the archive
slugbody · string Lowercase letters, digits and dashes, not a name ApresMail keeps like www, api or mail. The shared from address (hello@.) and the archive subdomain follow it.
imageUrlbody · string Square logo, 128×128 or larger: an https:// link
fromNamebody · string Name in the From field
fromEmailbody · string The shared address (hello@., set automatically) or an address on a domain added to this account
replyTobody · string Where replies go. Empty: replies to the shared address go to the account owner.
postalAddressbody · string Printed in the footer of every email. Never set, it uses the configured default; saved empty, there is none and sending waits for one.
archiveEnabledbody · boolean A public page for each sent issue, with a signup form. On for new newsletters: the website goes live after the first issue.
descriptionbody · string One sentence under the name on the archive, 200 characters at most
authorbody · object The archive’s author page; the author’s name is fromName
author.biobody · string Under the author’s name on the archive, 160 characters at most
author.imageUrlbody · string Author photo: an https:// link. The newsletter image otherwise.
socialLinksbody · string[] https:// links shown on the archive, 8 at most
requireConfirmationbody · boolean Confirmed opt-in: new signups get an email with a button and only join once they click it. On for new newsletters. New subscribers get the confirmation email or the welcome email: turning it on while the welcome email is on needs welcome.enabled false in the same request.
cleanupbody · object List cleanup at each send: contacts who ignored several issues get a last-chance email instead, and become dormant if they don’t answer
cleanup.enabledbody · boolean On for new newsletters
cleanup.issuesbody · number null
cleanup.daysbody · number null
welcomebody · object Email sent to each new subscriber, while signups don’t need confirming: turning it on while requireConfirmation is on needs requireConfirmation false in the same request.
welcome.enabledbody · boolean
welcome.subjectbody · string
welcome.previewTextbody · string
welcome.markdownbody · string Markdown
confirmationbody · object The confirmation email for confirmed opt-in. Sent back unchanged, the built-in one stays built-in and follows the name and description.
confirmation.subjectbody · string
confirmation.previewTextbody · string
confirmation.markdownbody · string Markdown that keeps the button: an HTML link like <a href="{{confirm_url}}">Confirm</a>
themebody · object Its look on its website and in its emails: a preset from list_themes and what’s changed on top of it. Send only what changes; null takes a choice back to the preset’s.
theme.presetbody · “mailcheap” “broadsheet”
theme.colorsbody · object null
theme.fontsbody · object null
theme.headingWeightbody · integer null
theme.radiusbody · string null
theme.shadowbody · string null
theme.spacingbody · string null

Request

curl -X PATCH "https://mail.apresly.com/api/v1/newsletters/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"replyTo":"[email protected]","requireConfirmation":true}'

List themes

GET /api/v1/themes

Lists the theme presets a newsletter can take, with their colors, fonts and choices, and the options to change them with: fonts, heading weights, radius, shadow and spacing. update_newsletter’s theme sets them.

MCP tool list_themes Key content:read Read-only Safe to repeat

Request

curl "https://mail.apresly.com/api/v1/themes" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Check a slug

GET /api/v1/newsletters/slugs/ {slug}

Says whether a newsletter can take a slug: available, or taken by another newsletter, reserved by ApresMail or invalid, with the message saving it would answer. Checking doesn’t count toward the 3 slug changes a day.

MCP tool check_newsletter_slug Key content:read Read-only Safe to repeat

Parameter Description
slugrequiredpath · string The slug to check
idquery · string The newsletter that would take it, by ID or slug: its own slug is available to it

Request

curl "https://mail.apresly.com/api/v1/newsletters/slugs/6650f1c2e9b1d4a012345678?slug=field-notes" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Send a test of the welcome email

POST /api/v1/newsletters/ {id} /welcome-test

Sends the saved welcome email to the account owner’s address, switched on or not. It counts toward the plan’s emails.

MCP tool send_welcome_test_email Key messages:send Reaches outside ApresMail

Parameter Description
idrequiredpath · string The newsletter’s ID or slug

Request

curl -X POST "https://mail.apresly.com/api/v1/newsletters/6650f1c2e9b1d4a012345678/welcome-test" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

SMS

Get SMS settings

GET /api/v1/sms/settings

Shows the account’s controlled SMS pilot limit. This is a spending cap, not a bill or retail price.

MCP tool get_sms_settings Key content:read Read-only Safe to repeat

Request

curl "https://mail.apresly.com/api/v1/sms/settings" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

List SMS senders

GET /api/v1/sms/senders

Lists this account’s approved or pending brand senders without AWS resource details.

MCP tool list_sms_senders Key content:read Read-only Safe to repeat

Parameter Description
cursorquery · string The resource ID in this account
limitquery · integer Number of senders per page, up to 100

Request

curl "https://mail.apresly.com/api/v1/sms/senders" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

PUT /api/v1/newsletters/ {id} /sms-consent

Sets this newsletter’s separate SMS wording and approved confirmation sender. It never grants SMS consent.

MCP tool update_newsletter_sms_consent Key settings:manage + messages:send Safe to repeat

Parameter Description
idrequiredpath · string The resource ID in this account
expectedRevisionrequiredbody · integer The current version; stale changes are rejected
requestIdrequiredbody · string A unique request ID; reuse unchanged after an uncertain result
senderIdrequiredbody · string The resource ID in this account
wordingTextrequiredbody · string Separate SMS consent wording shown to subscribers
privacyUrlrequiredbody · string Published HTTPS privacy policy URL for this newsletter

Request

curl -X PUT "https://mail.apresly.com/api/v1/newsletters/6650f1c2e9b1d4a012345678/sms-consent" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"expectedRevision":"…","requestId":"…","senderId":"…","wordingText":"…","privacyUrl":"…"}'

Get subscriber SMS preferences

GET /api/v1/subscribers/ {id} /sms

Shows a masked verified phone and independent SMS preferences; never exposes a full phone number.

MCP tool get_subscriber_sms Key audience:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string The resource ID in this account

Request

curl "https://mail.apresly.com/api/v1/subscribers/6650f1c2e9b1d4a012345678/sms" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Remove subscriber SMS phone

DELETE /api/v1/subscribers/ {id} /sms/phone

Removes the phone and withdraws all its SMS consents. Email subscriptions remain unchanged.

MCP tool remove_subscriber_sms_phone Key audience:write + audience:read Can’t be undone Safe to repeat

Parameter Description
idrequiredpath · string The resource ID in this account
expectedPhoneVersionrequiredquery · integer The current version; stale changes are rejected
requestIdrequiredquery · string A unique request ID; reuse unchanged after an uncertain result

Request

curl -X DELETE "https://mail.apresly.com/api/v1/subscribers/6650f1c2e9b1d4a012345678/sms/phone" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

POST /api/v1/subscribers/ {id} /sms/subscriptions/ {subscriptionId} /withdraw

Withdraws SMS permission for one newsletter, cancels pending confirmation and keeps other preferences unchanged. Cannot grant consent.

MCP tool withdraw_subscriber_sms Key audience:write + audience:read Safe to repeat

Parameter Description
idrequiredpath · string The resource ID in this account
subscriptionIdrequiredpath · string The resource ID in this account
expectedVersionrequiredbody · integer The current version; stale changes are rejected
requestIdrequiredbody · string A unique request ID; reuse unchanged after an uncertain result

Request

curl -X POST "https://mail.apresly.com/api/v1/subscribers/6650f1c2e9b1d4a012345678/sms/subscriptions/6650f1c2e9b1d4a012345678/withdraw" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"expectedVersion":"…","requestId":"…"}'

Contacts

Newsletter-specific compatibility actions. On v2, a contact ID is a NewsletterSubscription ID; add is organizational by default; explicit subscribe:true records owner authorization for unrestricted subscriptions without recipient confirmation. Imports do not imply consent, no welcome/sequence mail starts, and delete removes only that subscription.

Inspect proposed import recipients

POST /api/v1/contacts/import-preview

Preview only. No contacts or consent were changed. Reads consent for the selected newsletter on v2 accounts, current account-wide consent on v1 accounts, and independent restrictions for up to 200 addresses in one request snapshot. Different requests do not share a snapshot; these diagnostics never authorize delivery.

MCP tool inspect_import_recipients Key audience:read Read-only Safe to repeat

Parameter Description
newsletterrequiredbody · string Newsletter ID or slug in this account
recordsrequiredbody · object[] One through 200 distinct normalized addresses to inspect; no records are written
records[].ordinalrequiredbody · integer Unique address ordinal in the local analysis, 1 through 25000
records[].emailrequiredbody · string Normalized email; lowercase, no surrounding whitespace, preserving dots and plus suffixes

Request

curl -X POST "https://mail.apresly.com/api/v1/contacts/import-preview" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"newsletter":"weekly","records":"…"}'

Create subscriber import

POST /api/v1/subscriber-imports

Bounded durable CSV import for one newsletter. Simple csv requires one profiles file and an existing target group, without migration evidence. New simple CSV runs authorize eligible blank/active subscriptions after exact-plan approval; existing restrictions and older runs retain their meaning. Owner-authorized approval and apply also require sending permission for scoped agents. Classic source active status alone never grants consent. No email, DOI or sequence is started. Verify your export columns and statuses; real Classic export qualification remains separate.

MCP tool create_subscriber_import Key audience:write + audience:read Safe to repeat

Parameter Description
newsletterIdrequiredbody · string The one existing newsletter receiving this import.
sourceKindrequiredbody · “mailerlite-classic-csv” “csv”
requestKeyrequiredbody · string Stable idempotency key; retry exactly the same payload with this key.
filesrequiredbody · object[] Confirmed file roles, headers and owner-declared source byte hashes; no raw file is stored.
files[].fileRolerequiredbody · “profiles” “statuses”
files[].headerrequiredbody · string[]
files[].delimiterrequiredbody · “comma” “semicolon”
files[].declaredRowsrequiredbody · integer
files[].byteCountrequiredbody · integer
files[].ownerDeclaredFileSha256requiredbody · string
mappingrequiredbody · object Explicit header, source status, group delimiter and timestamp mappings.
mapping.profilesrequiredbody · object
mapping.statusesbody · object
mapping.membershipsbody · object
mapping.timestampFormatbody · “iso-utc” “classic-utc”
mapping.timezonebody · string
mapping.groupSeparatorbody · string
mapping.statusValuesbody · object
sourceContextbody · object Required only for Classic: source account/newsletter identity and UTC extraction time. Omit for csv.
sourceContext.sourceAccountIdrequiredbody · string
sourceContext.sourceNewsletterIdrequiredbody · string
sourceContext.extractedAtrequiredbody · string
groupMappingsbody · object[] Explicit source group to newsletter-scoped existing or new group mapping.
groupMappings[].sourceGroupIdrequiredbody · string
groupMappings[].targetrequiredbody · object
constantGroupbody · object For csv, one required existing group in the target newsletter. Optional for Classic. Membership never grants consent.
evidencePolicybody · object csv requires only version csv_facts_v1; new simple runs activate eligible subscriptions through owner authorization, without claiming recipient confirmation. Classic retains its closed facts-only or reviewed source policy.
evidencePolicy.versionrequiredbody · “classic_csv_facts_v1” “classic_confirmation_record_v1”
evidencePolicy.sourceNewsletterIdbody · string
evidencePolicy.artifactSha256body · string
evidencePolicy.acknowledgedSourceAssertionbody · boolean

Request

curl -X POST "https://mail.apresly.com/api/v1/subscriber-imports" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"newsletterId":"…","sourceKind":"…","requestKey":"…","files":"…","mapping":"…"}'

Upload subscriber import chunk

POST /api/v1/subscriber-imports/ {id} /chunks

Bounded durable CSV import for one newsletter. Simple csv requires one profiles file and an existing target group, without migration evidence. New simple CSV runs authorize eligible blank/active subscriptions after exact-plan approval; existing restrictions and older runs retain their meaning. Owner-authorized approval and apply also require sending permission for scoped agents. Classic source active status alone never grants consent. No email, DOI or sequence is started. Verify your export columns and statuses; real Classic export qualification remains separate.

MCP tool upload_subscriber_import_chunk Key audience:write + audience:read Safe to repeat

Parameter Description
idrequiredpath · string The opaque import run ID in this account.
revisionrequiredbody · integer The latest run revision; stale writes return a conflict.
requestKeyrequiredbody · string Stable idempotency key; retry exactly the same payload with this key.
fileRolerequiredbody · “profiles” “statuses”
chunkIndexrequiredbody · integer Contiguous zero-based chunk index for this role.
rowsrequiredbody · object[] Up to 200 raw cell arrays with contiguous one-based source ordinals.
rows[].ordinalrequiredbody · integer
rows[].cellsrequiredbody · string[]
declaredDigestrequiredbody · string SHA256 of JSON.stringify(rows), verified independently by the server.

Request

curl -X POST "https://mail.apresly.com/api/v1/subscriber-imports/6650f1c2e9b1d4a012345678/chunks" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"revision":"…","requestKey":"…","fileRole":"…","chunkIndex":"…","rows":"…","declaredDigest":"…"}'

Stage subscriber import

POST /api/v1/subscriber-imports/ {id} /stage

Bounded durable CSV import for one newsletter. Simple csv requires one profiles file and an existing target group, without migration evidence. New simple CSV runs authorize eligible blank/active subscriptions after exact-plan approval; existing restrictions and older runs retain their meaning. Owner-authorized approval and apply also require sending permission for scoped agents. Classic source active status alone never grants consent. No email, DOI or sequence is started. Verify your export columns and statuses; real Classic export qualification remains separate.

MCP tool stage_subscriber_import Key audience:write + audience:read Safe to repeat

Parameter Description
idrequiredpath · string The opaque import run ID in this account.
revisionrequiredbody · integer The latest run revision; stale writes return a conflict.
requestKeyrequiredbody · string Stable idempotency key; retry exactly the same payload with this key.
uploadedCountsrequiredbody · object Exact uploaded row counts per role.
canonicalDigestrequiredbody · string Authoritative canonical digest returned by the last upload.

Request

curl -X POST "https://mail.apresly.com/api/v1/subscriber-imports/6650f1c2e9b1d4a012345678/stage" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"revision":"…","requestKey":"…","uploadedCounts":"…","canonicalDigest":"…"}'

Preview subscriber import

POST /api/v1/subscriber-imports/ {id} /preview

Bounded durable CSV import for one newsletter. Simple csv requires one profiles file and an existing target group, without migration evidence. New simple CSV runs authorize eligible blank/active subscriptions after exact-plan approval; existing restrictions and older runs retain their meaning. Owner-authorized approval and apply also require sending permission for scoped agents. Classic source active status alone never grants consent. No email, DOI or sequence is started. Verify your export columns and statuses; real Classic export qualification remains separate.

MCP tool preview_subscriber_import Key audience:write + audience:read Safe to repeat

Parameter Description
idrequiredpath · string The opaque import run ID in this account.
revisionrequiredbody · integer The latest run revision; stale writes return a conflict.
requestKeyrequiredbody · string Stable idempotency key; retry exactly the same payload with this key.

Request

curl -X POST "https://mail.apresly.com/api/v1/subscriber-imports/6650f1c2e9b1d4a012345678/preview" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"revision":"…","requestKey":"…"}'

Get subscriber import

GET /api/v1/subscriber-imports/ {id}

Bounded durable CSV import for one newsletter. Simple csv requires one profiles file and an existing target group, without migration evidence. New simple CSV runs authorize eligible blank/active subscriptions after exact-plan approval; existing restrictions and older runs retain their meaning. Owner-authorized approval and apply also require sending permission for scoped agents. Classic source active status alone never grants consent. No email, DOI or sequence is started. Verify your export columns and statuses; real Classic export qualification remains separate.

MCP tool get_subscriber_import Key audience:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string The opaque import run ID in this account.

Request

curl "https://mail.apresly.com/api/v1/subscriber-imports/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

List subscriber imports

GET /api/v1/subscriber-imports

Bounded durable CSV import for one newsletter. Simple csv requires one profiles file and an existing target group, without migration evidence. New simple CSV runs authorize eligible blank/active subscriptions after exact-plan approval; existing restrictions and older runs retain their meaning. Owner-authorized approval and apply also require sending permission for scoped agents. Classic source active status alone never grants consent. No email, DOI or sequence is started. Verify your export columns and statuses; real Classic export qualification remains separate.

MCP tool list_subscriber_imports Key audience:read Read-only Safe to repeat

Parameter Description
cursorquery · string Opaque signed continuation cursor from the preceding page.
limitquery · integer Maximum bounded page size.

Request

curl "https://mail.apresly.com/api/v1/subscriber-imports" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Get subscriber import rows

GET /api/v1/subscriber-imports/ {id} /rows

Bounded durable CSV import for one newsletter. Simple csv requires one profiles file and an existing target group, without migration evidence. New simple CSV runs authorize eligible blank/active subscriptions after exact-plan approval; existing restrictions and older runs retain their meaning. Owner-authorized approval and apply also require sending permission for scoped agents. Classic source active status alone never grants consent. No email, DOI or sequence is started. Verify your export columns and statuses; real Classic export qualification remains separate.

MCP tool get_subscriber_import_rows Key audience:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string The opaque import run ID in this account.
cursorquery · string Opaque signed continuation cursor from the preceding page.
limitquery · integer Maximum bounded page size.
resultCodequery · string Optional exact safe result classification filter.

Request

curl "https://mail.apresly.com/api/v1/subscriber-imports/6650f1c2e9b1d4a012345678/rows" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Approve subscriber import

POST /api/v1/subscriber-imports/ {id} /approve

Bounded durable CSV import for one newsletter. Simple csv requires one profiles file and an existing target group, without migration evidence. New simple CSV runs authorize eligible blank/active subscriptions after exact-plan approval; existing restrictions and older runs retain their meaning. Owner-authorized approval and apply also require sending permission for scoped agents. Classic source active status alone never grants consent. No email, DOI or sequence is started. Verify your export columns and statuses; real Classic export qualification remains separate.

MCP tool approve_subscriber_import Key audience:write + audience:read Safe to repeat

Parameter Description
idrequiredpath · string The opaque import run ID in this account.
revisionrequiredbody · integer The latest run revision; stale writes return a conflict.
requestKeyrequiredbody · string Stable idempotency key; retry exactly the same payload with this key.
planDigestrequiredbody · string The exact completed preview plan digest being approved or applied.
evidenceDigestrequiredbody · string The exact retained source evidence digest reviewed by the owner.
acknowledgementrequiredbody · “approve-reviewed-import” “approve-owner-authorized-import”

Request

curl -X POST "https://mail.apresly.com/api/v1/subscriber-imports/6650f1c2e9b1d4a012345678/approve" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"revision":"…","requestKey":"…","planDigest":"…","evidenceDigest":"…","acknowledgement":"…"}'

Apply subscriber import

POST /api/v1/subscriber-imports/ {id} /apply

Bounded durable CSV import for one newsletter. Simple csv requires one profiles file and an existing target group, without migration evidence. New simple CSV runs authorize eligible blank/active subscriptions after exact-plan approval; existing restrictions and older runs retain their meaning. Owner-authorized approval and apply also require sending permission for scoped agents. Classic source active status alone never grants consent. No email, DOI or sequence is started. Verify your export columns and statuses; real Classic export qualification remains separate.

MCP tool apply_subscriber_import Key audience:write + audience:read Safe to repeat

Parameter Description
idrequiredpath · string The opaque import run ID in this account.
revisionrequiredbody · integer The latest run revision; stale writes return a conflict.
requestKeyrequiredbody · string Stable idempotency key; retry exactly the same payload with this key.
planDigestrequiredbody · string The exact completed preview plan digest being approved or applied.

Request

curl -X POST "https://mail.apresly.com/api/v1/subscriber-imports/6650f1c2e9b1d4a012345678/apply" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"revision":"…","requestKey":"…","planDigest":"…"}'

Cancel subscriber import

POST /api/v1/subscriber-imports/ {id} /cancel

Bounded durable CSV import for one newsletter. Simple csv requires one profiles file and an existing target group, without migration evidence. New simple CSV runs authorize eligible blank/active subscriptions after exact-plan approval; existing restrictions and older runs retain their meaning. Owner-authorized approval and apply also require sending permission for scoped agents. Classic source active status alone never grants consent. No email, DOI or sequence is started. Verify your export columns and statuses; real Classic export qualification remains separate.

MCP tool cancel_subscriber_import Key audience:write + audience:read Can’t be undone Safe to repeat

Parameter Description
idrequiredpath · string The opaque import run ID in this account.
revisionrequiredbody · integer The latest run revision; stale writes return a conflict.
requestKeyrequiredbody · string Stable idempotency key; retry exactly the same payload with this key.

Request

curl -X POST "https://mail.apresly.com/api/v1/subscriber-imports/6650f1c2e9b1d4a012345678/cancel" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"revision":"…","requestKey":"…"}'

Export subscriber import report

POST /api/v1/subscriber-imports/ {id} /report

Bounded durable CSV import for one newsletter. Simple csv requires one profiles file and an existing target group, without migration evidence. New simple CSV runs authorize eligible blank/active subscriptions after exact-plan approval; existing restrictions and older runs retain their meaning. Owner-authorized approval and apply also require sending permission for scoped agents. Classic source active status alone never grants consent. No email, DOI or sequence is started. Verify your export columns and statuses; real Classic export qualification remains separate.

MCP tool export_subscriber_import_report Key audience:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string The opaque import run ID in this account.
cursorbody · string Opaque signed continuation cursor from the preceding page.
limitbody · integer Maximum bounded page size.
resultCodebody · string Optional exact safe result classification filter.

Request

curl -X POST "https://mail.apresly.com/api/v1/subscriber-imports/6650f1c2e9b1d4a012345678/report" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

List contacts

GET /api/v1/contacts

Lists newsletter contacts, newest signups first, 50 a page. On v2 each contact ID is a Subscription ID and email comes from its Subscriber profile. Filter by newsletter, status or the start of the email address; segment filtering remains a v1 option. Pass nextCursor back as cursor. counts has every status for the same filters.

MCP tool list_contacts Key audience:read Read-only Safe to repeat

Parameter Description
newsletterquery · string Only this newsletter’s: its ID or slug. Default: every newsletter.
statusquery · “active” “pending”
segmentquery · string Only the contacts a segment picks (its ID, from list_segments), whatever their status unless status is given. With newsletter, one of that newsletter’s segments.
searchquery · string Contacts whose email starts with this
limitquery · integer Contacts per page, 50 by default, 100 at most
cursorquery · string nextCursor from the previous page

Request

curl "https://mail.apresly.com/api/v1/contacts?status=active&search=jane" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Get a contact

GET /api/v1/contacts/ {id}

Gets one newsletter contact by Subscription ID on v2 (legacy Contact ID on v1), or by email when unambiguous. Status and engagement belong to that newsletter.

MCP tool get_contact Key audience:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string The contact’s ID or email address
newsletterquery · string The newsletter’s ID or slug, needed for an email address that is a contact of several newsletters

Request

curl "https://mail.apresly.com/api/v1/contacts/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Add a contact

POST /api/v1/contacts

Adds a contact to one newsletter. With subscribe:true on a ready unified audience, the owner authorizes a new unrestricted subscription to receive issues without recipient confirmation. Omit subscribe to add an organizational contact only. Existing withdrawals, delivery blocks and dormant states remain unchanged. Never sends a welcome or confirmation message. Requires full access.

MCP tool add_contact Key audience:write + audience:read Reaches outside ApresMail

Parameter Description
newsletterbody · string The newsletter’s ID or slug. Default: the account’s first newsletter, the one it has had longest.
emailrequiredbody · string The subscriber’s email address
sourcebody · string Where they signed up, e.g. website. Default: api.
subscribebody · boolean The owner authorizes this newsletter subscription without recipient confirmation. Unified audience and full access required. Never restores a withdrawal or removes delivery blocks.
resubscribebody · boolean Legacy option: true is rejected. Use a recipient-confirmed signup to renew consent.
ipbody · string The visitor’s IP address: one visitor gets 5 signups in 10 minutes

Request

curl -X POST "https://mail.apresly.com/api/v1/contacts" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","source":"website"}'

Change a contact’s status

PATCH /api/v1/contacts/ {id}

Changes engagement status for an already-consented newsletter contact, or withdraws only its newsletter consent on v2 (account-wide on v1). Operator input cannot activate pending or withdrawn consent. No email is sent.

MCP tool update_contact_status Key audience:write + audience:read Can’t be undone Safe to repeat

Parameter Description
idrequiredpath · string The contact’s ID or email address
newsletterbody · string The newsletter’s ID or slug, needed for an email address that is a contact of several newsletters
statusrequiredbody · “active” “dormant”
consentbody · boolean Legacy assertion; it never grants or restores marketing consent

Request

curl -X PATCH "https://mail.apresly.com/api/v1/contacts/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status":"dormant"}'

Delete a contact

DELETE /api/v1/contacts/ {id}

Deletes one newsletter contact. On v2 its ID is a Subscription ID: only that newsletter is withdrawn and soft-deleted, while the Subscriber and other newsletters remain. On v1, the legacy deletion and account-wide recipient rules apply. Reimporting never restores consent.

MCP tool delete_contact Key audience:write + audience:read Can’t be undone Safe to repeat

Parameter Description
idrequiredpath · string The contact’s ID or email address
newsletterquery · string The newsletter’s ID or slug, needed for an email address that is a contact of several newsletters

Request

curl -X DELETE "https://mail.apresly.com/api/v1/contacts/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Import contacts

POST /api/v1/contacts/import

Adds up to 1000 contacts per call, with the same checks as the dashboard’s CSV import: invalid, misspelled (gmial.com…), spam trap, role (info@, support@…), throwaway, duplicate and suppressed addresses, undeliverable ones (ApresMail knows they can’t receive email: they hard bounced or hit a spam trap, from any sender on ApresMail), and addresses on domains that can’t receive email, are left out and counted. consent must be true: “These people agreed to receive my emails”. Existing contacts keep their status unless a row gives a stricter one (unsubscribed, bounced, complained), which is final. No welcome emails go out. For more rows, send the next chunk with the importId of the first.

MCP tool import_contacts Key audience:write + audience:read Can’t be undone Safe to repeat

Parameter Description
newsletterbody · string The newsletter’s ID or slug. Default: the account’s first newsletter, the one it has had longest.
consentrequiredbody · boolean Must be true: These people agreed to receive my emails. Bought or scraped lists aren’t allowed.
contactsrequiredbody · object[] The rows, 1000 at most
contacts[].emailrequiredbody · string Invalid addresses are left out and counted
contacts[].statusbody · “active” “dormant”
contacts[].subscribedAtbody · string When they signed up, ISO 8601
contacts[].emailsReceivedbody · number Emails they got on the previous platform
contacts[].openRatebody · number 0 to 1, from the previous platform: sends reach the most engaged first
contacts[].clickRatebody · number 0 to 1, from the previous platform
importIdbody · string The importId of the first chunk, to add rows to the same import
duplicatesbody · integer Duplicates you removed before sending, counted in the import’s report

Request

curl -X POST "https://mail.apresly.com/api/v1/contacts/import" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"consent":true,"contacts":[{"email":"[email protected]","subscribedAt":"2025-03-01T00:00:00Z"},{"email":"[email protected]","status":"unsubscribed"}]}'

Export contacts

GET /api/v1/contacts/export

Makes a CSV download link for the contacts matching the filters, valid for an hour, no API key needed to open it. The columns go back in through the import as they are.

MCP tool export_contacts Key audience:read Read-only Safe to repeat

Parameter Description
newsletterquery · string Only this newsletter’s: its ID or slug. Default: every newsletter.
statusquery · “active” “pending”
segmentquery · string Only the contacts a segment picks (its ID, from list_segments), whatever their status unless status is given. With newsletter, one of that newsletter’s segments.
searchquery · string Contacts whose email starts with this

Request

curl "https://mail.apresly.com/api/v1/contacts/export?status=active" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Subscribers

Canonical v2 profiles and newsletter-specific subscriptions, groups and consent events. Writes are scoped and idempotent; no action grants consent.

List subscribers

GET /api/v1/subscribers

Lists canonical profiles, fifty raw records per keyset page. Newsletter, consent and group filters never grant consent.

MCP tool list_subscribers Key audience:read Read-only Safe to repeat

Parameter Description
emailquery · string Exact email address to look up; cannot be combined with a cursor
newsletterIdquery · string An ID in this account
consentStatequery · “none” “active”
groupIdquery · string An ID in this account
cursorquery · string Opaque continuation cursor from the previous page; omit for the first page

Request

curl "https://mail.apresly.com/api/v1/subscribers" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Get a subscriber

GET /api/v1/subscribers/ {id}

Gets one live canonical profile in this account.

MCP tool get_subscriber Key audience:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string An ID in this account

Request

curl "https://mail.apresly.com/api/v1/subscribers/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

List subscriber subscriptions

GET /api/v1/subscribers/ {id} /subscriptions

Lists a subscriber’s newsletter-specific subscriptions, fifty raw records per page.

MCP tool list_subscriptions Key audience:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string An ID in this account
cursorquery · string Opaque continuation cursor from the previous page; omit for the first page

Request

curl "https://mail.apresly.com/api/v1/subscribers/6650f1c2e9b1d4a012345678/subscriptions" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

List subscription groups

GET /api/v1/subscriptions/ {id} /groups

Lists only groups attached to this subscription’s newsletter.

MCP tool list_subscription_groups Key audience:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string An ID in this account
cursorquery · string Opaque continuation cursor from the previous page; omit for the first page

Request

curl "https://mail.apresly.com/api/v1/subscriptions/6650f1c2e9b1d4a012345678/groups" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

GET /api/v1/subscriptions/ {id} /events

Lists newsletter-scoped consent evidence without private references or legacy account grants.

MCP tool list_subscription_events Key audience:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string An ID in this account
cursorquery · string Opaque continuation cursor from the previous page; omit for the first page

Request

curl "https://mail.apresly.com/api/v1/subscriptions/6650f1c2e9b1d4a012345678/events" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Update subscriber profile

PATCH /api/v1/subscribers/ {id}

Changes only the first name with profile version compare-and-set. Never grants consent.

MCP tool update_subscriber Key audience:write + audience:read Safe to repeat

Parameter Description
idrequiredpath · string An ID in this account
profileVersionrequiredbody · integer Current profile version for conflict detection
firstNamerequiredbody · string null
requestIdrequiredbody · string Stable UUID for this exact operation

Request

curl -X PATCH "https://mail.apresly.com/api/v1/subscribers/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"profileVersion":"…","firstName":"…","requestId":"…"}'

Withdraw subscription

POST /api/v1/subscriptions/ {id} /withdraw

Withdraws only this newsletter’s current consent epoch. Replays with the same requestId return the original result.

MCP tool withdraw_subscription Key audience:write + audience:read Can’t be undone Safe to repeat

Parameter Description
idrequiredpath · string An ID in this account
requestIdrequiredbody · string Stable UUID for this exact operation

Request

curl -X POST "https://mail.apresly.com/api/v1/subscriptions/6650f1c2e9b1d4a012345678/withdraw" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"requestId":"…"}'

Delete a subscription

DELETE /api/v1/subscriptions/ {id}

Soft-deletes one newsletter subscription, withdraws consent and removes its organizational memberships. The profile and other newsletters remain.

MCP tool delete_subscription Key audience:write + audience:read Can’t be undone Safe to repeat

Parameter Description
idrequiredpath · string An ID in this account
requestIdrequiredquery · string Stable UUID for this exact operation

Request

curl -X DELETE "https://mail.apresly.com/api/v1/subscriptions/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Erase subscriber

DELETE /api/v1/subscribers/ {id}

Starts account-wide privacy erasure for this profile and all its newsletter subscriptions. Retains tombstone IDs.

MCP tool erase_subscriber Key audience:write + audience:read Can’t be undone Safe to repeat

Parameter Description
idrequiredpath · string An ID in this account
requestIdrequiredquery · string Stable UUID for this exact operation

Request

curl -X DELETE "https://mail.apresly.com/api/v1/subscribers/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Recipients

Deprecated v1 account-wide consent reads. V2 accounts use Subscribers actions and receive conflict for these legacy tools.

List recipients through the deprecated endpoint

GET /api/v1/recipients

Deprecated legacy account-wide consent read. On a v2 account this always returns conflict; use list_subscribers and list_subscriptions. On v1, exact email search only; erased records are omitted.

MCP tool list_recipients Key audience:read Read-only Safe to repeat

Parameter Description
statequery · “none” “active”
emailquery · string Exact email match, preserving plus suffixes and dots; cannot be combined with cursor
cursorquery · string The previous page nextCursor with the same filters; never combine with email

Request

curl "https://mail.apresly.com/api/v1/recipients" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Get a recipient through the deprecated endpoint

GET /api/v1/recipients/ {id}

Deprecated legacy account-wide consent read. On a v2 account this always returns conflict; use get_subscriber and list_subscriptions. On v1, erased and foreign records return not_found.

MCP tool get_recipient Key audience:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string The canonical recipient ID in this account

Request

curl "https://mail.apresly.com/api/v1/recipients/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Segments

Saved conditions that pick some of a newsletter’s contacts by engagement, signup date, source or address, to send campaigns to them only.

List segments

GET /api/v1/segments

Lists segments, oldest first, with their conditions in words and how many active contacts each picks now.

MCP tool list_segments Key audience:read Read-only Safe to repeat

Parameter Description
newsletterquery · string Only this newsletter’s: its ID or slug. Default: every newsletter.

Request

curl "https://mail.apresly.com/api/v1/segments" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Get a segment

GET /api/v1/segments/ {id}

Gets one segment with its conditions and how many active contacts it picks now.

MCP tool get_segment Key audience:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string The segment’s ID

Request

curl "https://mail.apresly.com/api/v1/segments/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Count a segment’s contacts

POST /api/v1/segments/count

Counts the active contacts some conditions would pick, without saving anything: try them before create_segment.

MCP tool count_segment Key audience:read Read-only Safe to repeat

Parameter Description
newsletterbody · string The newsletter’s ID or slug. Default: the account’s first newsletter, the one it has had longest.
matchbody · “all” “any”
conditionsrequiredbody · object[] The conditions, 10 at most. Dates count back from each send, so “within 30 days” moves with time.
conditions[].fieldrequiredbody · “opened” “clicked”
conditions[].oprequiredbody · “within” “not_within”
conditions[].valuebody · number string

Request

curl -X POST "https://mail.apresly.com/api/v1/segments/count" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"conditions":[{"field":"opened","op":"within","value":30}]}'

Create a segment

POST /api/v1/segments

Saves conditions that pick some of a newsletter’s contacts, to send campaigns to them only (segment on update_campaign, send_campaign or schedule_campaign). Contacts join and leave it as they meet the conditions.

MCP tool create_segment Key audience:write + audience:read

Parameter Description
newsletterbody · string The newsletter’s ID or slug. Default: the account’s first newsletter, the one it has had longest.
namerequiredbody · string The segment’s name, 60 characters at most
matchbody · “all” “any”
conditionsrequiredbody · object[] The conditions, 10 at most. Dates count back from each send, so “within 30 days” moves with time.
conditions[].fieldrequiredbody · “opened” “clicked”
conditions[].oprequiredbody · “within” “not_within”
conditions[].valuebody · number string

Request

curl -X POST "https://mail.apresly.com/api/v1/segments" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Engaged","conditions":[{"field":"opened","op":"within","value":30}]}'

Update a segment

PATCH /api/v1/segments/ {id}

Renames a segment or changes its conditions. Send only what changes; conditions replace the old ones. Campaigns going to it, scheduled ones included, use the new conditions when they go out.

MCP tool update_segment Key audience:write + audience:read Safe to repeat

Parameter Description
idrequiredpath · string The segment’s ID
namebody · string The segment’s name, 60 characters at most
matchbody · “all” “any”
conditionsbody · object[] The conditions, 10 at most. Dates count back from each send, so “within 30 days” moves with time.
conditions[].fieldrequiredbody · “opened” “clicked”
conditions[].oprequiredbody · “within” “not_within”
conditions[].valuebody · number string

Request

curl -X PATCH "https://mail.apresly.com/api/v1/segments/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Engaged this quarter","conditions":[{"field":"opened","op":"within","value":90}]}'

Delete a segment

DELETE /api/v1/segments/ {id}

Deletes a segment. Its contacts stay as they are. A scheduled, sending or paused campaign going to it answers conflict: change who it goes to first. Drafts going to it can’t be sent until they get another segment or none.

MCP tool delete_segment Key audience:write + audience:read Can’t be undone Safe to repeat

Parameter Description
idrequiredpath · string The segment’s ID

Request

curl -X DELETE "https://mail.apresly.com/api/v1/segments/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Sequences

Import a Classic sequence draft

POST /api/v1/sequences/import-classic

Imports a reviewed MailerLite Classic migration bundle as a draft. Repeating the same source account, workflow and target returns the original draft; changed content conflicts. Does not publish, enroll participants or send.

MCP tool import_classic_sequence Key content:write Safe to repeat

Parameter Description
newsletterIdrequiredbody · string The existing target newsletter in this account; its sender settings apply.
bundlerequiredbody · object One explicitly authored Classic migration bundle, not a native automation export; at most 512 KiB.
bundle.formatrequiredbody · string
bundle.versionrequiredbody · number
bundle.sourceAccountrequiredbody · string
bundle.sourceSequenceIdrequiredbody · string
bundle.namerequiredbody · string
bundle.triggerrequiredbody · object
bundle.entryPolicybody · “once” “on_new_join”
bundle.schedulerequiredbody · object
bundle.entryStepIdrequiredbody · string
bundle.stepsrequiredbody · any[]
groupMappingsbody · object[] Exact source group references mapped to groups in the target newsletter; omitted groups stay unresolved.
groupMappings[].sourceGroupIdrequiredbody · string
groupMappings[].targetGroupIdrequiredbody · string
contentReviewedrequiredbody · boolean Confirm manual review of original unpersonalized content, retained external links/assets and timing; this does not grant consent or publish.

Request

curl -X POST "https://mail.apresly.com/api/v1/sequences/import-classic" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"newsletterId":"…","bundle":"…","contentReviewed":"…"}'

List sequences

GET /api/v1/sequences

Lists account-wide email sequences without enrolling or sending.

MCP tool list_sequences Key content:read Read-only Safe to repeat

Parameter Description
pagequery · integer One-based result page, fifty entries per page
statequery · “draft” “active”

Request

curl "https://mail.apresly.com/api/v1/sequences" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Get a sequence

GET /api/v1/sequences/ {id}

Reads the saved draft and published revision identity.

MCP tool get_sequence Key content:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string The resource ID in the authenticated account

Request

curl "https://mail.apresly.com/api/v1/sequences/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Create a sequence

POST /api/v1/sequences

Creates a draft only; reuse requestId after a lost response. Does not enroll or send.

MCP tool create_sequence Key content:write Safe to repeat

Parameter Description
requestIdrequiredbody · string A stable UUID for this exact operation; reuse it only to retry the same payload
namerequiredbody · string A short name for the sequence
newsletterIdrequiredbody · string The resource ID in the authenticated account

Request

curl -X POST "https://mail.apresly.com/api/v1/sequences" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"requestId":"…","name":"…","newsletterId":"…"}'

Save a sequence

PATCH /api/v1/sequences/ {id}

Saves the exact draft using its expected version and stable request identity; existing enrollments are unchanged.

MCP tool update_sequence Key content:write Safe to repeat

Parameter Description
idrequiredpath · string The resource ID in the authenticated account
requestIdrequiredbody · string A stable UUID for this exact operation; reuse it only to retry the same payload
expectedVersionrequiredbody · integer The expected version returned by the latest read of this resource
namerequiredbody · string A short name for the sequence
draftrequiredbody · object The complete saved trigger, graph and send schedule
draft.triggerrequiredbody · any
draft.entryPolicybody · “once” “on_new_join”
draft.entryNodeIdrequiredbody · string
draft.nodesrequiredbody · any[]
draft.schedulerequiredbody · object

Request

curl -X PATCH "https://mail.apresly.com/api/v1/sequences/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"requestId":"…","expectedVersion":"…","name":"…","draft":"…"}'

Preview a sequence

POST /api/v1/sequences/ {id} /preview

Validates and renders a saved draft. Simulates synthetic facts without creating recipients, jobs or sending.

MCP tool preview_sequence Key content:write Read-only Safe to repeat

Parameter Description
idrequiredpath · string The resource ID in the authenticated account
expectedVersionrequiredbody · integer The expected version returned by the latest read of this resource
simulationbody · object Synthetic clock, memberships and origin form for a read-only path simulation
simulation.atrequiredbody · string
simulation.memberGroupIdsrequiredbody · string[]
simulation.originFormIdrequiredbody · string null

Request

curl -X POST "https://mail.apresly.com/api/v1/sequences/6650f1c2e9b1d4a012345678/preview" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"expectedVersion":"…"}'

Publish a sequence

POST /api/v1/sequences/ {id} /publish

Approves the exact preview as an immutable revision for future trigger events. A paused sequence remains paused.

MCP tool publish_sequence Key content:write + messages:send Safe to repeat

Parameter Description
idrequiredpath · string The resource ID in the authenticated account
requestIdrequiredbody · string A stable UUID for this exact operation; reuse it only to retry the same payload
expectedVersionrequiredbody · integer The expected version returned by the latest read of this resource
previewDigestrequiredbody · string The digest from previewing this exact saved version

Request

curl -X POST "https://mail.apresly.com/api/v1/sequences/6650f1c2e9b1d4a012345678/publish" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"requestId":"…","expectedVersion":"…","previewDigest":"…"}'

Change sequence state

POST /api/v1/sequences/ {id} /lifecycle

Pauses, resumes, permanently stops or archives a sequence. Resume never replays historical trigger events.

MCP tool sequence_lifecycle Key content:write Safe to repeat

Parameter Description
idrequiredpath · string The resource ID in the authenticated account
requestIdrequiredbody · string A stable UUID for this exact operation; reuse it only to retry the same payload
expectedLifecycleVersionrequiredbody · integer The expected version returned by the latest read of this resource
actionrequiredbody · “pause” “resume”

Request

curl -X POST "https://mail.apresly.com/api/v1/sequences/6650f1c2e9b1d4a012345678/lifecycle" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"requestId":"…","expectedLifecycleVersion":"…","action":"…"}'

List sequence participants

GET /api/v1/sequences/ {id} /participants

Lists participant versions, status and next due times within this account.

MCP tool list_sequence_participants Key audience:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string The resource ID in the authenticated account
pagequery · integer One-based result page, fifty entries per page
statequery · “waiting” “active”

Request

curl "https://mail.apresly.com/api/v1/sequences/6650f1c2e9b1d4a012345678/participants" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Get sequence participant

GET /api/v1/sequences/ {id} /participants/ {enrollmentId}

Reads bounded execution history including chosen branches and safe stop reasons.

MCP tool get_sequence_participant Key audience:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string The resource ID in the authenticated account
enrollmentIdrequiredpath · string The resource ID in the authenticated account

Request

curl "https://mail.apresly.com/api/v1/sequences/6650f1c2e9b1d4a012345678/participants/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Change participant state

POST /api/v1/sequences/ {id} /participants/ {enrollmentId} /lifecycle

Pauses, resumes or stops one enrollment without reentry or replaying an unknown provider attempt.

MCP tool sequence_participant_lifecycle Key audience:write + audience:read Safe to repeat

Parameter Description
idrequiredpath · string The resource ID in the authenticated account
enrollmentIdrequiredpath · string The resource ID in the authenticated account
requestIdrequiredbody · string A stable UUID for this exact operation; reuse it only to retry the same payload
expectedCursorVersionrequiredbody · integer The expected version returned by the latest read of this resource
actionrequiredbody · “pause” “resume”

Request

curl -X POST "https://mail.apresly.com/api/v1/sequences/6650f1c2e9b1d4a012345678/participants/6650f1c2e9b1d4a012345678/lifecycle" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"requestId":"…","expectedCursorVersion":"…","action":"…"}'

Groups

On v2 every group belongs to one newsletter: list/create require newsletterId, and membership uses an existing Subscriber in that newsletter. Membership never grants consent. V1 account-wide groups remain available during maintenance.

List groups

GET /api/v1/groups

Lists organizational groups and member counts. On v2 newsletterId is required and only groups of that newsletter are returned. Membership does not grant permission to send email.

MCP tool list_groups Key content:read Read-only Safe to repeat

Parameter Description
newsletterIdquery · string The owning newsletter ID; required for v2 group listing and creation
archivedquery · boolean List archived groups instead of active groups
queryquery · string Case-insensitive literal text in the group name
pagequery · integer Page number, starting at 1; 50 results per page

Request

curl "https://mail.apresly.com/api/v1/groups" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Get a group

GET /api/v1/groups/ {id}

Reads one organizational group, including an archived group. On v2 the DTO includes its immutable newsletterId.

MCP tool get_group Key content:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string The group’s ID

Request

curl "https://mail.apresly.com/api/v1/groups/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Create a group

POST /api/v1/groups

Creates an empty organizational group. On v2 newsletterId is required and cannot later change. Does not create contacts, consent or email.

MCP tool create_group Key audience:write

Parameter Description
namerequiredbody · string The group name, 1 to 100 characters
newsletterIdbody · string The owning newsletter ID; required for v2 group listing and creation

Request

curl -X POST "https://mail.apresly.com/api/v1/groups" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"…"}'

Rename a group

PATCH /api/v1/groups/ {id}

Renames an active group without changing its v2 newsletter parent, membership or consent.

MCP tool update_group Key audience:write Safe to repeat

Parameter Description
idrequiredpath · string The group’s ID
namerequiredbody · string The group name, 1 to 100 characters

Request

curl -X PATCH "https://mail.apresly.com/api/v1/groups/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"…"}'

Archive a group

DELETE /api/v1/groups/ {id}

Archives a group and retains its newsletter-specific members. Does not unsubscribe contacts or change campaigns.

MCP tool archive_group Key audience:write Safe to repeat

Parameter Description
idrequiredpath · string The group’s ID

Request

curl -X DELETE "https://mail.apresly.com/api/v1/groups/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

List group members

GET /api/v1/groups/ {id} /members

Lists group members, including unsubscribed contacts. On v2 each row has subscriberId instead of email and is scoped to the group’s newsletter. This is not an eligible sending audience.

MCP tool list_group_members Key audience:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string The group’s ID
pagequery · integer Page number, starting at 1; 50 results per page

Request

curl "https://mail.apresly.com/api/v1/groups/6650f1c2e9b1d4a012345678/members" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Add a group member

POST /api/v1/groups/ {id} /members

Adds an existing profile to a group once, without changing consent or sending email. On v2 pass subscriberId (or a legacy email alias); the group determines its newsletter.

MCP tool add_group_member Key audience:write + audience:read + messages:send Safe to repeat

Parameter Description
idrequiredpath · string The group’s ID
emailbody · string An existing contact email in this account; membership never grants consent
subscriberIdbody · string The v2 canonical subscriber ID; membership never grants consent

Request

curl -X POST "https://mail.apresly.com/api/v1/groups/6650f1c2e9b1d4a012345678/members" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Remove a group member

POST /api/v1/groups/ {id} /members/remove

Removes a profile from this newsletter’s group without unsubscribing it. On v2 pass subscriberId or a legacy email alias.

MCP tool remove_group_member Key audience:write + audience:read Safe to repeat

Parameter Description
idrequiredpath · string The group’s ID
emailbody · string An existing contact email in this account; membership never grants consent
subscriberIdbody · string The v2 canonical subscriber ID; membership never grants consent

Request

curl -X POST "https://mail.apresly.com/api/v1/groups/6650f1c2e9b1d4a012345678/members/remove" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Signup forms

List signup forms

GET /api/v1/forms

Lists private form drafts and immutable publication summaries, without subscriber data.

MCP tool list_forms Key content:read Read-only Safe to repeat

Parameter Description
statusquery · “draft” “published”
newsletterIdquery · string Limit forms to their owning newsletter
pagequery · integer Page number, starting at 1; 50 results per page

Request

curl "https://mail.apresly.com/api/v1/forms" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Get a signup form

GET /api/v1/forms/ {id}

Reads a private draft, its current published revision and publication readiness.

MCP tool get_form Key content:read Read-only Safe to repeat

Parameter Description
idrequiredpath · string The signup form’s ID

Request

curl "https://mail.apresly.com/api/v1/forms/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Create a signup form

POST /api/v1/forms

Creates an inert private draft. Does not subscribe anyone or send email.

MCP tool create_form Key content:write

Parameter Description
namerequiredbody · string Private form name, 1 to 100 characters
draftbody · object Optional initial publication fields; incomplete drafts are allowed
draft.titlebody · string Public form title; required before publication
draft.consentTextbody · string Exact plain-text consent wording approved by the operator
draft.privacyUrlbody · string Real privacy policy URL; no fragments or credentials
draft.groupIdbody · string A group belonging to this account and, on v2 accounts, the selected newsletter
draft.newsletterIdbody · string The newsletter joined after double opt-in
draft.appearancebody · object Published page appearance and copy; full replacement normalized with defaults, readable colors required
draft.fieldMappingbody · object Native HTML field names for email, consent and honeypot only; JSON retains canonical names
draft.allowedOriginsbody · string[] Exact website origins permitted to embed and submit this form; maximum 20

Request

curl -X POST "https://mail.apresly.com/api/v1/forms" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"…"}'

Edit a signup form

PATCH /api/v1/forms/ {id}

Updates private draft fields using editVersion. An existing public revision remains unchanged.

MCP tool update_form Key content:write

Parameter Description
idrequiredpath · string The signup form’s ID
expectedVersionrequiredbody · integer The editVersion returned by the last read; prevents overwriting concurrent edits
namebody · string Private form name, 1 to 100 characters
draftbody · object Merge these fields into the existing private draft
draft.titlebody · string Public form title; required before publication
draft.consentTextbody · string Exact plain-text consent wording approved by the operator
draft.privacyUrlbody · string Real privacy policy URL; no fragments or credentials
draft.groupIdbody · string A group belonging to this account and, on v2 accounts, the selected newsletter
draft.newsletterIdbody · string The newsletter joined after double opt-in
draft.appearancebody · object Published page appearance and copy; full replacement normalized with defaults, readable colors required
draft.fieldMappingbody · object Native HTML field names for email, consent and honeypot only; JSON retains canonical names
draft.allowedOriginsbody · string[] Exact website origins permitted to embed and submit this form; maximum 20

Request

curl -X PATCH "https://mail.apresly.com/api/v1/forms/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"expectedVersion":"…"}'

Publish a signup form

POST /api/v1/forms/ {id} /publish

Publishes an immutable revision only after audience, delivery, sender and source readiness checks pass. Does not send email.

MCP tool publish_form Key settings:manage + messages:send Safe to repeat

Parameter Description
idrequiredpath · string The signup form’s ID
expectedVersionrequiredbody · integer The editVersion returned by the last read; prevents overwriting concurrent edits

Request

curl -X POST "https://mail.apresly.com/api/v1/forms/6650f1c2e9b1d4a012345678/publish" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"expectedVersion":"…"}'

Archive a signup form

DELETE /api/v1/forms/ {id}

Stops new signup requests and pending confirmations for this form. Existing consent and memberships remain unchanged.

MCP tool archive_form Key settings:manage Safe to repeat

Parameter Description
idrequiredpath · string The signup form’s ID

Request

curl -X DELETE "https://mail.apresly.com/api/v1/forms/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Domains

Own sending domains with their DNS records, and the shared address.

List domains

GET /api/v1/domains

Lists the account’s own sending domains with their DNS records and status as last checked, and each newsletter’s shared address (hello@.), which works with no setup.

MCP tool list_domains Key content:read Read-only Safe to repeat

Request

curl "https://mail.apresly.com/api/v1/domains" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Add a domain

POST /api/v1/domains

Adds a domain to send from, in the account’s own tenant at the email provider: emails are signed with DKIM and bounces return to a subdomain of it (rp. on PostShiba, bounce. on Amazon SES). The answer lists the DNS records to add; check_domain reads them once they’re in. Newsletters can send from it once it’s verified.

MCP tool add_domain Key settings:manage + messages:send Reaches outside ApresMail

Parameter Description
domainrequiredbody · string e.g. example.com. An address or a link works too: [email protected] and https://www.example.com/about both add example.com.
archiveHostbody · string Used when the domain’s setup lists an archive step: the subdomain for the archive, tracked links and unsubscribe links. Default: news..

Request

curl -X POST "https://mail.apresly.com/api/v1/domains" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain":"example.com"}'

Retry a domain’s sender setup and check its DNS records

POST /api/v1/domains/ {id} /check

Retries incomplete sender setup, then asks the email provider and DNS again whether the domain’s records are in, and looks up its DMARC record or its parent domain’s. On PostShiba, a check within a minute of the last one answers what that one found. When its setup lists an archive step, the newsletter sending from the domain moves its archive and links to that subdomain once it points at ApresMail.

MCP tool check_domain Key settings:manage + messages:send Safe to repeat Reaches outside ApresMail

Parameter Description
idrequiredpath · string The domain’s ID

Request

curl -X POST "https://mail.apresly.com/api/v1/domains/6650f1c2e9b1d4a012345678/check" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Remove a domain

DELETE /api/v1/domains/ {id}

Removes a domain from the email provider, and its archive subdomain from ApresMail when its setup lists one. Newsletters on it can’t send until they move to another address. Refused while a campaign from it is sending, paused or scheduled. Adding it again needs new DNS records.

MCP tool remove_domain Key settings:manage + messages:send Can’t be undone Safe to repeat Reaches outside ApresMail

Parameter Description
idrequiredpath · string The domain’s ID

Request

curl -X DELETE "https://mail.apresly.com/api/v1/domains/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Images

Pictures for campaign content, on ApresMail’s CDN, kept in the account’s library to use again.

List images

GET /api/v1/images

Lists the images uploaded to the account, newest first, 50 a page, so a campaign can use one again without uploading it twice. Pass nextCursor back as cursor for the next page.

MCP tool list_images Key content:read Read-only Safe to repeat

Parameter Description
limitquery · integer Images per page, 50 by default, 100 at most
cursorquery · string nextCursor from the previous page

Request

curl "https://mail.apresly.com/api/v1/images?limit=20" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Upload an image

POST /api/v1/images

Stores a PNG, JPEG, GIF or WebP image under 4 MB on ApresMail’s CDN and returns its URL for campaign content. Send the file as base64 (under about 3 MB, since requests stop at 4.5 MB) or an https:// link ApresMail downloads. The URL never changes: sent emails keep pointing at it. list_images finds images uploaded before.

MCP tool upload_image Key content:write Reaches outside ApresMail

Parameter Description
base64body · string The image file, base64 encoded; a data: URL works too
urlbody · string An https:// link to the image
fileNamebody · string Used in the stored file’s name
contentTypebody · string The file’s type, checked against its first bytes

Request

curl -X POST "https://mail.apresly.com/api/v1/images" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/cover.png"}'

API keys

Keys for the REST API and MCP.

List API keys

GET /api/v1/api-keys

Lists the account’s API keys, revoked ones included, with their level and when they were last used. Keys themselves are never shown again.

MCP tool list_api_keys Key Dashboard or legacy full credentials only Read-only Safe to repeat

Request

curl "https://mail.apresly.com/api/v1/api-keys" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Create an API key

POST /api/v1/api-keys

Creates an API key and returns it once; only its hash is stored. Scoped keys have selected permissions and expire after 7, 30 or 90 days. Only dashboard sessions or legacy full credentials can manage keys. Legacy full/signups modes remain for compatibility. An account has up to 20 active keys: one more answers conflict until one is revoked.

MCP tool create_api_key Key Dashboard or legacy full credentials only

Parameter Description
namerequiredbody · string What the key is for, e.g. Website signups
levelbody · “full” “signups”
scopesbody · “content:read” “content:write”
expiresInDaysbody · number Scoped key lifetime: 7, 30 or 90 days; default 30

Request

curl -X POST "https://mail.apresly.com/api/v1/api-keys" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Draft assistant","level":"scoped","scopes":["content:read","content:write"],"expiresInDays":30}'

Revoke an API key

DELETE /api/v1/api-keys/ {id}

Revokes an API key for good: requests with it answer unauthorized from now on. A key can revoke itself.

MCP tool revoke_api_key Key Dashboard or legacy full credentials only Can’t be undone Safe to repeat

Parameter Description
idrequiredpath · string The API key’s ID

Request

curl -X DELETE "https://mail.apresly.com/api/v1/api-keys/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

List connected apps

GET /api/v1/connected-apps

Lists the apps connected to the account with OAuth, such as ChatGPT, Claude and Grok Bot, with when they were connected and last used. Each app has its selected permissions; older connections may retain legacy full access.

MCP tool list_connected_apps Key Dashboard or legacy full credentials only Read-only Safe to repeat

Request

curl "https://mail.apresly.com/api/v1/connected-apps" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"

Disconnect an app

DELETE /api/v1/connected-apps/ {id}

Disconnects an app connected with OAuth: its tokens stop working at once, and it has to ask for access again to come back. An app can disconnect itself.

MCP tool revoke_connected_app Key Dashboard or legacy full credentials only Can’t be undone Safe to repeat

Parameter Description
idrequiredpath · string The connected app’s ID

Request

curl -X DELETE "https://mail.apresly.com/api/v1/connected-apps/6650f1c2e9b1d4a012345678" \
  -H "Authorization: Bearer $APRESMAIL_API_KEY"
In this categoryAuthentication

NEED A HAND?

Let’s get you moving again.

Tell us what you’re setting up and which step you’re stuck on. We’ll help you find a solution.

Contact support