A mock server implementation of the Resend API, useful for testing and development without using the live Resend service.
- API Compatibility: Full REST API compatible with Resend's endpoints
- Email Management: Send, list, track, and cancel emails
- Domain Management: Configure and verify sending domains
- API Keys: Create and manage API keys with granular permissions
- Webhooks: Configure webhooks with delivery tracking and retry logic
- Audiences & Contacts: Manage email lists and subscribers
- Web UI: Optional dashboard for visual management
- Persistence: SQLite database with JSON backup
- Docker Support: Production-ready containerized deployment
# Clone the repository
git clone https://github.com/hongkongkiwi/mock-resend.git
cd mock-resend
# Run with default settings
cargo run
# Server starts at http://localhost:3030cargo run --features web-ui -- --webAccess the web UI at http://localhost:3030
# Build and start
docker-compose up -d
# View logs
docker-compose logs -f
# Stop
docker-compose downEdit config.yaml to customize settings:
server:
host: "0.0.0.0"
port: 3030
cors:
allow_origin: ["*"]
allow_methods: ["*"]
allow_headers: ["*"]
rate_limit:
window_seconds: 60
default_max: 1000
database:
url: "sqlite:./data/mock-resend.db"
max_connections: 10
min_connections: 1
persistence:
enabled: true
file_path: "./data/store.json"
save_interval_seconds: 30
logging:
level: "info"
web_auth:
enabled: falsemock-resend [OPTIONS]
Options:
-c, --config <PATH> Path to config file (default: "config.yaml")
-w, --web Enable web UI
-p, --port <PORT> Port (overrides config)
-h, --host <HOST> Host (overrides config)http://localhost:3030
Most endpoints require a Bearer token:
curl -H "Authorization: Bearer re_test_123" http://localhost:3030/v1/emailsAPI keys follow the format re_<env>_<type>_<random>_<secret>.
| Method | Endpoint | Description |
|---|---|---|
| GET | /health |
Health check |
| GET | /docs |
Swagger UI redirect |
| GET | /docs/openapi.json |
OpenAPI specification |
| Method | Endpoint | Description |
|---|---|---|
| GET | /v1/account |
Get account information |
| Method | Endpoint | Description |
|---|---|---|
| POST | /v1/emails |
Send an email |
| GET | /v1/emails |
List all emails |
| GET | /v1/emails/:id |
Get email details |
| PATCH | /v1/emails/:id |
Update email |
| POST | /v1/emails/:id/cancel |
Cancel pending email |
| POST | /v1/batch |
Send batch emails |
Example: Send an email
curl -X POST http://localhost:3030/v1/emails \
-H "Authorization: Bearer re_test_123" \
-H "Content-Type: application/json" \
-d '{
"from": "[email protected]",
"to": ["[email protected]"],
"subject": "Hello World",
"html": "<p>Welcome!</p>"
}'| Method | Endpoint | Description |
|---|---|---|
| GET | /v1/api-keys |
List API keys |
| POST | /v1/api-keys |
Create API key |
| DELETE | /v1/api-keys/:id |
Delete API key |
| POST | /v1/api-keys/verify |
Verify API key |
| Method | Endpoint | Description |
|---|---|---|
| GET | /v1/domains |
List domains |
| POST | /v1/domains |
Create domain |
| GET | /v1/domains/:id |
Get domain details |
| DELETE | /v1/domains/:id |
Delete domain |
| GET | /v1/domains/:id/records |
Get DNS records |
| POST | /v1/domains/:id/verify |
Verify domain |
| Method | Endpoint | Description |
|---|---|---|
| GET | /v1/audiences |
List audiences |
| POST | /v1/audiences |
Create audience |
| GET | /v1/audiences/:id |
Get audience |
| DELETE | /v1/audiences/:id |
Delete audience |
| GET | /v1/audiences/:id/members |
List audience members |
| POST | /v1/audiences/:id/members |
Add audience member |
| GET | /v1/contacts |
List contacts |
| POST | /v1/contacts |
Create contact |
| Method | Endpoint | Description |
|---|---|---|
| GET | /v1/webhooks |
List webhook configs |
| POST | /v1/webhooks |
Create webhook |
| GET | /v1/webhooks/:id |
Get webhook |
| PATCH | /v1/webhooks/:id |
Update webhook |
| DELETE | /v1/webhooks/:id |
Delete webhook |
| GET | /v1/webhook-deliveries |
List deliveries |
| POST | /v1/webhook-deliveries/:id/retry |
Retry delivery |
| POST | /v1/webhooks/simulate |
Simulate webhook event |
Webhook Event Types:
email.sentemail.deliveredemail.bouncedemail.complainedemail.openedemail.clicked
| Method | Endpoint | Description |
|---|---|---|
| GET | /v1/stats |
Get sending statistics |
| Method | Endpoint | Description |
|---|---|---|
| POST | /_internal/reset |
Reset all data |
The optional web UI provides a visual interface for managing your mock Resend instance.
| Route | Description |
|---|---|
/ |
Dashboard with stats overview |
/emails |
View and send emails |
/domains |
Manage domains |
/api-keys |
Manage API keys |
/webhooks |
Configure and monitor webhooks |
/audiences |
Manage audience lists |
The UI includes reusable components:
- Sidebar - Navigation menu
- Header - Page headers with actions
- Card - Content containers
- Table - Sortable data tables
- Modal - Dialog forms
- ToastContainer - Notifications
# Build with web UI
cargo leptos build --features web-uimock-resend/
├── Cargo.toml # Rust dependencies
├── config.yaml # Configuration file
├── Dockerfile # Container definition
├── docker-compose.yml # Docker services
├── leptos.toml # Leptos configuration
│
├── src/
│ ├── main.rs # Entry point
│ ├── models.rs # Data models
│ ├── middleware.rs # Auth & rate limiting
│ ├── persistence.rs # JSON file persistence
│ ├── openapi.rs # OpenAPI specification
│ │
│ ├── db/
│ │ ├── mod.rs # Database setup
│ │ └── entities/ # SQLx entities
│ │ ├── email.rs
│ │ ├── domain.rs
│ │ ├── api_key.rs
│ │ ├── webhook_config.rs
│ │ └── ...
│ │
│ ├── routes/
│ │ ├── mod.rs # Route definitions
│ │ ├── emails.rs # Email endpoints
│ │ ├── domains.rs # Domain endpoints
│ │ ├── webhooks.rs # Webhook endpoints
│ │ ├── account.rs # Account endpoints
│ │ └── web_ui.rs # Web UI routes
│ │
│ └── web/ # Web UI (optional)
│ ├── app.rs
│ ├── auth.rs
│ ├── components/
│ │ ├── button.rs
│ │ ├── card.rs
│ │ ├── modal.rs
│ │ ├── table.rs
│ │ └── ...
│ └── pages/
│ ├── dashboard.rs
│ ├── emails.rs
│ ├── domains.rs
│ └── ...
│
├── data/ # Data storage
│ └── store.json # JSON backup
│
└── tests/
└── integration_test.rs # Integration tests
# Run all tests
cargo test
# Run with verbose output
cargo test -- --nocapture- Define models in
src/models.rs - Create database entities in
src/db/entities/ - Add route handlers in appropriate
src/routes/*.rs - Register route in
src/routes/mod.rs - Update OpenAPI spec in
src/openapi.rs
# Run migrations
cargo run --migrateThe application supports two persistence mechanisms:
- SQLite Database - Primary storage using SQLx
- JSON Backup - Automatic periodic backup to
data/store.json
Both are kept in sync automatically.
# Build image
docker build -t mock-resend .
# Run container
docker run -p 3030:3030 \
-v $(pwd)/data:/data \
-v $(pwd)/config.yaml:/data/config.yaml:ro \
mock-resend| Variable | Description |
|---|---|
RUST_LOG |
Logging level (info, debug, warn, error) |
DATABASE_URL |
Override database connection string |
# Find process using port 3030
lsof -i :3030
# Kill the process
kill <PID>If using SQLite, ensure no other processes are accessing the database file.
Ensure you built with the web-ui feature:
cargo run --features web-ui -- --webMIT License - see LICENSE file for details.
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests:
cargo test - Submit a pull request
Mock Resend is not affiliated with, endorsed by, or sponsored by Resend Inc. This project provides a mock implementation for testing purposes.