Inbound Email
Receive incoming emails via webhook with custom inbound routing domains
Inbound Email
Inbound routing lets you receive incoming emails and forward their contents to your application via webhook. Point an MX record at MisarMail and every email sent to that address triggers a POST to your webhook URL.
Auth scope: inbound
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/v1/inbound | List inbound domains |
POST | /api/v1/inbound | Create an inbound domain |
GET | /api/v1/inbound/:id | Get a single inbound domain |
PATCH | /api/v1/inbound/:id | Update webhook URL or secret |
DELETE | /api/v1/inbound/:id | Remove an inbound domain |
Setup Overview
Create an inbound domain via POST /api/v1/inbound with your webhook URL.
Add an MX record in your DNS pointing to inbound.mail.misar.io with priority 10.
Receive emails — every inbound message triggers a signed POST to your webhook_url.
GET /api/v1/inbound
curl https://mail.misar.io/api/v1/inbound \
-H "Authorization: Bearer msk_YOUR_API_KEY"Response
{
"success": true,
"domains": [
{
"id": "inb_abc123",
"subdomain": "replies.yourdomain.com",
"webhook_url": "https://yourapp.com/webhooks/email",
"status": "active",
"created_at": "2026-03-01T10:00:00Z"
}
]
}POST /api/v1/inbound
Create a new inbound routing domain.
curl -X POST https://mail.misar.io/api/v1/inbound \
-H "Authorization: Bearer msk_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subdomain": "replies.yourdomain.com",
"webhook_url": "https://yourapp.com/webhooks/email",
"webhook_secret": "your-secret-32chars"
}'Request Fields
| Field | Type | Required | Notes |
|---|---|---|---|
subdomain | string | ✓ | Full domain/subdomain to receive email on |
webhook_url | string | ✓ | HTTPS URL to POST inbound payloads to |
webhook_secret | string | — | Used to sign payloads with HMAC-SHA256 |
Response
{
"success": true,
"domain": {
"id": "inb_abc123",
"subdomain": "replies.yourdomain.com",
"mx_record": {
"type": "MX",
"host": "replies.yourdomain.com",
"value": "inbound.mail.misar.io",
"priority": 10
},
"status": "pending"
}
}DELETE /api/v1/inbound/:id
Remove an inbound domain. Emails sent to this domain after deletion will bounce.
curl -X DELETE https://mail.misar.io/api/v1/inbound/inb_abc123 \
-H "Authorization: Bearer msk_YOUR_API_KEY"Webhook Payload
When an email is received, MisarMail sends a POST request to your webhook_url:
{
"event": "email.received",
"id": "msg_inb_xyz789",
"received_at": "2026-04-06T12:00:00Z",
"from": {
"email": "sender@example.com",
"name": "Sender Name"
},
"to": [
{ "email": "replies@yourdomain.com" }
],
"subject": "Re: Your order has shipped",
"text": "Thanks for the update!",
"html": "<p>Thanks for the update!</p>",
"headers": {
"message-id": "<abc123@example.com>",
"in-reply-to": "<def456@mail.misar.io>"
},
"attachments": [
{
"filename": "invoice.pdf",
"content_type": "application/pdf",
"size": 48210,
"url": "https://mail.misar.io/api/v1/inbound/attachments/att_abc"
}
]
}Webhook Signature Verification
Every payload is signed with HMAC-SHA256 using your webhook_secret. Verify it in your handler:
import crypto from 'crypto';
function verifyInboundWebhook(
rawBody: string,
signature: string,
secret: string
): boolean {
const expected = crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}The signature is in the X-MisarMail-Signature request header.
Always verify the webhook signature before processing inbound payloads to prevent spoofing. Reject any payload that fails verification with a 403 response.