REST API

API Reference

Send transactional and campaign emails, manage mailboxes, configure sender groups, and query domain health, warmup status, bounce stats, and campaign analytics -- all from your application.

Your key is never sent to our servers from this page. Requests go directly to the API. Get your API key →

Overview

The Mailmark API is a simple HTTP REST API. All endpoints are hosted at:

https://api.mailmark.dev

Format

JSON request and response bodies.

Auth

Bearer token via the Authorization header.

Errors

Standard HTTP status codes with an error field in the body.

SDK

Use the mailmark npm package for a typed client.

Error responses

All errors return a JSON body with an error field:

HTTP 401
{
  "error": "Invalid or revoked API key"
}

Authentication

All API requests require an API key passed as a Bearer token in the Authorization header.

Authorization: Bearer dm_live_your_api_key_here
1

Go to the Developer section in your dashboard.

2

Click Create API Key, give it a name, and choose a scope: select a specific domain (domain-scoped) or "All domains" (org-wide).

3

Copy the key immediately. It is shown only once and stored as a hash.

4

Domain-scoped keys can access all endpoints but only for that domain. Org-wide keys can query analytics endpoints (health, warmup, bounces, suppressions, campaign stats) across all your domains, but return 403 on write endpoints.

Quick start

curl -X GET https://api.mailmark.dev/v1/mailboxes \
  -H "Authorization: Bearer dm_live_your_key"
GET/v1/mailboxes

List Mailboxes

Returns all mailboxes that belong to the domain scoped to your API key. Each mailbox includes its local address, full address, and optional display name.

Returns: Array of Mailbox objects.
curl -X GET https://api.mailmark.dev/v1/mailboxes \
  -H "Authorization: Bearer dm_live_..."

Try it

POST/v1/mailboxes

Create Mailbox

Creates a new mailbox on the domain associated with your API key. Only the local part of the address is needed (e.g. 'hello'). The domain suffix is appended automatically.

  • Returns 409 if the mailbox already exists.

Parameters

NameTypeDescription
addresstext*The local part of the email address, e.g. hello (not hello@domain.com).
displayNametextOptional sender display name, e.g. 'Support Team'.

* required

Returns: The created Mailbox object.
curl -X POST https://api.mailmark.dev/v1/mailboxes \
  -H "Authorization: Bearer dm_live_..." \
  -H "Content-Type: application/json" \
  -d '{"address":"hello","displayName":"Hello Team"}'

Try it

The local part of the email address, e.g. hello (not hello@domain.com).

Optional sender display name, e.g. 'Support Team'.

DELETE/v1/mailboxes/:address

Delete Mailbox

Permanently deletes a mailbox and all its emails. Also removes it from any sender groups it belongs to. Pass the local part ('hello') or the full address ('hello@domain.com').

  • This action is irreversible. All emails in the mailbox are permanently deleted.

Parameters

NameTypeDescription
addresspathtext*Local part or full address of the mailbox to delete.

* required

Returns: { deleted: true }
curl -X DELETE https://api.mailmark.dev/v1/mailboxes/hello \
  -H "Authorization: Bearer dm_live_..."

Try it

Local part or full address of the mailbox to delete.

GET/v1/sender-groups

List Sender Groups

Returns all sender groups for the API key's domain. A sender group defines which mailboxes act as senders and which recipient emails are targeted.

Returns: Array of SenderGroup objects.
curl -X GET https://api.mailmark.dev/v1/sender-groups \
  -H "Authorization: Bearer dm_live_..."

Try it

POST/v1/sender-groups

Create Sender Group

Creates a sender group. Specify which sender mailboxes to include and an optional list of recipient emails. Pass 'all' for mailboxes to include every mailbox on the domain.

Parameters

NameTypeDescription
nametext*A descriptive name for the group.
mailboxestextComma-separated mailbox addresses to include as senders, or "all" to include every mailbox on the domain. Defaults to "all".
emailscsvComma or newline separated list of recipient email addresses.

* required

Returns: The created SenderGroup object.
curl -X POST https://api.mailmark.dev/v1/sender-groups \
  -H "Authorization: Bearer dm_live_..." \
  -H "Content-Type: application/json" \
  -d '{"name":"My Group","mailboxes":"all","emails":[]}'

Try it

A descriptive name for the group.

Comma-separated mailbox addresses to include as senders, or "all" to include every mailbox on the domain. Defaults to "all".

Comma or newline separated list of recipient email addresses.

PATCH/v1/sender-groups/:id

Update Sender Group

Updates a sender group. All fields are optional. Only the fields you provide will be changed. Use addEmails / removeEmails for incremental recipient list changes, or emails to replace the entire list at once.

Parameters

NameTypeDescription
idpathtext*The ID of the sender group to update (from listSenderGroups).
nametextNew name for the group.
addEmailscsvEmails to add to the recipient list.
removeEmailscsvEmails to remove from the recipient list.
emailscsvReplace the entire recipient list with this set. Overrides addEmails/removeEmails.
mailboxestextReplace the sender mailbox list. Comma-separated addresses or "all".

* required

Returns: The updated SenderGroup object.
curl -X PATCH https://api.mailmark.dev/v1/sender-groups/GROUP_ID \
  -H "Authorization: Bearer dm_live_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Try it

The ID of the sender group to update (from listSenderGroups).

New name for the group.

Emails to add to the recipient list.

Emails to remove from the recipient list.

Replace the entire recipient list with this set. Overrides addEmails/removeEmails.

Replace the sender mailbox list. Comma-separated addresses or "all".

DELETE/v1/sender-groups/:id

Delete Sender Group

Permanently deletes a sender group. The mailboxes themselves are not affected.

Parameters

NameTypeDescription
idpathtext*The ID of the sender group to delete.

* required

Returns: { deleted: true }
curl -X DELETE https://api.mailmark.dev/v1/sender-groups/GROUP_ID \
  -H "Authorization: Bearer dm_live_..."

Try it

The ID of the sender group to delete.

POST/v1/send

Send Email

Sends an email from a mailbox on the API key's domain. Supports transactional sends (one email to all recipients), campaign sends (individual email per recipient with a shared batchId), and scheduled sends (delivered at a future time).

  • The from address must be an existing mailbox created under this API key's domain.
  • For campaign sends, each recipient receives a separate individually tracked email.
  • scheduledAt must be a future unix millisecond timestamp.

Parameters

NameTypeDescription
fromtext*Full address of the sender mailbox. Must be an existing mailbox on your domain.
tocsv*One or more recipient email addresses (comma or newline separated).
subjecttext*Email subject line.
htmltextareaHTML content of the email. Either html or text is required.
texttextareaPlain text fallback. Used if html is not provided.
typeselect"transactional" sends one email to all recipients together. "campaign" sends individual emails to each recipient, all tracked under a shared batchId.
scheduledAtdatetimeSchedule the email for a future time. Leave blank to send immediately.

* required

Returns: For transactional: { messageId, status }. For campaign: { messageIds, batchId, status }. status is 'queued' or 'scheduled'.
curl -X POST https://api.mailmark.dev/v1/send \
  -H "Authorization: Bearer dm_live_..." \
  -H "Content-Type: application/json" \
  -d '{
  "from": "hello@yourdomain.com",
  "to": [
    "user@example.com"
  ],
  "subject": "Hello!"
}'

Try it

Full address of the sender mailbox. Must be an existing mailbox on your domain.

One or more recipient email addresses (comma or newline separated).

Email subject line.

HTML content of the email. Either html or text is required.

Plain text fallback. Used if html is not provided.

"transactional" sends one email to all recipients together. "campaign" sends individual emails to each recipient, all tracked under a shared batchId.

Schedule the email for a future time. Leave blank to send immediately.

GET/v1/sequences

List Sequences

Returns all sequences created by the authenticated user. Each sequence includes its status, step count, and enrollment statistics (total, active, completed, replied, bounced, cancelled).

Returns: Array of Sequence objects with stats.
curl -X GET https://api.mailmark.dev/v1/sequences \
  -H "Authorization: Bearer dm_live_..."

Try it

POST/v1/sequences

Create Sequence

Creates a new automated email sequence for campaign-style sends (one email per recipient). A sequence is a series of steps: send_email steps deliver an email, delay steps wait a specified duration before proceeding. The first step must be send_email. Supports merge field placeholders like {{firstName}} in subject and html.

  • First step must be send_email (a sequence cannot start with a delay).
  • delayMs is in milliseconds (86400000 = 1 day).
  • Use {{fieldName}} placeholders in subject/html for merge field personalization.

Parameters

NameTypeDescription
nametext*A descriptive name for this sequence.
fromtext*Full address of the sender mailbox. Must be an existing mailbox on your domain.
stepstextarea*JSON array of steps. Each step is { "type": "send_email", "subject": "...", "html": "..." } or { "type": "delay", "delayMs": 86400000 }.

* required

Returns: Sequence object with id, name, status, steps, and createdAt.
curl -X POST https://api.mailmark.dev/v1/sequences \
  -H "Authorization: Bearer dm_live_..." \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Welcome Series",
  "from": "hello@yourdomain.com",
  "steps": [
    {
      "type": "send_email",
      "subject": "Welcome {{firstName}}",
      "html": "<p>Hello!</p>"
    },
    {
      "type": "delay",
      "delayMs": 86400000
    },
    {
      "type": "send_email",
      "subject": "Follow up",
      "html": "<p>Checking in</p>"
    }
  ]
}'

Try it

A descriptive name for this sequence.

Full address of the sender mailbox. Must be an existing mailbox on your domain.

JSON array of steps. Each step is { "type": "send_email", "subject": "...", "html": "..." } or { "type": "delay", "delayMs": 86400000 }.

POST/v1/sequences/:sequenceId/enroll

Enroll Contacts

Enroll one or more contacts into a sequence. Each contact will start receiving sequence emails from step 1. Contacts already actively enrolled are skipped. Maximum 100 contacts per request.

  • Sequence must be in 'active' status.
  • Contacts already enrolled with 'active' status are skipped (not duplicated).
  • mergeFields are used to personalize {{placeholder}} tags in email steps.

Parameters

NameTypeDescription
sequenceIdpathtext*The ID of the sequence to enroll contacts into.
contactstextarea*JSON array of contacts. Each: { "email": "...", "mergeFields": { "firstName": "..." } }.

* required

Returns: { "enrolled": 2, "skipped": 0, "enrollmentIds": [...] }
curl -X POST https://api.mailmark.dev/v1/sequences/:sequenceId/enroll \
  -H "Authorization: Bearer dm_live_..." \
  -H "Content-Type: application/json" \
  -d '{
  "contacts": [
    {
      "email": "jane@example.com",
      "mergeFields": {
        "firstName": "Jane"
      }
    }
  ]
}'

Try it

The ID of the sequence to enroll contacts into.

JSON array of contacts. Each: { "email": "...", "mergeFields": { "firstName": "..." } }.

PATCH/v1/sequences/:sequenceId

Pause / Resume Sequence

Pause or resume a sequence. Pausing prevents new step executions (scheduled steps will check sequence status before sending). Resume re-enables processing.

Parameters

NameTypeDescription
sequenceIdpathtext*The ID of the sequence to update.
statusselect*Set to 'paused' to pause or 'active' to resume.

* required

Returns: Updated sequence object.
curl -X PATCH https://api.mailmark.dev/v1/sequences/:sequenceId \
  -H "Authorization: Bearer dm_live_..." \
  -H "Content-Type: application/json" \
  -d '{"status": "paused"}'

Try it

The ID of the sequence to update.

Set to 'paused' to pause or 'active' to resume.

DELETE/v1/sequences/:sequenceId

Cancel Sequence

Cancel a sequence permanently. Sets sequence status to 'completed' and cancels all active enrollments. Scheduled follow-up emails will not be sent.

Parameters

NameTypeDescription
sequenceIdpathtext*The ID of the sequence to cancel.

* required

Returns: { "id": "...", "status": "completed", "cancelledEnrollments": 42 }
curl -X DELETE https://api.mailmark.dev/v1/sequences/:sequenceId \
  -H "Authorization: Bearer dm_live_..."

Try it

The ID of the sequence to cancel.

GET/v1/domain-health

Domain Health

Returns the latest health check for the API key's domain (domain-scoped key) or all domains (org-wide key). Includes SPF, DKIM, DMARC, MX, blacklist status, and an overall score.

  • Works with both domain-scoped and org-wide API keys.

Parameters

NameTypeDescription
domaintextFilter to a specific domain (useful for org-wide keys).

* required

Returns: Domain health object (domain-scoped key) or array of domain health objects (org-wide key).
curl -X GET https://api.mailmark.dev/v1/domain-health \
  -H "Authorization: Bearer dm_live_..."

Try it

Filter to a specific domain (useful for org-wide keys).

GET/v1/warmup

Warmup Status

Returns warmup status for all enrolled mailboxes on the API key's domain. Includes health score, inbox rate, daily limits, and activity counts.

  • Works with both domain-scoped and org-wide API keys.

Parameters

NameTypeDescription
mailboxtextFilter to a specific mailbox address.

* required

Returns: Array of warmup mailbox status objects.
curl -X GET https://api.mailmark.dev/v1/warmup \
  -H "Authorization: Bearer dm_live_..."

Try it

Filter to a specific mailbox address.

GET/v1/bounces

Bounce Stats

Returns bounce and delivery statistics for the domain over a configurable lookback window. Includes total sent, delivered, bounced, failed, opened, clicked, and replied counts.

  • Works with both domain-scoped and org-wide API keys.

Parameters

NameTypeDescription
daystextLookback period in days (default 30, max 90).
domaintextFilter to a specific domain (for org-wide keys).

* required

Returns: Bounce statistics object with counts and bounce rate.
curl -X GET https://api.mailmark.dev/v1/bounces \
  -H "Authorization: Bearer dm_live_..."

Try it

Lookback period in days (default 30, max 90).

Filter to a specific domain (for org-wide keys).

GET/v1/suppressions

Suppression List

Returns the suppression (unsubscribe) list for the domain. Supports pagination via the 'after' cursor parameter.

  • Works with both domain-scoped and org-wide API keys.

Parameters

NameTypeDescription
limittextNumber of results to return (default 100, max 500).
aftertextPagination cursor -- unsubscribedAt timestamp from the last item in the previous page.
domaintextFilter to a specific domain (for org-wide keys).

* required

Returns: Suppression list with total count, items, and hasMore flag.
curl -X GET https://api.mailmark.dev/v1/suppressions \
  -H "Authorization: Bearer dm_live_..."

Try it

Number of results to return (default 100, max 500).

Pagination cursor -- unsubscribedAt timestamp from the last item in the previous page.

Filter to a specific domain (for org-wide keys).

GET/v1/campaign-stats

Campaign Stats

Returns aggregate stats for sequences and/or batch sends. Includes open, click, reply, and bounce rates for each campaign.

  • Works with both domain-scoped and org-wide API keys.

Parameters

NameTypeDescription
typeselectFilter by campaign type: "sequence", "batch", or "all" (default).
sequenceIdtextFilter to a specific sequence.
batchIdtextFilter to a specific batch.
domaintextFilter to a specific domain (for org-wide keys).

* required

Returns: Object with sequences and/or batches arrays, each containing stats.
curl -X GET https://api.mailmark.dev/v1/campaign-stats \
  -H "Authorization: Bearer dm_live_..."

Try it

Filter by campaign type: "sequence", "batch", or "all" (default).

Filter to a specific sequence.

Filter to a specific batch.

Filter to a specific domain (for org-wide keys).

Node.js SDK

Install the official typed SDK to avoid writing raw fetch calls:

npm install mailmark-sdk\n# or\nbun add mailmark-sdk
import { Mailmark } from 'mailmark-sdk';

const client = new Mailmark('dm_live_your_key');

// List mailboxes
const mailboxes = await client.listMailboxes();

// Send an email
const result = await client.send({
  from: 'hello@yourdomain.com',
  to: ['user@example.com'],
  subject: 'Hello!',
  html: '<p>Sent via Mailmark.</p>',
});

// Campaign send
const campaign = await client.send({
  from: 'hello@yourdomain.com',
  to: ['a@example.com', 'b@example.com'],
  subject: 'Big announcement',
  html: '<h1>Hello!</h1>',
  type: 'campaign',
});

// Scheduled send
const scheduled = await client.send({
  from: 'hello@yourdomain.com',
  to: ['user@example.com'],
  subject: 'Reminder',
  html: '<p>This is scheduled.</p>',
  scheduledAt: Date.now() + 60 * 60 * 1000, // 1 hour from now
});