Skip to content

Falakme/mail-relay

Repository files navigation

Mail Relay

A dead simple email relay service with a slick admin dashboard. Built with Next.js and Convex, using Brevo as the primary provider with NotificationAPI as fallback.

Table of Contents

What it does

  • Sends emails reliably via Brevo (with automatic fallback to NotificationAPI if something fails)
  • Tracks every email sent with detailed logs
  • Provides a secure admin dashboard to manage everything
  • API-first design – use it from your own apps or scripts
  • Zero-downtime deployments (uses Convex, not your database)

Stack

  • Next.js 16 with App Router
  • TypeScript (strict mode)
  • Tailwind CSS v4 for styling
  • Convex for the backend (serverless)
  • Brevo + NotificationAPI for email
  • Bun or Node 18+ as runtime

Getting started

Clone and install:

git clone https://github.com/Falakme/mail-relay.git
cd mail-relay
bun install

Set up Convex:

bunx convex dev

Create your config:

cp example.env .env

Fill in your secrets in .env (Brevo API key, NotificationAPI creds, and Convex URL).

Start the dev server:

bun dev

Head to http://localhost:3000 and log in with your SITE_KEY.

Screenshots

Light Mode

Email Logs (Light) API Keys (Light) System Status (Light) Documentation (Light)

Dark Mode

Email Logs (Dark) API Keys (Dark) System Status (Dark) Documentation (Dark)

Configuration

Everything lives in .env. See example.env for a template.

Required:

  • SITE_KEY – Secret key for admin login
  • BREVO_API_KEY – Your Brevo API key
  • NOTIFICATIONAPI_CLIENT_ID & NOTIFICATIONAPI_CLIENT_SECRET – NotificationAPI credentials
  • CONVEX_DEPLOYMENT & NEXT_PUBLIC_CONVEX_URL – Convex setup (auto-generated by bunx convex dev)

Optional:

  • DEFAULT_FROM_EMAIL – Default sender email

API

Send an email

POST /api/send-mail
Authorization: Bearer <your-api-key>
Content-Type: application/json

Body:

{
  "to": "user@example.com",
  "subject": "Hello",
  "body": "Text version",
  "html": "<p>HTML version</p>",
  "from": "sender@example.com",
  "senderName": "My App",
  "replyTo": "reply@example.com"
}

Only to, subject, and body are required.

Get system status

GET /api/status?hours=24

Returns health stats, delivery rates, and provider status.

Admin endpoints

All admin routes require authentication via SITE_KEY:

  • POST /api/auth – Login, logout, check session
  • GET /api/api-keys – List your API keys
  • POST /api/api-keys – Create a new key
  • PUT /api/api-keys – Update a key
  • DELETE /api/api-keys – Delete a key
  • GET /api/logs – View email logs
  • DELETE /api/logs – Delete a log entry

Admin Dashboard

Log in at / with your SITE_KEY. You get:

  • Email Logs – See every email sent, delivery status, any errors
  • API Keys – Create, rotate, disable, and delete keys
  • System Status – Real-time health, delivery metrics, provider limits

Security

  • Admin sessions are HMAC-signed and stored as httpOnly cookies
  • API keys are hashed with SHA256 and never stored in plaintext
  • Bearer tokens work for API access from other services

Testing

bun test
bun test:watch

Project layout

mail-relay/
├── app/
│   ├── (admin)/             # Admin dashboard pages
│   ├── api/                 # API routes
│   ├── page.tsx             # Login page
│   └── globals.css          # Global styles
├── components/              # UI components
├── convex/                  # Database schema + functions
├── lib/                     # Auth, email logic, crypto
├── public/
│   └── screenshots/         # UI screenshots
└── test/                    # Test files

Setting up the providers

Brevo

  1. Sign up at brevo.com
  2. Get a transactional API key
  3. Set BREVO_API_KEY in your .env

NotificationAPI

  1. Create an account at notificationapi.com
  2. Create an email template called email_relay
  3. Add merge tags: {{subject}}, {{body}}, {{html}}
  4. Grab your Client ID and Secret
  5. Set NOTIFICATIONAPI_CLIENT_ID and NOTIFICATIONAPI_CLIENT_SECRET

Deploying

Vercel works great. Just:

  1. Push your code to GitHub
  2. Connect the repo to Vercel
  3. Set all environment variables
  4. Deploy

Or deploy manually:

bun run build
bun run start

Notes

  • Rate limiting is in-memory per provider (resets on restart)
  • Convex handles all persistence – no database setup needed
  • Colors: #000040 (main), #0000C0 (accent)
  • Font: FalakSans

License

MIT – use freely.

About

Serverless email relay with Brevo failover and admin dashboard

Resources

License

Stars

Watchers

Forks

Contributors