self-hosted REST API to automatically create temporary email addresses on your own domain using Cloudflare, with optional expiry.
This API allows you to quickly generate temporary email forwarding rules on your Cloudflare-managed domain. You can optionally set an expiry time (minimum 5 minutes), after which the email rule will be automatically deleted by a background cleanup job.
- Docker installed.
- A domain name managed by Cloudflare.
- Cloudflare Email Routing configured and enabled for your domain.
-
Clone the repository and navigate into the directory:
git clone https://github.com/nocdn/vanish.git cd cloudflare-temp-mail/ -
Create the
.envfile: Copy the example file:cp .env.example .env
Edit the
.envfile and fill in your details:CLOUDFLARE_API_TOKEN: Your Cloudflare API Token (see instructions below).CLOUDFLARE_ZONE_ID: Your Cloudflare Zone ID for the domain (see instructions below).DOMAIN_NAME: The domain you own and want to use to create the temporary addresses on (e.g.,example.com).DESTINATION_EMAIL: The real email address where temporary emails should be forwarded.- (Optional)
FLASK_DEBUGandFLASK_RUN_PORTif you need to change defaults.
-
Get Cloudflare Credentials:
- API Token (
CLOUDFLARE_API_TOKEN):- Go to your Cloudflare dashboard -> My Profile -> API Tokens.
- Click "Create Token".
- Find the "Custom token" template and click "Get started".
- Give the token a name (e.g.,
vanish-api). - Set the following Permissions:
Zone-Email Routing-Edit
- Set the Zone Resources:
Include-Specific Zone- Select yourDOMAIN_NAME.
- Click "Continue to summary", then "Create Token".
- Copy the generated token immediately and paste it into your
.envfile. You won't see it again.
- Zone ID (
CLOUDFLARE_ZONE_ID):- Go to your Cloudflare dashboard.
- Select your
DOMAIN_NAME. - On the Overview page for the domain, find the "Zone ID" on the right-hand side and copy it into your
.envfile.
- API Token (
Important
You must verify your DESTINATION_EMAIL with Cloudflare first as a Destination Address in your Cloudflare Email Routing settings before the API can create rules forwarding to it.
-
Create Data Directory: This directory will store the persistent SQLite database for tracking email expiry. Create it in your project root (same level as the
.envfile):mkdir data
Important
For security reasons, never run this Docker command as root on your host system. If you're currently logged in as root:
- Create a regular user account:
adduser myuser- Add the user to the docker group:
usermod -aG docker myuser- Switch to that user:
su - myuser- Navigate back to your project directory and continue with the build steps below.
Build and Run the Docker Container:
This command builds the image (vanish-img) and then runs it in detached mode (-d), mapping port 6020, loading your .env file, mounting the local ./data directory for database persistence, and naming the container. The --restart=always flag ensures the container restarts automatically if stopped.
docker build -t vanish-img . && \
docker run -d \
--restart=always \
-p 6020:6020 \
--env-file .env \
-v "$(pwd)/data":/app/data \
--name vanish \
vanish-img
```
The API should now be running and accessible at `http://<your_server_ip>:6020`.
### Usage
The API provides the following endpoints:
**Generate an email address:**
Without expiry or comment:
```bash
curl http://localhost:6020/generateWith comment:
curl "http://localhost:6020/generate?comment=test"With expiry (e.g., 1 hour, 2 days, 30 minutes). Minimum expiry is 5 minute.
# Expires in 1 hour
curl "http://localhost:6020/generate?expiry=1h"
# Expires in 2 days
curl "http://localhost:6020/generate?expiry=2d"
# Expires in 30 minutes
curl "http://localhost:6020/generate?expiry=30m"
# Error - Too short
curl "http://localhost:6020/generate?expiry=1m"Successful Response (200 OK):
{
"comment": "test",
"email": "[email protected]",
"expires_at": "2025-04-06T12:30:00.123456+00:00" // or null if no expiry
}Error Response (e.g., 400 Bad Request for invalid expiry):
{
"error": "Minimum expiry duration is 10 minutes. Requested: '5m'"
}List all generated email addresses (created by this API instance):
curl http://localhost:6020/listResponse (200 OK):
{
"generated_emails": [
{
"email": "[email protected]",
"comment": "test"
},
{
"email": "[email protected]",
"comment": "none"
}
]
}Delete an email address rule:
curl -X DELETE http://localhost:6020/remove/[email protected]Successful Response (200 OK):
{
"message": "Successfully removed rule for [email protected]"
}Error Response (e.g., 404 Not Found):
{
"error": "Rule for email [email protected] not found"
}Health Check:
curl http://localhost:6020/healthResponse (200 OK):
{
"status": "healthy"
}Automatic Cleanup: A background job runs every 5 minutes (by default) inside the container to check for emails in the local database that have passed their expiry time. If found, it attempts to delete the corresponding rule from Cloudflare and removes the entry from the database.
- Python 3.10+
pipandvenv
-
Clone & Setup
.env: Follow steps 1 & 2 from the Docker deployment instructions (clone repo, create and fill.env). Also get your Cloudflare credentials as described above. -
Create Virtual Environment & Install Dependencies:
python -m venv venv source venv/bin/activate # on Windows use `venv\Scripts\activate` pip install -r requirements.txt
-
Create Data Directory: The local database will be stored here.
mkdir data
-
Run the API:
python app.py
The API will run directly on your machine, accessible at
http://localhost:6020(or the port specified in.env). Theemails.dbfile will be created inside the./datadirectory.
This project is licensed under the MIT License - see the LICENSE file for details.
You can spin up the API on the free Render tier in seconds:
The button imports the project, builds the Docker image using the provided Dockerfile, and provisions a web service. After the deploy completes go to Environment → Add Environment Variable and enter the values from your .env file (CLOUDFLARE_API_TOKEN, CLOUDFLARE_ZONE_ID, DOMAIN_NAME, DESTINATION_EMAIL, etc.).
Render automatically maps the internal port 6020 to an external URL, and the health-check is wired to /health.