A FastAPI email gateway with API key authentication, per-key daily limits, and async Gmail SMTP delivery.
- API key authentication with bcrypt/PBKDF2 hashing
- Per-key daily send limits enforced with atomic PostgreSQL operations
- Rate limiting (thread-safe, 429 responses when exceeded)
- Async SMTP delivery via aiosmtplib with TLS support
- Healthcheck endpoint and Prometheus metrics at
/metrics - Alembic migrations for schema management
cp .env.example .env
# fill in SMTP_* and DATABASE_URL in .env
docker compose up -d
# create an API key
docker compose exec app python create_api_key.py
# send an email
curl -X POST http://localhost:8000/api/v1/send \
-H "X-API-Key: <your_key>" \
-H "Content-Type: application/json" \
-d '{
"to": "recipient@example.com",
"subject": "Hello",
"html_body": "<p>Hello</p>",
"text_body": "Hello"
}'POST /api/v1/send
X-API-Key: <key>
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
to |
string | yes | Recipient address |
subject |
string | yes | Email subject |
html_body |
string | yes | HTML content |
text_body |
string | no | Plain text fallback |
headers |
object | no | Additional SMTP headers |
Responses: 202 Accepted / 401 Unauthorized / 429 Too Many Requests / 422 Unprocessable Entity
| Endpoint | Description |
|---|---|
GET /health |
Healthcheck (returns service status) |
GET /metrics |
Prometheus metrics |
GET /docs |
Swagger UI |
GET /redoc |
ReDoc |
Copy .env.example to .env and set the following:
# Database
DATABASE_URL=postgresql://teachme:securepassword@localhost:15432/mailgateway
# SMTP (Gmail example)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=your-email@gmail.com
SMTP_PASSWORD=your-app-password
SMTP_FROM_ADDRESS=your-email@gmail.com
# Security
CORS_ORIGINS=["http://localhost:3000"]
MAX_REQUEST_SIZE=262144
# Admin UI (optional — BasicAuth or header key)
ADMIN_USERNAME=admin
ADMIN_PASSWORD=changeme
# ADMIN_API_KEY=some-secret-value
# Observability
LOG_LEVEL=INFO
SENTRY_DSN= # optional; leave empty to disable Sentry
# Development
DEBUG=truehttp_requests_total— requests by endpoint and statusemail_sends_total— delivery attempts and outcomesrate_limit_hits_total— rate limiting eventssmtp_connection_duration_seconds— SMTP latency
MIT — see LICENSE.