Documentation

API reference and setup guide for mailer.khalid.id — a receive-only temp mail service.

SetupAPI ReferenceSMTPRetentionExamples

Setup

DNS Configuration

Add an MX record pointing your domain to mailer.khalid.id:

Type:     MX
Host:     @            (apex domain)
Priority: 10
Value:    mailer.khalid.id

For wildcard support (catch-all on any subdomain), add a second record:

Host:     *
Priority: 10
Value:    mailer.khalid.id

Steps

  1. Add the MX record in your DNS provider
  2. Wait for propagation (usually seconds, up to 48h)
  3. On the Claim page, enter your domain and click Check MX
  4. Click Claim domain to get your API key
  5. Save the API key — it's shown only once
Cloudflare users: MX records must use DNS Only mode (gray cloud). Cloudflare's proxy does not support MX traffic.

API Reference

Base URL: https://mailer.khalid.id/api/v1

Authentication

Pass your API key in the X-API-Key header or as Authorization: Bearer <key>. Public endpoints don't need auth.

Pagination

List endpoints accept ?limit=N&offset=M. Default limit is 50, max 200.

Public Endpoints

GET/healthz
Health check. Returns 200 if the server is up.
GET/api/v1/meta
Server metadata (hostname, version).
Response
{
  "success": true,
  "data": {
    "hostname": "mailer.khalid.id",
    "version": "1.0.0"
  }
}
GET/api/v1/stats
Mail statistics.
Response
{
  "success": true,
  "data": {
    "today_count": 42,
    "total": 1337,
    "live_count": 5,
    "top_headers": [
      { "address": "test@example.com", "count": 12 }
    ]
  }
}
POST/api/v1/domains/verify
Check if a domain's MX records point to mailer.khalid.id.
Request body
{ "domain": "example.com" }
Response
{
  "success": true,
  "data": { "verified": true }
}
POST/api/v1/domains
Claim a domain and receive an API key. Domain must have valid MX records.
Request body
{ "domain": "example.com" }
// or for wildcard:
{ "domain": "*.example.com" }
Response
{
  "success": true,
  "data": {
    "domain": "example.com",
    "api_key": "tm_abc123...",
    "wildcard": false
  }
}

Authenticated Endpoints

GET/api/v1/domainsAUTH
List domains owned by your API key.
Response
{
  "success": true,
  "data": [
    { "domain": "example.com", "wildcard": false }
  ]
}
GET/api/v1/mailboxesAUTH
List all mailboxes across your domains.
Response
{
  "success": true,
  "data": [
    {
      "address": "test@example.com",
      "local_part": "test",
      "domain": "example.com"
    }
  ]
}
POST/api/v1/mailboxesAUTH
Create a mailbox. Omit local_part for a random address.
Request body
{ "local_part": "hello", "domain": "example.com" }
// or random:
{ "domain": "example.com" }
Response
{
  "success": true,
  "data": {
    "address": "hello@example.com",
    "local_part": "hello",
    "domain": "example.com"
  }
}
DELETE/api/v1/mailboxes/:addressAUTH
Delete a mailbox and all its messages.
GET/api/v1/mailboxes/:address/messagesAUTH
List messages for a mailbox. Supports ?limit=N&offset=M.
Response
{
  "success": true,
  "data": [
    {
      "id": 1,
      "from_addr": "sender@other.com",
      "to_addr": "test@example.com",
      "subject": "Hello",
      "created_at": "2025-01-15T10:30:00Z"
    }
  ]
}
GET/api/v1/messages/:idAUTH
Get a single message with full body.
Response
{
  "success": true,
  "data": {
    "id": 1,
    "from_addr": "sender@other.com",
    "to_addr": "test@example.com",
    "subject": "Hello",
    "body_text": "Plain text body",
    "body_html": "<p>HTML body</p>",
    "created_at": "2025-01-15T10:30:00Z"
  }
}
DELETE/api/v1/messages/:idAUTH
Delete a single message.

SMTP

The SMTP server listens on port 25 at mailer.khalid.id. It is receive-only — you cannot send outbound mail through it.

When a message arrives for a known domain, the server automatically creates a mailbox if one doesn't exist yet. Max message size is 10 MB.

Retention

  • Messages are deleted after 1 hour
  • Cleanup runs every 5 minutes
  • Stats (counts) are permanent

Examples

Claim a domain

curl -X POST https://mailer.khalid.id/api/v1/domains \
  -H 'Content-Type: application/json' \
  -d '{"domain": "example.com"}'

Create a mailbox

curl -X POST https://mailer.khalid.id/api/v1/mailboxes \
  -H 'X-API-Key: tm_your_key_here' \
  -H 'Content-Type: application/json' \
  -d '{"local_part": "hello", "domain": "example.com"}'

Create a random mailbox

curl -X POST https://mailer.khalid.id/api/v1/mailboxes \
  -H 'X-API-Key: tm_your_key_here' \
  -H 'Content-Type: application/json' \
  -d '{"domain": "example.com"}'

List mailboxes

curl https://mailer.khalid.id/api/v1/mailboxes \
  -H 'X-API-Key: tm_your_key_here'

List messages

curl 'https://mailer.khalid.id/api/v1/mailboxes/hello@example.com/messages?limit=10' \
  -H 'X-API-Key: tm_your_key_here'

Read a message

curl https://mailer.khalid.id/api/v1/messages/1 \
  -H 'X-API-Key: tm_your_key_here'

Delete a message

curl -X DELETE https://mailer.khalid.id/api/v1/messages/1 \
  -H 'X-API-Key: tm_your_key_here'