MisarMisar Docs
MisarMailMisar.BlogMisarReachMisarPostMisar.DevMisarSEOMisar PlatformMisar SSO
API Reference

SMTP Pools

Configure custom SMTP relay servers and route outbound email through your own infrastructure

SMTP pools let you route outbound email through your own SMTP relay instead of MisarMail's shared sending infrastructure. This is useful when you have an existing arrangement with a provider like Amazon SES, Postfix, Mailgun, or SendGrid, or when you need isolated sending pools for different business units.

The same functionality is available in the dashboard at Settings → SMTP Pools.

Requires an active MisarMail session (dashboard only). Passwords and DKIM private keys are never returned — responses expose only hasPassword and hasDkim.

List SMTP pools

GET/api/smtp-pools

Returns all configured SMTP pools for the account.

Response fields

poolsArray<object>

Each pool includes id, name, pool_type (transactional | marketing | cold), host, port, username, use_tls, max_connections, max_messages, dkim_selector, dkim_domain, is_active, is_system, health_status, created_at, plus the booleans hasPassword and hasDkim. The encrypted password and DKIM private key are stripped from the response.

{
  "pools": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Amazon SES — us-east-1",
      "pool_type": "transactional",
      "host": "email-smtp.us-east-1.amazonaws.com",
      "port": 587,
      "username": "AKIAIOSFODNN7EXAMPLE",
      "use_tls": true,
      "max_connections": 5,
      "max_messages": 100,
      "dkim_selector": "misarmail",
      "dkim_domain": null,
      "is_active": true,
      "is_system": false,
      "health_status": "unknown",
      "created_at": "2026-05-01T00:00:00Z",
      "hasPassword": true,
      "hasDkim": false
    }
  ]
}

Create SMTP pool

POST/api/smtp-pools

Create a new SMTP pool.

Request body

namestringbodyrequired

Display name for the pool.

poolTypetransactional | marketing | coldbodyrequired

Which sending category this pool serves.

hoststringbodyrequired

SMTP server hostname. Wildcard domains are rejected.

portintegerbodydefault: 587

SMTP port (1–65535).

usernamestringbodyrequired

SMTP authentication username.

passwordstringbodyrequired

SMTP authentication password (stored encrypted).

useTlsbooleanbodydefault: true

Whether to connect over TLS/STARTTLS.

maxConnectionsintegerbodydefault: 5

Maximum concurrent SMTP connections (1–50).

maxMessagesintegerbodydefault: 100

Maximum messages per connection (1–1000).

generateDkimbooleanbodydefault: false

Generate a DKIM key pair for this pool. When true, the response includes a dkimDnsRecord to publish.

dkimDomainstringbody

Domain the DKIM key signs for (used with generateDkim).

dkimSelectorstringbodydefault: misarmail

DKIM selector (max 63 chars).

Response fields

poolobject

The created pool (password and DKIM private key stripped).

dkimDnsRecordobject | null

The DKIM TXT record to publish when generateDkim was true; otherwise null.

createdboolean

Always true on success.

curl -X POST /api/smtp-pools \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Amazon SES — us-east-1",
    "poolType": "transactional",
    "host": "email-smtp.us-east-1.amazonaws.com",
    "port": 587,
    "username": "AKIAIOSFODNN7EXAMPLE",
    "password": "your-ses-smtp-password",
    "useTls": true
  }'
{
  "pool": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Amazon SES — us-east-1",
    "pool_type": "transactional",
    "host": "email-smtp.us-east-1.amazonaws.com",
    "port": 587,
    "use_tls": true,
    "is_active": true,
    "hasPassword": true,
    "hasDkim": false
  },
  "dkimDnsRecord": null,
  "created": true
}
const res = await fetch('/api/smtp-pools', {
  method: 'POST',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    name: 'Amazon SES — us-east-1',
    poolType: 'transactional',
    host: 'email-smtp.us-east-1.amazonaws.com',
    port: 587,
    username: process.env.SES_USERNAME,
    password: process.env.SES_PASSWORD,
    useTls: true,
  }),
});
const { pool, dkimDnsRecord } = await res.json();

Common provider settings

ProviderHostPortuseTls
Amazon SESemail-smtp.<region>.amazonaws.com587true
Mailgunsmtp.mailgun.org587true
SendGridsmtp.sendgrid.net587true
Postfix (self-hosted)Your server IP/hostname587true
Gmail SMTPsmtp.gmail.com465true

Update SMTP pool

PUT/api/smtp-pools

Update a pool you own. Pass the pool id in the body along with any fields to change. System pools cannot be modified.

Request body

idUUIDbodyrequired

ID of the pool to update.

isActivebooleanbody

Enable or disable the pool.

Any field accepted by POST (name, poolType, host, port, username, password, useTls, maxConnections, maxMessages, generateDkim, dkimDomain, dkimSelector) may also be sent to update it. Omitted fields are left unchanged.

Response fields

poolobject

The updated pool.

dkimDnsRecordobject | null

Present when DKIM was (re)generated during the update.

updatedboolean

Always true on success.

curl -X PUT /api/smtp-pools \
  -H "Content-Type: application/json" \
  -d '{ "id": "550e8400-e29b-41d4-a716-446655440000", "isActive": false }'
{
  "pool": { "id": "550e8400-e29b-41d4-a716-446655440000", "is_active": false },
  "dkimDnsRecord": null,
  "updated": true
}

Delete SMTP pool

DELETE/api/smtp-pools

Delete a pool you own. The pool id is passed as a query parameter. A pool that is still referenced by one or more aliases cannot be deleted — reassign those aliases first. System pools cannot be deleted.

Query parameters

idUUIDqueryrequired

ID of the pool to delete.

Response fields

deletedboolean

true when the pool was removed.

curl -X DELETE "/api/smtp-pools?id=550e8400-e29b-41d4-a716-446655440000"
{ "deleted": true }
{ "error": "Cannot delete a pool that is still assigned to aliases" }

Test SMTP connection

POST/api/smtp-pools/:id/test

Runs a live connectivity check against the pool's SMTP server: TCP connect → EHLO → STARTTLS (on port 587) → success. It does not send an email. The response is returned at HTTP 200 even when the check fails — inspect the status field.

Path parameters

idUUIDpathrequired

ID of the SMTP pool to test.

Response fields

successboolean

true when the connection check passed.

statusstring

healthy when the check passed, unhealthy otherwise. Persisted to the pool's health_status.

errorstring

The underlying SMTP/connection error, present only when status is unhealthy.

{ "success": true, "status": "healthy" }
{
  "success": false,
  "status": "unhealthy",
  "error": "Connection error: connect ECONNREFUSED 198.51.100.1:587"
}

Status codes

  • 200 — OK. List, update, delete, or test completed (a failed connectivity test still returns 200 with status: "unhealthy").
  • 201 — Created. Pool created.
  • 400 — Bad request. Failed body validation, missing/invalid pool id, or invalid JSON.
  • 401 — Unauthorized. No active session.
  • 403 — Forbidden. The pool is a system pool, or it does not belong to you.
  • 404 — Not found. Pool not found.
  • 409 — Conflict. The pool is still assigned to one or more aliases.
  • 500 — Server error. Failed to create, update, or delete the pool.

Using an SMTP pool for sends

A send never references a pool directly — it references an alias, and the alias routes through its assigned SMTP pool. Assign a pool to an alias (see Email Aliases), then reference that alias by id in your send request:

curl -X POST https://api.misar.io/mail/v1/send \
  -H "Authorization: Bearer msk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "to": [{ "email": "user@example.com" }],
    "from": { "email": "hello@example.com", "name": "Acme" },
    "subject": "Your order is confirmed",
    "html": "<p>Thanks for your order!</p>",
    "alias_id": "660e8400-e29b-41d4-a716-446655440111"
  }'

If alias_id is omitted, MisarMail uses your default alias (and its pool).

Amazon SES setup notes

  1. Verify your sending domain in the SES console
  2. Request production access if you are out of the SES sandbox
  3. Create SMTP credentials in SES → Account dashboard → SMTP settings → Create SMTP credentials
  4. Use port 587 with STARTTLS (useTls: true)
  5. Ensure your EC2 or VPS security group allows outbound TCP on port 587

Amazon SES SMTP credentials (access key + secret) are different from your AWS IAM credentials. Generate them specifically in the SES console.