Skip to content
Bring your own SMTP or SES — pay AWS rates, not SaaS rates

API v1

REST API
for MailerSpark.

Bearer-token auth, idempotent endpoints for contacts and lists, full campaign creation with sequence steps. Everything your team does in the dashboard, you can do over the API.

Base URL

All API v1 endpoints live under https://app.mailerspark.com/api/v1. The base URL is the same in development and production.

Authentication

Authenticate every request with a Bearer token. Generate API keys in Settings → API Keys. The full secret is only ever shown once — store it somewhere safe immediately.

Authorization: Bearer ms_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
# or
X-Api-Key: ms_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

Rate limits

Rate limits are enforced per API key, backed by Redis. The default limit is 100 requests per minute. Check the response headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 97
X-RateLimit-Reset: 1700000000

Endpoints

GET/api/v1/contacts

List contacts in your organization. Supports filtering by segment, list, status, and search query.

Parameters
segmentFilter to a segment ID (seg_*)
listFilter to a list/group ID (lst_*)
statusactive | unsubscribed | bounced | complained
searchSearch across email, firstName, lastName, company
limit1–100, default 50
cursorPagination cursor from previous response
POST/api/v1/contacts

Create a contact. Idempotent on (organizationId, email) — repeat calls return the existing record.

Parameters
emailRequired · valid email address
firstNameOptional
lastNameOptional
companyOptional
customFieldsObject of { fieldName: value }
listsArray of list IDs to add the contact to
GET/api/v1/lists

List contact groups/lists in your organization.

Parameters
limit1–100, default 50
cursorPagination cursor
POST/api/v1/lists

Create a contact list/group. Optional double opt-in.

Parameters
nameRequired
doubleOptInBoolean · default false
descriptionOptional
GET/api/v1/campaigns

List campaigns. Filter by type (newsletter or cold), status, and date range.

Parameters
typenewsletter | cold
statusdraft | scheduled | sending | sent | failed
limit1–100, default 50
POST/api/v1/campaigns

Create a campaign. For type=cold, include the steps array with wait days and content.

Parameters
typeRequired · newsletter | cold
nameRequired · human-readable name
listIdRequired · recipient list ID
subjectRequired for newsletter
htmlContentRequired for newsletter · raw HTML or builder document
stepsRequired for cold · array of { waitDays, subject, htmlContent }
scheduleAtOptional · ISO 8601 timestamp

Public endpoints (no auth)

These endpoints are designed for public subscribe forms. They are rate-limited per IP and require no authentication.

POST/api/subscribeNone

Add a contact to a list, optionally with double opt-in.

Parameters
emailRequired
listIdRequired
customFieldsOptional object
doubleOptInOptional · default uses the list's setting
POST/api/subscribe/confirmNone

Confirm a double opt-in token. Returns { status: 'subscribed' } on success.

Parameters
tokenRequired · from the confirmation email
GET/api/t/o/{token}None

Tracking pixel for opens. Returns a 1x1 transparent GIF.

GET/api/t/c/{token}?u=&s=None

Click redirect. Logs the click and 302-redirects to the original URL.

Parameters
uOriginal URL
sSender ID

Errors

The API returns standard HTTP status codes. The response body always includes a code and message:

{
  "code": "rate_limited",
  "message": "Rate limit exceeded. Try again in 47 seconds.",
  "retryAfter": 47
}

Common error codes

StatusCodeMeaning
400invalid_requestMissing or malformed parameter
401unauthorizedMissing or invalid API key
403forbiddenCross-organization access attempt
404not_foundResource does not exist
409duplicateContact with this email already exists
422validation_failedField-level validation failed
429rate_limitedPer-minute rate limit exceeded

Try it on the free plan

API access from day one.

Free plan includes API access. Generate a key, make a request, see it in the dashboard.

Encrypted in transitGDPR readyNo credit card