All-in-one email platform combining transactional email, marketing campaigns, email receiving, and unified inbox management.
- Send Emails: Transactional email API with templates, webhooks, and tracking
- Receive Emails: AWS SES integration for receiving emails with real-time notifications
- Unified Inbox: Gmail-like interface with folders, labels, and search across all identities
- Multi-Domain: Support for multiple domains with DNS management
- Real-time: SSE (Server-Sent Events) for instant email notifications
- Identity Management: Multiple identities per domain with color coding
- Catch-All Support: Route unmatched emails to a designated identity per domain
- Smart Reply: Auto-selects correct sender identity when replying (including catch-all)
- Go 1.24+
- Node.js 20+
- Docker
- PostgreSQL database
- AWS account (for SES email sending/receiving)
# Install dependencies
pnpm install
# Start Stalwart mail server
docker-compose up -d
# Build and run Go API
cd apps/api
go build -o bin/server ./cmd/server
./bin/server
# Run Vue frontend (in another terminal)
cd apps/web
npm run devCopy .env.example to .env and configure:
# Database
DATABASE_URL="postgresql://user:password@host:5432/database?sslmode=require"
# Redis (optional)
REDIS_URL="redis://:password@host:6379"
# Authentication
JWT_SECRET="your-jwt-secret-min-32-chars"
JWT_EXPIRES_IN="7d"
# AWS SES (Required for email sending/receiving)
AWS_REGION="us-east-1"
AWS_ACCESS_KEY_ID="your-access-key"
AWS_SECRET_ACCESS_KEY="your-secret-key"
# Stalwart Mail Server
STALWART_URL="http://localhost:8080"
STALWART_ADMIN_TOKEN="your-admin-token"Mailat uses AWS SES for:
- Sending emails via SES SMTP or API
- Receiving emails via SES Receipt Rules → S3 → SNS → Webhook
| Service | Purpose |
|---|---|
| SES | Send and receive emails |
| S3 | Store raw received emails |
| SNS | Notify webhook of new emails |
| IAM | API credentials with required permissions |
Create an IAM user with the following policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ses:SendEmail",
"ses:SendRawEmail",
"ses:VerifyDomainIdentity",
"ses:VerifyDomainDkim",
"ses:GetIdentityVerificationAttributes",
"ses:CreateReceiptRule",
"ses:CreateReceiptRuleSet",
"ses:SetActiveReceiptRuleSet",
"ses:DescribeReceiptRuleSet",
"ses:DeleteReceiptRule"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:CreateBucket",
"s3:PutBucketPolicy",
"s3:GetBucketPolicy",
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::mailat-*",
"arn:aws:s3:::mailat-*/*"
]
},
{
"Effect": "Allow",
"Action": [
"sns:CreateTopic",
"sns:Subscribe",
"sns:ConfirmSubscription",
"sns:Publish",
"sns:DeleteTopic"
],
"Resource": "arn:aws:sns:*:*:mailat-*"
}
]
}Email receiving is only available in these AWS regions:
us-east-1(N. Virginia)us-west-2(Oregon)eu-west-1(Ireland)
-
Verify Domain in SES Console
- Go to AWS SES → Verified Identities → Create Identity
- Add your domain and complete DNS verification
-
Configure MX Record
MX @ 10 inbound-smtp.us-east-1.amazonaws.com(Replace region with your SES region)
-
Enable Receiving in Mailat
- Go to Domains page in the app
- Click "Enable Receiving" on your verified domain
- The system automatically creates:
- S3 bucket for email storage
- SNS topic for notifications
- SES receipt rule for your domain
1. Email sent to user@yourdomain.com
2. AWS SES receives email (via MX record)
3. SES stores raw email in S3
4. SES sends notification to SNS
5. SNS POSTs to your webhook endpoint
6. API processes and stores email metadata
7. SSE notifies connected clients in real-time
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/auth/register |
Register new user with organization |
| POST | /api/v1/auth/login |
Login and get JWT token |
| GET | /api/v1/auth/me |
Get current user profile |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/domains |
Add domain with DKIM generation |
| GET | /api/v1/domains |
List all domains |
| GET | /api/v1/domains/:uuid |
Get domain with DNS records |
| POST | /api/v1/domains/:uuid/verify |
Verify DNS records |
| POST | /api/v1/domains/:uuid/setup-receiving |
Setup email receiving |
| DELETE | /api/v1/domains/:uuid |
Delete domain |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/identities |
Create identity with Stalwart sync |
| GET | /api/v1/identities |
List all identities |
| GET | /api/v1/identities/:uuid |
Get identity details |
| PUT | /api/v1/identities/:uuid/password |
Update identity password |
| POST | /api/v1/identities/:uuid/catch-all |
Set as catch-all for domain |
| DELETE | /api/v1/identities/:uuid |
Delete identity |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/inbox/received |
List received emails with filters |
| GET | /api/v1/inbox/received/:uuid |
Get single email with content |
| GET | /api/v1/inbox/received/counts |
Get folder counts |
| POST | /api/v1/inbox/received/mark |
Mark emails as read/unread |
| POST | /api/v1/inbox/received/star |
Star/unstar emails |
| POST | /api/v1/inbox/received/move |
Move emails to folder |
| POST | /api/v1/inbox/received/trash |
Trash or permanently delete |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/compose/send |
Send email via AWS SES |
| POST | /api/v1/compose/draft |
Save email as draft |
| PUT | /api/v1/compose/draft/:uuid |
Update existing draft |
| DELETE | /api/v1/compose/draft/:uuid |
Delete draft |
| GET | /api/v1/compose/reply/:uuid |
Get reply context for email |
| GET | /api/v1/compose/forward/:uuid |
Get forward context for email |
Query Parameters for listing:
identityId- Filter by identity ID (0 or omitted = unified inbox, all identities)folder- inbox, sent, drafts, spam, trash, archive, allsearch- Search in subject, from, bodylabels- Filter by label UUIDspage- Page number (default: 1)pageSize- Items per page (default: 50)
Unified Inbox:
- When
identityId=0or omitted, emails from all user's identities are returned - Response includes
identityEmail,identityDisplayName,identityColorfor UI display - Counts endpoint also supports unified view with
identityId=0
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/sse/connect?token=JWT |
SSE connection for real-time updates |
Event Types:
connected- Connection establishedheartbeat- Keep-alive (every 30s)new_email- New email receivedemail_update- Email status changedemail_deleted- Email deletedcounts_update- Folder counts changed
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/labels |
List user labels |
| POST | /api/v1/labels |
Create label |
| DELETE | /api/v1/labels/:uuid |
Delete label |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/emails |
Send single transactional email |
| POST | /api/v1/emails/batch |
Batch send (up to 100) |
| GET | /api/v1/emails/:id |
Get email status and events |
| DELETE | /api/v1/emails/:id |
Cancel scheduled email |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/templates |
Create new template |
| GET | /api/v1/templates |
List all templates |
| GET | /api/v1/templates/:uuid |
Get template details |
| PUT | /api/v1/templates/:uuid |
Update template |
| DELETE | /api/v1/templates/:uuid |
Delete template |
| POST | /api/v1/templates/:uuid/preview |
Preview with variables |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/webhooks |
Create webhook endpoint |
| GET | /api/v1/webhooks |
List all webhooks |
| PUT | /api/v1/webhooks/:uuid |
Update webhook |
| DELETE | /api/v1/webhooks/:uuid |
Delete webhook |
| POST | /api/v1/webhooks/:uuid/rotate-secret |
Rotate webhook secret |
| POST | /api/v1/webhooks/:uuid/test |
Send test webhook |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/webhooks/ses/incoming |
AWS SNS notifications for received emails |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/api-keys |
Create new API key |
| GET | /api/v1/api-keys |
List all API keys |
| DELETE | /api/v1/api-keys/:uuid |
Revoke API key |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/health |
Health check (PostgreSQL + Redis) |
| GET | /api/v1/ready |
Readiness check |
curl -X POST http://localhost:3001/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"password"}'
# Use the token
curl http://localhost:3001/api/v1/auth/me \
-H "Authorization: Bearer <jwt_token>"curl -X POST http://localhost:3001/api/v1/emails \
-H "Authorization: Bearer ue_<api_key>" \
-H "Idempotency-Key: unique-request-id" \
-H "Content-Type: application/json" \
-d '{
"from": "sender@yourdomain.com",
"to": ["recipient@example.com"],
"subject": "Hello {{firstName}}",
"html": "<p>Welcome, {{firstName}}!</p>",
"variables": {"firstName": "John"}
}'Deploy Mailat instantly on Dublyo PaaS — handles SSL, DNS, containers, and updates automatically.
For Docker-based self-hosting, see docker-compose.prod.yml and .env.production.example in this repository.
mailat/
├── apps/
│ ├── api/ # Go + GoFrame Backend API
│ │ ├── cmd/server/ # Entry point
│ │ └── internal/
│ │ ├── config/ # Configuration
│ │ ├── controller/ # HTTP handlers
│ │ │ ├── received_inbox.go # Received email handlers
│ │ │ ├── compose.go # Compose/Send handlers
│ │ │ └── sse.go # SSE real-time
│ │ ├── database/ # DB connections
│ │ ├── handler/ # Webhook handlers
│ │ │ └── sns_webhook.go # AWS SNS handler
│ │ ├── middleware/ # Auth middleware
│ │ ├── model/ # Data models
│ │ ├── provider/ # External providers
│ │ │ └── receiving_provider.go # AWS setup
│ │ ├── router/ # Route definitions
│ │ └── service/ # Business logic
│ │ ├── inbox.go # Inbox service
│ │ ├── compose.go # Email sending (SES/JMAP)
│ │ ├── identity.go # Identity & Stalwart sync
│ │ ├── receiving.go # Email receiving
│ │ └── transactional.go # Sending API
│ └── web/ # Vue 3 Frontend
│ └── src/
│ ├── views/
│ │ └── ReceivedInbox.vue # Gmail-like inbox
│ ├── stores/
│ │ └── receivedInbox.ts # Pinia state
│ └── lib/
│ └── api.ts # API client
├── prisma/
│ ├── schema.prisma # Database schema
│ └── migrations/ # SQL migrations
├── docker/
│ └── caddy/Caddyfile # Reverse proxy config
└── docker-compose.yml # Local development
| Component | Technology |
|---|---|
| Backend | Go 1.24+, GoFrame v2 |
| Frontend | Vue 3.5+, TypeScript, Pinia, Tailwind |
| Database | PostgreSQL 17 |
| Cache/Queue | Redis 7.4+, Asynq |
| Mail Server | Stalwart (IMAP/SMTP/JMAP) |
| Email Provider | AWS SES |
| Storage | AWS S3 |
| Notifications | AWS SNS |
| Real-time | Server-Sent Events (SSE) |
| Reverse Proxy | Caddy (auto SSL) |
- Stalwart mail server with RocksDB backend
- Management API integration
- Account provisioning
- User authentication with JWT
- Organization and role management
- Domain management with DNS records
- Identity/mailbox management
- JMAP client for Stalwart
- Send single and batch emails
- Template system with variables
- Job queue with Redis/Asynq
- Webhook notifications
- Idempotency support
- Rate limiting
- AWS SES receipt rules
- S3 storage for raw emails
- SNS → Webhook processing
- Real-time SSE notifications
- Gmail-like inbox UI
- Folder management
- Labels and filters
- Search functionality
- AWS SES as primary email provider
- Compose/Reply/Forward UI
- Draft saving and editing
- Email threading support
- Stalwart JMAP as fallback
- Automatic From address handling
- Unified Inbox: View emails from all identities in one place (
identityId=0) - Identity Filter: Dropdown to filter by specific identity
- Identity Color Coding: Visual distinction with colored dots
- Catch-All Support: One catch-all address per domain for unmatched emails
- Smart Reply: Auto-selects correct sender identity (works with catch-all)
- Identity Actions Menu: Set default, toggle catch-all, delete identities
- Contact management
- List segmentation
- Campaign builder
- A/B testing
- Monitoring dashboard
- Analytics and reporting
- Alerting system
Automate your email workflows with the official n8n community node. Send emails, manage your inbox, and react to email events directly from n8n.
n8n-nodes-mailat
Install via Settings > Community Nodes > Install in your n8n instance, or manually:
cd ~/.n8n && npm install n8n-nodes-mailatSupported operations: Send email, batch send, inbox management, domain & identity listing, and 8 webhook trigger events (email received, email sent, contact CRUD, bounces, complaints).
See the n8n-nodes-mailat README for full documentation.
MIT

