API reference
A JSON API over HTTPS. All paths are relative to https://stalkmail.com/api/v1. Every request needs a newsletter API key.
Conventions
- Requests and responses are JSON.
- Timestamps are ISO 8601 in UTC.
- Lists are paginated with
limitandcursor, and returnpagination.nextCursor. - Errors use the shape described on the errors page.
curl "https://stalkmail.com/api/v1/subscribers?limit=20" \\
-H "Authorization: Bearer $STALKMAIL_API_KEY"Add a subscriber
Adds a contact to the key's newsletter. A duplicate email returns 409 conflict.
curl https://stalkmail.com/api/v1/subscribers \\
-H "Authorization: Bearer $STALKMAIL_API_KEY" \\
-H "Content-Type: application/json" \\
-d '{ "email": "reader@example.com", "name": "Alex Reader" }'Update a subscriber
curl https://stalkmail.com/api/v1/subscribers/<id> \\
-X PATCH \\
-H "Authorization: Bearer $STALKMAIL_API_KEY" \\
-H "Content-Type: application/json" \\
-d '{ "status": "unsubscribed" }'Endpoints
Newsletter
- GET
/api/v1/newsletterNewsletter details and subscriber counts.
Subscribers
- GET
/api/v1/subscribersList and filter subscribers. - POST
/api/v1/subscribersAdd a subscriber. - GET
/api/v1/subscribers/:idRetrieve one subscriber. - PATCH
/api/v1/subscribers/:idUpdate the name or status. - DELETE
/api/v1/subscribers/:idDelete a subscriber.
Forms (public)
- GET
/api/forms/:slugForm settings for the hosted page and embed. - POST
/api/forms/:slug/subscribeSubmit a signup. Honors double opt-in.
Webhooks (Unosend)
- POST
/api/webhooks/unosendDelivery, open, click, bounce and spam events. Called by Unosend, not by your app.
Campaigns (planned)
- GET
/api/v1/campaignsList campaigns. - POST
/api/v1/campaignsCreate a draft. - POST
/api/v1/campaigns/:id/sendSend now. - POST
/api/v1/campaigns/:id/scheduleSchedule for later. - GET
/api/v1/campaigns/:id/reportDelivery and engagement.
Domains (planned)
- GET
/api/v1/domainsList sending domains. - POST
/api/v1/domainsAdd a domain. - POST
/api/v1/domains/:id/verifyCheck DNS records.
API keys and forms
Create and revoke keys in the dashboard under API keys. Signup forms are configured in Settings → Form and embed. The hosted page lives at /join/{slug} and can be embedded with /embed.js. The embed renders the form directly on the page inside a Shadow DOM, so it does not use an iframe.
MCP clients
Requests made by an MCP client should send X-StalkMail-Client: mcp. The newsletter owner can then turn agent actions off in Settings → Notifications without revoking the API key. Requests with that header return 403 forbidden while the toggle is off. Plain API requests are unaffected.
Signup form endpoints
These endpoints are public and scoped by newsletter slug, not by API key. They honor the form's on/off toggle, its domain allowlist and double opt-in.
curl "https://stalkmail.com/api/forms/your-slug" \\
-H "Origin: https://example.com"curl https://stalkmail.com/api/forms/your-slug/subscribe \\
-X POST \\
-H "Content-Type: application/json" \\
-H "Origin: https://example.com" \\
-d '{ "email": "reader@example.com", "name": "Alex Reader" }'Email activity webhooks
Delivery, opens, clicks, bounces and spam complaints for confirmation and welcome emails are recorded automatically. Our provider, Unosend, calls POST /api/webhooks/unosend with signed events; you do not need to configure anything for this to work. Every event is applied at most once, updates the contact's engagement stats, and shows up in the dashboard logs.
Want the same events in your own app? Unosend can call your endpoint too — see their webhook guide.