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:
- Custom domain (recommended) — Add and verify your own domain in Settings > Sending Domains for full branding control.
- Platform domain (fallback) — If your
fromdomain is not verified, Mailpulse automatically rewrites the sender to@send.mailpulse-io.lyten.agencyand setsreply-toto 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/sendRequest Body
| Field | Type | Required | Description |
|---|---|---|---|
from | string | Yes | Sender address (e.g. Your Name <you@yourdomain.com>) |
to | string | string[] | Yes | Recipient email address(es) |
subject | string | Yes | Email subject line |
htmlContent | string | Yes | HTML content of the email |
replyTo | string | No | Reply-to email address |
cc | string | string[] | No | CC recipient(s) |
bcc | string | string[] | No | BCC recipient(s) |
campaignId | string | No | Campaign name to associate with |
metadata | object | No | Custom 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
| Field | Type | Description |
|---|---|---|
id | string | Resend email ID |
emailTrackingId | string | Mailpulse tracking ID |
from | string | Sender address used |
to | string[] | Recipient addresses |
subject | string | Email subject |
links | TrackedLink[] | Tracked links with original and tracking URLs |
pixelUrl | string | Open 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:
- Checks if the sender domain is verified — if not, falls back to the platform domain
- Extracts all links from the HTML content
- Creates tracking records for the email and each link
- Rewrites all links to pass through Mailpulse tracking endpoints
- Injects a 1x1 tracking pixel for open detection
- Sends the modified HTML via Resend
- Triggers the
EMAIL_SENTwebhook if configured
All opens and clicks are then tracked automatically — no additional setup needed.
Difference with Register Email
POST /api/send | POST /api/emails | |
|---|---|---|
| Sends the email | Yes (via Resend) | No (returns modified HTML) |
| Requires sending domain | No (falls back to platform domain) | No |
| Tracking | Automatic | You inject pixel/links yourself |
| Use case | Send + track in one call | Track 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
| Status | Description |
|---|---|
400 Bad Request | Missing required fields or invalid JSON |
401 Unauthorized | Invalid or missing API key |
500 Internal Server Error | Email delivery failed |
Last updated on