API documentation

The SendNext REST API lets your website, store or tools add contacts, manage lists and send campaigns. Every request and response is JSON.

Authentication

Create a key in the app under API keys, then send it with every request. Keys belong to one workspace and only see its data. A key is shown once, so store it safely and revoke it if it leaks.

Authorization: Bearer sn_live_...

Each key has permissions. Read only can read everything. Contacts can also add, change and remove contacts and list members. Campaigns can also send. Full access can do all of it.

Add a subscriber

Creates the contact, or updates it if the email already exists. Someone who unsubscribed, bounced or complained is never subscribed again by the API.

curl https://sendnextmail.com/api/v1/contacts \ -H "Authorization: Bearer sn_live_..." \ -H "Content-Type: application/json" \ -d '{ "email": "maya@example.com", "first_name": "Maya", "fields": { "city": "Toronto", "plan": "pro" }, "lists": [12] }'

Returns 201 for a new contact or 200 for an update:

{ "data": { "id": 4812, "email": "maya@example.com", "first_name": "Maya", "last_name": "", "fields": { "city": "Toronto", "plan": "pro" }, "status": "subscribed", "lists": [12] }, "created": true }

Send a campaign

Build the campaign in the app, then send it from your code. SendNext runs the same checks as the Send button: a verified sending domain, a postal address, recipients and enough monthly emails left.

curl -X POST https://sendnextmail.com/api/v1/campaigns/57/send \ -H "Authorization: Bearer sn_live_..." \ -H "Content-Type: application/json" \ -d '{ "scheduled_at": "2026-12-01T14:00:00Z" }'

Errors

Errors use standard HTTP status codes and a body you can show or log:

{ "error": { "code": "insufficient_scope", "message": "This key needs the \"campaigns\" permission." } }

401 missing or revoked key · 403 permission, plan or paused account · 404 not found · 409 wrong state · 422 invalid input · 429 rate limit · 500 our side.

Rate limits

Each key can make a set number of requests per minute, depending on your plan. Every response carries X-RateLimit-Limit and X-RateLimit-Remaining. Over the limit you get 429 with Retry-After: 60.

Endpoints

MethodPathPermissionWhat it does
GET/api/v1/meRead onlyYour workspace, plan and this month's usage.
GET/api/v1/contactsRead onlyList contacts. Filter with ?email=, ?status=, ?list_id=; page with ?page= and ?limit= (max 100).
POST/api/v1/contactsContactsCreate or update a contact by email, and add it to lists.
GET/api/v1/contacts/{id}Read onlyOne contact, with the lists it's on.
PATCH/api/v1/contacts/{id}ContactsUpdate names and custom fields, or unsubscribe.
DELETE/api/v1/contacts/{id}ContactsDelete a contact.
GET/api/v1/listsRead onlyLists with subscribed and total counts.
POST/api/v1/listsContactsCreate a list.
POST/api/v1/lists/{id}/contactsContactsAdd existing contacts to a list by contact_ids or emails.
DELETE/api/v1/lists/{id}/contactsContactsRemove contacts from a list.
GET/api/v1/campaignsRead onlyYour 100 most recent campaigns.
GET/api/v1/campaigns/{id}Read onlyA campaign with its report: delivered, opens, clicks, bounces.
POST/api/v1/campaigns/{id}/sendCampaignsSend a draft now, or pass scheduled_at to schedule it.