Mailzeno LogomailzenoDocs

API Reference

Mailzeno exposes a versioned REST API for sending transactional emails through your own SMTP server.

The base URL for all API requests is:

GEThttps://api.mailzeno.dev

Authentication

All API requests require a valid API key passed in the Authorization header using the Bearer scheme:

Authorization: Bearer mz_api_your_api_key

API keys are validated by hashing (SHA-256) and comparing against stored key hashes. Inactive or invalid keys return a 401 status.

Send Email

POSTv1/emails

Sends a transactional email through your configured SMTP server.

Request headers

HeaderTypeRequiredDescription
AuthorizationstringYesBearer token with your API key
Content-TypestringYesMust be application/json
Idempotency-KeystringNoUnique key to prevent duplicate sends

Request body

FieldTypeRequiredDescription
smtpIdstringYesSMTP configuration ID
fromstringYesSender email (must match SMTP account username)
tostring | string[]YesRecipient email address(es)
subjectstringConditionalEmail subject (required if not using templates)
htmlstringConditionalHTML email body (required if not using templates)
textstringNoPlain text fallback
templateIdstringNoTemplate UUID
templateKeystringNoTemplate lookup key
variablesobjectNoDynamic variables for template or raw content interpolation

Provide either html + subject, or a templateId / templateKey.

Example request

cURL
curl -X POST https://api.mailzeno.dev/v1/emails \
-H "Authorization: Bearer mz_api_your_api_key" \
-H "Content-Type: application/json" \
-d '{
  "smtpId": "your_smtp_id",
  "from": "you@example.com",
  "to": "recipient@example.com",
  "subject": "Hello from Mailzeno",
  "html": "<h1>Hello World</h1>"
}'
Request Body
{
"smtpId": "your_smtp_id",
"from": "you@example.com",
"to": "recipient@example.com",
"subject": "Hello",
"html": "<h1>Hello</h1>"
}

Success response

200 OK
{
"success": true,
"messageId": "<unique-message-id@smtp.example.com>"
}

Error response

400 Bad Request
{
"error": "Missing required fields: smtpId, from, to",
"code": "missing_required_fields"
}

401 Unauthorized

401 Unauthorized
{
"error": "Invalid or inactive API key",
"code": "invalid_api_key"
}

Response headers

Every API response includes these headers:

HeaderDescription
x-request-idUnique request identifier for debugging
x-ratelimit-limitMaximum requests allowed per window
x-ratelimit-remainingRemaining requests in the current window
x-ratelimit-resetUnix timestamp when the rate limit resets
retry-afterSeconds to wait before retrying (only on 429)

Request lifecycle

The API processes each request through this pipeline:

  1. Authentication — Validate the Bearer token against stored API key hashes
  2. Plan resolution — Determine the user's plan (free or pro)
  3. Rate limiting — Check per-minute and daily rate limits via Redis
  4. Input validation — Verify required fields are present
  5. SMTP ownership check — Verify the SMTP config belongs to the authenticated user
  6. From address validation — Ensure from matches the SMTP account username
  7. Template resolution — If using templates, fetch and render with variables
  8. Usage check — Verify daily send limit not exceeded
  9. SMTP decryption — Decrypt the stored SMTP password (AES-256-GCM)
  10. Send via core engine — Send through @mailzeno/core with pooling and retry
  11. Logging — Log the email with retention policy
  12. Usage increment — Update the user's daily send count
Rate limits

API endpoints are rate limited per API key. See the Rate Limits page for details.