Transactional email platform

# Send reliable email via API & SMTP

Self-hosted MailHub gives you domain DNS guidance, DKIM signing, delivery logs, and signed webhooks — without locking you into a black-box SaaS.

Get started View API sample

- Self-hosted
- DKIM
- SPF
- DMARC
- Delivery webhooks

curl

## Built for production senders

Everything you need to authenticate domains and observe delivery.

### Domains & DNS

Guided SPF, DKIM, DMARC, and one-click DNS provider writes.

### SMTP Submission

App-friendly SMTP listeners with credentials you control.

### HTTP Send API

Bearer tokens and a simple JSON send endpoint for apps and services.

### Mailboxes & receiving

Create persistent or expiring inboxes with IMAP, POP3, forwarding, and catch-all routing.

### Delivery logs

Track queue and MTA outcomes with searchable send history.

### Webhooks

Signed callbacks for sent, bounced, and failed terminal events.

### Multi-user isolation

Domains, tokens, and logs stay scoped to each account.

## Start in four steps

The console keeps domain, token, mailbox, and delivery configuration in one place.

1

### Add a domain

Add your sending domain and publish the DNS records shown by MailHub.

Review domain setup →
2

### Create a scoped token

Give each integration only the send or mailbox permissions it needs.

Review API access →
3

### Provision mailboxes

Create persistent mailboxes in the console or create persistent and temporary mailboxes by API.

Review mailbox API →
4

### Connect your client

Use SMTP to send and IMAP or POP3 to receive with the mailbox's full address and password.

Review protocol settings →

## API authentication and sending

All public API calls use a Bearer token. The hostname below is a placeholder; replace it with your MailHub host.

### Create and protect a token

Create a token in Console > API Tokens. Full tokens can be viewed and copied by the owning account, so keep console access restricted and never place tokens in browser code or public repositories.

- `send` — send messages with POST /api/send
- `mailboxes:read` — list mailboxes with GET /api/mailboxes
- `mailboxes:write` — create mailboxes with POST /api/mailboxes
- `messages:read` — read inbound messages with GET /api/inbound-messages

### Send a message

The From domain must belong to the token account. When verified sending is enabled, complete the domain DNS checks before sending.

`Authorization: Bearer <USER_API_TOKEN>`

POST /api/send

Field | Required | Description
--- | --- | ---
`from` | Yes | sender address on an account-owned domain
`to` | Yes | recipient string or an address array
`subject` | No | defaults to (no subject)
`text` | No | plain-text body
`html` | No | HTML body; required when enabling open or click tracking
`tracking` | No | true/false, or { opens, clicks }; rewrites HTML only
`smtpRelayId` | No | an account-owned outbound SMTP relay ID

202 response

A 202 response means MailHub accepted the message for SMTP delivery. Use the console delivery log or webhooks to observe the later result.

## Mailbox API and clients

Create a persistent address for ongoing work, or an expiring address for a short-lived workflow.

### Mailbox API scope

POST /api/mailboxes requires mailboxes:write. The target domain must belong to the token account.

- `mode` — permanent or temporary
- `address` / `domain` — use a full address, or choose domain plus localPart
- `expiresInMinutes` — required for temporary mailboxes; 5 minutes to 30 days
- `password` — optional; a secure password is returned once when omitted

### Use the returned configuration

Creation returns the address, password, expiration, and ready-to-use IMAP, POP3, and SMTP settings.

- IMAP — recommended for synchronized folders and sent mail
- POP3 — for download-oriented clients
- SMTP — use the same full mailbox address and password to send

POST /api/mailboxes - permanent

POST /api/mailboxes - temporary

GET /api/mailboxes

201 creation response

- The returned password is the only opportunity to read an automatically generated password.
- A temporary mailbox expires after the requested interval and then stops receiving mail and authenticating.
- Use mailboxes:read to list mailbox metadata; passwords are never returned by the list endpoint.

## Receiving mail

Mail arrives through the domain MX record. Read it in MailHub Inbox, through IMAP/POP3, or with a scoped Bearer token.

GET /api/inbound-messages - list

GET /api/inbound-messages/:id - detail

Inbound APIs require messages:read and are limited by the token mailbox access setting. Only administrator tokens explicitly set to all mailboxes can read across accounts.

### Inbound delivery

Set the domain MX record to the receiving host. External mail servers then deliver to SMTP port 25, and MailHub stores mail for an existing mailbox, alias, or catch-all target.

### Mailbox, aliases, and catch-all

Create a full mailbox address first. Add aliases or forwarding on that mailbox, and configure the domain catch-all in the console to route unknown local parts to a mailbox or another address.

Protocol | Recommended ports | Security | Use
--- | --- | --- | ---
IMAP | `993` / `143` | SSL/TLS or STARTTLS | recommended for synchronized folders
POP3 | `995` / `110` | SSL/TLS or STLS | download-oriented clients
SMTP | `465` / `587` | SMTPS or STARTTLS | send with the same mailbox address and password

IMAP exposes INBOX, Sent, Drafts, Trash, Junk, and Archive. Use IMAP when the client should synchronize these folders and save sent messages.

## Domain configuration

Create the domain in MailHub first. Its DNS panel is the source of truth for your exact verification, DKIM, SPF, DMARC, and sender-host values.

Purpose | Record | Requirement
--- | --- | ---
Domain ownership | `TXT _mailhub.<domain>` | Publish the verification value generated in the console.
DKIM | `TXT <selector>._domainkey.<domain>` | Publish the public key generated for this domain.
SPF | `TXT <domain>` | Keep one SPF record and include the sender IP/host required by MailHub.
DMARC | `TXT _dmarc.<domain>` | Start with monitoring, then strengthen the policy after alignment is verified.
Inbound mail | `MX <domain>` | Point MX to the MailHub receiving host and ensure that host has an A/AAAA record.

For reliable delivery, also configure the sending IP's PTR to match the MailHub sending hostname and allow the documented SMTP, IMAP, and POP3 ports through your firewall.

## SMTP submission

Default listener ports (override in your deployment):

25 smtp
587 smtp / STARTTLS
465 smtps
2525 smtp

### Application SMTP

Create an SMTP login credential in the console for an application. Use that credential with an account-owned From domain.

### Mailbox SMTP

A created mailbox can also authenticate over SMTP with its full email address and password. Use the same credentials for IMAP or POP3.

Prefer 465 or 587 for sending, 993 for IMAP, and 995 for POP3. The creation response is the source of truth when a deployment overrides default ports or TLS listeners.

## Responses and common errors

The API returns JSON. Validate the HTTP status before consuming a response body.

Status | Meaning | What to do
--- | --- | ---
`201` | Mailbox created | Store the one-time password and clientConfig.
`202` | Message accepted for SMTP delivery | Inspect delivery logs or webhooks for later delivery status.
`400` | Invalid request or domain ownership rule | Read the JSON error and correct the request body or domain setup.
`401` | Missing, invalid, revoked, or expired token | Create or rotate a valid token.
`403` | Token does not have the required scope | Grant the minimum required scope in Console > API Tokens.
`409` | Mailbox address already exists | Choose another address or use the existing mailbox.

## Delivery webhooks

Terminal events only — signed HTTPS callbacks to your systems.

Status | type
--- | ---
`sent` | `email.sent`
`bounced` | `email.bounced`
`failed` | `email.failed`

Signature header: `X-MailHub-Signature: t=<unix>,v1=<hmac>`

## Ready to send?

Create an account, add a domain, and ship your first message in minutes.

Get started Log in