MailPilotX Documentation
Complete guide: product workflow, sending, API, integrations and best practices.
Overview
MailPilotX is an email platform for SMBs and agencies: visual editor, bulk campaigns, on-demand transactional emails, contact lists and BYO SMTP domains (bring your own mail server).
Recommended flow: create a project (design) → attach lists, domains, campaigns and reusable emails from the project hub → send or expose via API.
Projects & hub
A project = multilingual email design (blocks, variables, media). Open a project to access the hub: design, campaigns, transactional emails, lists and domains filtered by project.
From the hub, every created resource inherits project_id. Campaign wizard starts at Audience with project-scoped lists and domains.
- Editor: drag & drop blocks, translations, {{variables}}, merge preview, HTML export.
- Brand kit (General → Brand tab): default colors, logo and font for new blocks.
- showWhen conditions: show a block when a variable matches a value (e.g. plan = premium).
- Pre-send checklist: links, image weight, quality warnings before export.
Campaigns (bulk send)
4-step wizard: audience (list or segment), subject, schedule, review. Open/click tracking via pixel and tracked links.
Scheduling: date/time, allowed days and time window. A worker picks scheduled campaigns and sends within the configured window.
- Audience modes: single list, lists per locale, dynamic segment.
- A/B test: initial split (e.g. 10%), measure opens/clicks, auto-send winning variant to the rest.
- Post-send stats: opens, clicks, bounces : from Campaigns → Statistics.
- System variable {{unsubscribe_url}}: unsubscribe link auto-injected if missing from HTML.
On-demand emails (transactional)
Reusable emails identified by slug (e.g. welcome, reset-password). Each email links to a project (design) and optionally a sending domain.
Send from UI or API POST /api/v1/transactional-emails/send with slug, recipient and variables.
- Dedicated open/click tracking (/api/track/t/…).
- Per-template stats: open and click rates in On-demand emails.
- Async API response (202): sending goes through send_jobs queue; send_id for tracking.
- Test API keys (mpx_test_…): simulated send without real SMTP, status simulated.
POST /api/v1/transactional-emails/send
Authorization: Bearer mpx_live_…
{
"slug": "welcome",
"to": "client@example.com",
"name": "Marie",
"variables": { "firstName": "Marie", "code": "ABC123" }
}Send queue & reliability
By default (SEND_VIA_JOBS=1), campaigns and transactional emails use send_jobs table. A Node worker processes jobs with retries and backoff (1m, 5m, 30m).
After max_attempts, job becomes dead letter (status dead). Set SEND_VIA_JOBS=0 for synchronous send (debug only).
- SEND_WORKER_INTERVAL_MS: poll frequency (default 10s).
- SEND_WORKER_BATCH: jobs processed per tick.
- Domain warm-up: progressive daily send limit if warmup_max_per_day is set on the domain.
API & access keys
REST API v1 under /api/v1 : Pro and Business plans only. Auth: JWT (web UI) or API key mpx_live_… / mpx_test_… (Bearer or X-API-Key header).
Scopes: read (GET), write (POST/PATCH/DELETE), send (sends). Create keys in the API menu.
- OpenAPI docs: GET /api/v1/docs and /api/v1/openapi.json
- HTML guide: GET /api/v1/guide
- Rate limit: 120 req/min per API key.
- npm SDK: mailpilotx package : client.send(slug, { to, variables }).
- Upsert + send: POST /api/v1/inbound/contacts/upsert-and-send : add contact to list and send in one request.
import { MailPilotX } from 'mailpilotx'
const client = new MailPilotX({
apiKey: process.env.MPX_KEY,
baseUrl: 'https://your-api.com'
})
await client.send('welcome', {
to: 'user@example.com',
variables: { firstName: 'Alex' }
})Outbound webhooks
Configure URLs to receive real-time events. HMAC-SHA256 signature in X-MailPilotX-Signature header.
Manage in API menu → Webhooks section. Ping test available per endpoint.
- transactional.sent : transactional email sent
- transactional.failed : transactional send failed
- campaign.completed : campaign finished
- contact.unsubscribed : unsubscribe confirmed
- send.bounced : bounce recorded
{
"id": "uuid-delivery",
"event": "transactional.sent",
"created_at": "2026-06-19T12:00:00Z",
"data": { "send_id": "…", "slug": "welcome", "to": "…" }
}MailPilotX Sync
Sync links your tools (HubSpot, Shopify, WooCommerce, Typeform, Zapier…) to a MailPilotX list via a secret webhook URL. No OAuth store: the tool POSTs JSON, the contact is upserted into the list.
Pro and Business plans. Sync menu in the app. Optional: send a transactional email (slug) on each ingest.
- Create: POST /api/v1/sync (JWT) with provider, team_id, list_id
- Ingest: POST /api/v1/sync/hooks/:id/:secret (no JWT, secret in the URL)
- Minimum JSON: { "email": "…", "name": "…" }. Shopify, Typeform and HubSpot are parsed natively
- Rate limit: 120 requests / minute / connector
POST /api/v1/sync/hooks/<id>/<secret>
Content-Type: application/json
{ "email": "contact@company.com", "name": "Alex Martin" }Unsubscribe (GDPR)
Each campaign/transactional email can include {{unsubscribe_url}}. Link leads to a public one-click confirmation page.
Unsubscribed addresses are stored per team (team_unsubscribes) and excluded from future sends automatically.
- Public page: GET/POST /api/public/unsubscribe/:token
- Unsubscribe list: segments/unsubscribes API or CRM via contact.unsubscribed webhook.
Lists, contacts & segments
Lists tied to a team and optionally a project. CSV import: custom columns → contact metadata.
Dynamic segments: JSON rules (metadata, list, campaign open) evaluated at send time. Builder in list detail view.
- Contact statuses: active, bounced, complained, unsubscribed : auto-excluded on send.
- Automations: contact.added_to_list trigger → delayed transactional send.
Automations
Simple scenarios: trigger + delay + action. Automations menu in sidebar.
- contact.added_to_list → send slug X after N hours
- campaign.sent → follow-up if not opened (J+N, configurable)
- Executed via send_jobs (type automation)
Teams & roles
Collaborate with owner, admin, editor, viewer roles. Pro: up to 3 members; Business: up to 10. Teams menu: create, invite by email, manage members.
Active team selector (persisted) to filter projects and resources. API keys can be scoped to one team.
Domains & deliverability
Configure sender domain + SMTP (host, port, encrypted credentials). MailPilotX DNS verification and SMTP test built-in.
Deliverability score: SPF, DKIM, DMARC lookup + SMTP status + bounces. Optional warm-up for progressive volume.
- GET /api/domains/:id/deliverability : score and DNS detail
- POST /api/v1/inbound/bounce : report bounces from your SMTP infra
- Tip: configure SPF, DKIM and DMARC on the actual sender domain, not only the MailPilotX token.
Media & signed URLs
Images and videos uploaded in editor (asset:uuid). At send time, replaced with temporary signed public URLs (7 days default).
Public route: GET /api/public/assets/:token : no JWT required in received email.
Library
Full email templates and reusable sections.
Full templates → new project in the editor. Sections → ready-made module blocks.
API: GET /api/library?kind=project|section · POST /api/library/:id/import
Subscription & quotas
Free plan (Starter) with monthly quota. Dashboard warning at 80% quota, free plan blocked at 100%.
Paid plans: beyond Pro quota, upgrade to Business. Multi-user teams on Pro and Business plans.
Environment variables (API)
Main server variables (see api/.env.example):
- APP_SECRET : SMTP encryption (min. 32 chars)
- API_BASE_URL : tracking, unsubscribe, signed assets
- SEND_VIA_JOBS / SEND_WORKER_* : send queue
- ASSET_SIGN_SECRET : asset URL signing (defaults to APP_SECRET)
- STORAGE_DRIVER=local|s3 : media storage (optional S3)
- SCHEDULER_* : campaign schedule worker
Resources & support
Interactive API: « API guide » link from API menu. Structured logs (Pino) with X-Request-Id for request correlation.
- Health check: GET /api/health and /api/health/db
- Admin audit: API key revocation and sensitive actions logged