Hey there! 👋 This is a super handy API service that helps you check if an email address is using a disposable/temporary domain. You know those pesky throwaway email addresses that people use to bypass verification? Yeah, we catch those!
- Super Fast Checks: We use Redis caching to make checks lightning fast
- Smart Domain Detection: Can catch similar-looking domains (like
gmaill.com
trying to pose asgmail.com
) - Maintainable Lists: Automatically syncs allowlist and blocklist from GitHub repositories
- Audit Trail: Keeps track of all email checks with IP addresses for security
- API-First: Built with Hono.js for a lightweight but powerful API
First, make sure you have Bun installed (we're using it for that sweet performance). Then:
# Install all the goodies
bun install
# Fire up the development server
bun run dev
The server will start at http://localhost:3000
Create a .env
file with these:
DATABASE_URL=your_postgres_connection_string
REDIS_URL=your_redis_url
BLOCKLIST_URL=github_raw_url_to_blocklist
ALLOWLIST_URL=github_raw_url_to_allowlist
All endpoints are prefixed with: /api.nomorejunk.com
Bearer token authentication is required for all endpoints except /register
and /login
.
Token format: Authorization: Bearer <your_token>
POST /register
Content-Type: application/json
{
"email": "[email protected]",
"password": "your_secure_password"
}
POST /login
Content-Type: application/json
{
"email": "[email protected]",
"password": "your_password"
}
Response:
{
"message": "Login successful",
"token": "your_jwt_token"
}
POST /verify-email
Content-Type: application/json
{
"email": "[email protected]"
}
POST /blocklist
POST /allowlist
Content-Type: application/json
{
"domain": "example.com"
}
DELETE /remove-domain
Content-Type: application/json
{
"domain": "example.com",
"type": "disposable|allowlist"
}
GET /domains?type=disposable|allowlist&page=1&limit=10
GET /sync-domains
POST /refresh-cache
GET /audit-logs/pagination?page=1&limit=10
GET /audit-logs/{email}
// Authentication Success
{
"message": "Login successful",
"token": "jwt_token_here"
}
// Registration Success
{
"message": "Registration successful",
"user": {
"email": "[email protected]"
}
}
// Email Verification Success
{
"status": "success",
"disposable": false,
"reason": "Domain allowlisted",
"domain": "example.com",
"message": "Email address is valid and safe to use"
}
// Domain Operation Success
{
"status": "success",
"message": "Operation completed successfully",
"domain": "example.com",
"type": "disposable|allowlist"
}
// Audit Logs Success
{
"status": "success",
"message": "Audit logs retrieved successfully",
"logs": [
{
"id": "uuid",
"email": "[email protected]",
"domain": "example.com",
"ip": "ip_address",
"action": "action_type",
"timestamp": "timestamp"
}
]
}
{
"status": "error",
"message": "Error description",
"details": "Additional error context", // Only in validation errors
"error": "Detailed error message" // Only in 500 responses
}
Common HTTP Status Codes:
- 200: Success
- 201: Created
- 400: Bad Request
- 401: Unauthorized (Invalid credentials)
- 403: Forbidden (Valid token required)
- 409: Conflict (Resource already exists)
- 500: Internal Server Error
We're using Drizzle ORM with PostgreSQL. To handle database changes:
# Generate migrations
bun run generate
# Push changes to database
bun run db-push
- Runtime: Bun
- Framework: Hono.js
- Database: PostgreSQL with Drizzle ORM
- Cache: Redis
- Language: TypeScript
Feel free to jump in! Whether it's adding features, fixing bugs, or improving docs - all contributions are welcome. Just fork, make your changes, and send a PR.
Check out the source code - I've tried to keep it well-commented and organized. If you're still stuck, feel free to open an issue!
Made with ❤️ to keep email lists clean and genuine