guides
Sending Email
Send messages, reply to conversations, and manage threads.
Send email from any mailbox through a single API call. Nerfmail handles threading, reply routing, and delivery automatically.
Send a Message
curl -X POST https://api.nerfmail.com/v1/mailboxes/{mailboxId}/send \
-H "Authorization: Bearer $MAILBOX_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: send-001" \
-d '{
"to": ["recipient@example.com"],
"subject": "Hello from Nerfmail",
"textBody": "This is a test message.",
"htmlBody": "<p>This is a test message.</p>"
}'Response:
{
"message": {
"id": "uuid",
"status": "sent",
"from_address": "acme@nerfmail.com",
"to_address": "recipient@example.com",
"subject": "Hello from Nerfmail",
"direction": "outbound",
"transport": "smtp"
},
"provider_message_id": "message-id",
"reply_to": "acme+reply-AbCdEfGhIjKlMnOpQrStUv@nerfmail.com"
}The reply_to field is a secure alias. When the recipient replies to it, Nerfmail automatically routes the response back into the correct thread.
Secure Reply Routing
Every outbound message generates a cryptographic reply token — a unique address that maps replies back to the original conversation.
| Property | Value |
|---|---|
| Format | {localPart}+reply-{token}@{domain} |
| Expiry | 30 days |
| Scope | Bound to a specific mailbox and thread |
If a reply token has expired, the inbound reply is rejected with a 410 Gone error.
Reply to a Message
To reply to an inbound message:
curl -X POST https://api.nerfmail.com/v1/messages/{messageId}/reply \
-H "Authorization: Bearer $MAILBOX_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: reply-001" \
-d '{
"textBody": "Thanks for your message!",
"cc": ["other@example.com"]
}'The reply automatically:
- Sets the correct
In-Reply-Toheader - Stays in the same thread
- Generates a new reply token for continued conversation
Threading
Messages are grouped into conversations automatically using email headers:
- In-Reply-To header — If present, the message joins the referenced thread
- Message-ID header — Used to start or match a thread
- Heuristic fallback — Combines sender address and normalised subject (stripping Re:/Fw: prefixes)
List Threads
curl "https://api.nerfmail.com/v1/mailboxes/{mailboxId}/threads?status=open&limit=20" \
-H "Authorization: Bearer $MAILBOX_TOKEN"Filter by status (open or archived), search by query, and paginate with page and limit.
Suppression List
Nerfmail maintains a suppression list to prevent sending to addresses that have bounced, complained, or unsubscribed. Both send and reply check the list automatically.
Manage Suppressions
# List suppressions
curl "https://api.nerfmail.com/v1/accounts/{accountId}/suppressions?limit=50" \
-H "Authorization: Bearer $ADMIN_TOKEN"
# Add a suppression
curl -X POST https://api.nerfmail.com/v1/accounts/{accountId}/suppressions \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"address": "bounced@example.com",
"reason": "bounce"
}'
# Remove a suppression
curl -X DELETE "https://api.nerfmail.com/v1/accounts/{accountId}/suppressions?address=bounced@example.com" \
-H "Authorization: Bearer $ADMIN_TOKEN"Suppression reasons: bounce, complaint, unsubscribe, manual.
Delivery Events
Track the delivery status of outbound messages:
curl https://api.nerfmail.com/v1/messages/{messageId}/delivery \
-H "Authorization: Bearer $MAILBOX_TOKEN"Mailbox Policies
Control sending behaviour per mailbox:
curl -X PUT https://api.nerfmail.com/v1/mailboxes/{mailboxId}/policy \
-H "Authorization: Bearer $MAILBOX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"allow_outbound": true,
"allow_auto_reply": true,
"max_outbound_per_day": 500
}'| Policy | Default | Description |
|---|---|---|
allow_outbound |
true |
Whether the mailbox can send email |
allow_auto_reply |
true |
Whether agent protocol auto-replies are allowed |
max_outbound_per_day |
1000 |
Maximum outbound messages per hour (sliding window) |
Rate Limits
Outbound sends are rate-limited per mailbox (default: 1,000/hour). API keys are rate-limited at 600 calls per 10-minute window. Exceeding either returns 429 Too Many Requests.
Drafts
You can compose messages as drafts before sending. See the Drafts & Labels guide.