Misar Docs
MisarMailMisar.BlogMisarReachMisarPostMisar.DevMisar PlatformMisar IdentityMisar Posts API
Api Reference

Inbound Email

Receive incoming emails via webhook with custom inbound routing domains

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.

Authentication

All inbound endpoints require an API key with the inbound scope. Base URL: https://api.misar.io/mail.

Endpoints

MethodPathDescription
GET/api/v1/inboundList inbound domains
POST/api/v1/inboundCreate an inbound domain
GET/api/v1/inbound/:idGet a single inbound domain
PATCH/api/v1/inbound/:idUpdate webhook URL or secret
DELETE/api/v1/inbound/:idRemove an inbound domain

Setup Overview

Create an inbound domain via POST /mail/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.

List inbound domains

GET/mail/v1/inbound

List all inbound routing domains for the authenticated account.

Response fields

successboolean

true when the request succeeded.

domainsArray<InboundDomain>

The inbound domains. Each includes id, subdomain, webhook_url, status, and created_at.

curl https://api.misar.io/mail/v1/inbound \
  -H "Authorization: Bearer msk_YOUR_API_KEY"
{
  "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"
    }
  ]
}

Create an inbound domain

POST/mail/v1/inbound

Create a new inbound routing domain.

Request body

subdomainstringbodyrequired

Full domain/subdomain to receive email on.

webhook_urlstringbodyrequired

HTTPS URL to POST inbound payloads to.

webhook_secretstringbody

Used to sign payloads with HMAC-SHA256.

Response fields

successboolean

true when the domain was created.

domainobject

The created domain, including id, subdomain, an mx_record object to publish, and status.

curl -X POST https://api.misar.io/mail/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"
  }'
{
  "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"
  }
}

Remove an inbound domain

DELETE/mail/v1/inbound/:id

Remove an inbound domain. Emails sent to this domain after deletion will bounce.

Path parameters

idstringpathrequired

ID of the inbound domain to remove.

curl -X DELETE https://api.misar.io/mail/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": "[email protected]",
    "name":  "Sender Name"
  },
  "to": [
    { "email": "[email protected]" }
  ],
  "subject":  "Re: Your order has shipped",
  "text":     "Thanks for the update!",
  "html":     "<p>Thanks for the update!</p>",
  "headers": {
    "message-id":   "<[email protected]>",
    "in-reply-to":  "<[email protected]>"
  },
  "attachments": [
    {
      "filename":     "invoice.pdf",
      "content_type": "application/pdf",
      "size":         48210,
      "url":          "https://api.misar.io/mail/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.