One npx 4ward deploy. Inbound aliases with SPF/DMARC-safe forwarding plus a transactional email API — no servers, no idle bill.
Email forwarding is a solved problem — but hosted SaaS asks you to rent someone else's infrastructure every month, exactly when a side project can least afford it. 4ward runs the same job inside your own AWS account:
- 100% serverless — SES, Lambda, API Gateway, S3. Nothing to run, patch, or keep alive.
- Your account, your data — mail, API keys and config live in your AWS account. No third-party SaaS reads, stores, or brokers your email.
- $0/month at idle — send nothing, pay nothing. SES bills strictly per use, and Lambda's always-free tier (1M requests + 400,000 GB-seconds/month) covers the stack at rest.
- Deliverability preserved — SRS-style rewriting keeps SPF/DMARC alignment for your relay domain, and first-hop ARC sealing carries the original authentication results through Gmail/Outlook re-evaluation.
| Typical SaaS email service | 4ward (your AWS account) | |
|---|---|---|
| Cost at idle | Fixed subscription from day one | $0 — pay-per-use only |
| Where your mail lives | Vendor's servers | Your bucket, your functions, your SES identity |
| Control & portability | Vendor terms and export tools | CloudFormation stack in/out, standard AWS primitives |
| Quotas & limits | Vendor plan tiers | SES quotas you can raise yourself (npx 4ward request-production) |
| Lock-in | Proprietary pipeline | Open source, Apache-2.0, auditable end to end |
Comparisons are qualitative on purpose — vendor pricing changes constantly, so check current plans yourself. 4ward's own usage costs are AWS pay-per-use (SES, Lambda, S3, API Gateway), which at low volume stays inside the always-free Lambda tier plus pennies of SES.
npx 4ward init # questionnaire → 4ward.json
npx 4ward deploy # session check → arm64 builds → CloudFormation stack
npx 4ward dns # records to copy (table, --format json|bind)
npx 4ward keys create prod # token → SSM, printed once
npx 4ward status # sandbox? quota? enforcement?
npx 4ward request-production # automated SES production-access request
npx 4ward alias set support@example.com a@x.com,b@x.comNeeds an AWS CLI session with deploy permissions. Local Lambda builds need cargo-lambda + Zig (deploy warns and ships placeholder code without them).
curl -X POST "$API/v1/emails" \
-H "Authorization: Bearer 4w_live_<token>" \
-H 'Content-Type: application/json' -d '{
"from": "Acme <alerts@example.com>",
"to": ["customer@domain.com"],
"reply_to": "support@example.com",
"subject": "System Verification",
"html": "<p>Your code is: <strong>849201</strong></p>",
"text": "Your code is: 849201",
"attachments": [{ "filename": "document.pdf", "content": "<base64>", "content_type": "application/pdf" }]
}'{
"version": "1",
"project": "4ward",
"aws": { "region": "us-east-1", "profile": "default", "stack_name": "4ward-example-com" },
"api": { "enabled": true, "cors": ["*"], "rate_limit": { "requests_per_second": 100, "burst": 200 } },
"settings": { "banner_enabled": true, "retention_days": 1, "sender_format": "{name} (via {alias}) <relay@{domain}>" },
"domains": [
{ "domain": "example.com", "dns_provider": "route53", "catch_all": "me@gmail.com",
"routes": { "support": ["a@x.com", "b@x.com"] } }
]
}"route53" uses your existing hosted zone (auto-detected at deploy; records are printed for you to add); "external" prints the same MX / SPF / 3× DKIM CNAME / DMARC table to copy. Bounce (>5%) and complaint (>0.1%) CloudWatch alarms ship in the stack.
crates/4ward-core config schema + DNS record generation
crates/4ward-cli 4ward binary (embeds templates/template.yaml)
lambdas/forwarder inbound SRS forwarder
lambdas/api outbound API
docs/assets brand crops (lockup, icon) + architecture diagram
bin/run.js npx dispatcher (prebuilt per-platform binary, cargo fallback)
cargo check --workspace --all-targets
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
cargo lambda build --arm64 --release --package lambda-forwarder
cargo lambda build --arm64 --release --package lambda-api
aws cloudformation validate-template --template-body file://crates/4ward-cli/templates/template.yaml