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/
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@
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@ |
| 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@ |
| imageUrlbody · string | Square logo, 128×128 or larger: an https:// link |
| fromNamebody · string | Name in the From field |
| fromEmailbody · string | The shared address (hello@ |
| 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"
Update SMS consent wording
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"
Withdraw subscriber SMS consent
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"
List subscription consent events
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@
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.
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"