Skip to Content
API ReferenceSend Emails

Send Emails API

Send emails directly through Mailpulse with automatic open and click tracking. Emails are sent via your verified sending domain using the Resend infrastructure.

Sending Domain

You have two options for the sender address:

  1. Custom domain (recommended) — Add and verify your own domain in Settings > Sending Domains for full branding control.
  2. Platform domain (fallback) — If your from domain is not verified, Mailpulse automatically rewrites the sender to @send.mailpulse-io.lyten.agency and sets reply-to to your original address so recipients can still reply to you.

For example, if you send from Newsletter <news@example.com> without verifying example.com, the email will be sent from Newsletter <news@send.mailpulse-io.lyten.agency> with reply-to: news@example.com.

Send Email

Endpoint

POST /api/send

Request Body

FieldTypeRequiredDescription
fromstringYesSender address (e.g. Your Name <you@yourdomain.com>)
tostring | string[]YesRecipient email address(es)
subjectstringYesEmail subject line
htmlContentstringYesHTML content of the email
replyTostringNoReply-to email address
ccstring | string[]NoCC recipient(s)
bccstring | string[]NoBCC recipient(s)
campaignIdstringNoCampaign name to associate with
metadataobjectNoCustom metadata to store

Example Request

curl -X POST NEXT_PUBLIC_BASE_URL/api/send \ -H "x-api-key: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "from": "Newsletter <news@yourdomain.com>", "to": "recipient@example.com", "subject": "Welcome to our newsletter", "htmlContent": "<html><body><h1>Hello!</h1><a href=\"https://example.com\">Visit us</a></body></html>", "campaignId": "welcome-series", "metadata": { "userId": "123" } }'

Response Schema

FieldTypeDescription
idstringResend email ID
emailTrackingIdstringMailpulse tracking ID
fromstringSender address used
tostring[]Recipient addresses
subjectstringEmail subject
linksTrackedLink[]Tracked links with original and tracking URLs
pixelUrlstringOpen tracking pixel URL

Example Response

{ "id": "re_abc123", "emailTrackingId": "hE4kJ9xP", "from": "Newsletter <news@yourdomain.com>", "to": ["recipient@example.com"], "subject": "Welcome to our newsletter", "links": [ { "originalUrl": "https://example.com", "trackingId": "mN2pQ7", "trackingUrl": "https://mailpulse-io.lyten.agency/api/t/c/mN2pQ7" } ], "pixelUrl": "https://mailpulse-io.lyten.agency/api/t/o/hE4kJ9xP" }

How It Works

When you call POST /api/send, Mailpulse:

  1. Checks if the sender domain is verified — if not, falls back to the platform domain
  2. Extracts all links from the HTML content
  3. Creates tracking records for the email and each link
  4. Rewrites all links to pass through Mailpulse tracking endpoints
  5. Injects a 1x1 tracking pixel for open detection
  6. Sends the modified HTML via Resend
  7. Triggers the EMAIL_SENT webhook if configured

All opens and clicks are then tracked automatically — no additional setup needed.


Difference with Register Email

POST /api/sendPOST /api/emails
Sends the emailYes (via Resend)No (returns modified HTML)
Requires sending domainNo (falls back to platform domain)No
TrackingAutomaticYou inject pixel/links yourself
Use caseSend + track in one callTrack emails sent by another service

Use /api/send when you want Mailpulse to handle both sending and tracking. Use /api/emails when you send emails through your own provider (Gmail, SendGrid, SMTP, etc.) and only need tracking.


Error Responses

StatusDescription
400 Bad RequestMissing required fields or invalid JSON
401 UnauthorizedInvalid or missing API key
500 Internal Server ErrorEmail delivery failed
Last updated on
Mailpulse Documentation