DEVELOPER PLATFORM

JoyMail REST API

Automate temporary disposable inboxes for end-to-end testing (Playwright, Cypress), CI/CD pipelines, OTP verification codes, and automated bot integrations on Cloudflare's global edge network.

PUBLIC
Zero Auth Required
Fetch and query inboxes instantly with the public endpoint without API keys or accounts.
🌐 GLOBAL
Cloudflare Edge KV
Sub-millisecond read latency worldwide with automatic native TTL expiration.
🔒 V1 AUTH
Granular v1 API
Bearer token secured endpoints for programmatic deletion and parsed attachment manifests.

Base URL & Environment

All API requests should be addressed to the production server root or your local development instance:

EnvironmentBase URLDescription
Productionhttps://tmail.mhankbarbar.devCloudflare Global Edge Network
Developmenthttp://localhost:5173Local SvelteKit development server
💡
JSON Standard: All response bodies are formatted as UTF-8 application/json. Standard HTTP response codes indicate request outcome.

Authentication

JoyMail offers two access tiers:

Tier 1: Public

No Authentication

Endpoints under /api/inbox/:address and /api/domains can be queried directly without headers or registration.

Tier 2: Authenticated (v1)

Bearer API Key

Endpoints under /api/v1/* require a Bearer token supplied in the standard HTTP header:

Authorization: Bearer YOUR_API_KEY

GET /api/inbox/{address}
Public • No Auth

Retrieve all incoming emails received by a given address. Results are sorted by sent_at descending (newest first).

PATH PARAMETERS
address string required
Full email address (e.g. demo@mhankbarbar.dev).
curl -s "https://tmail.mhankbarbar.dev/api/inbox/demo@mhankbarbar.dev"
RESPONSE: 200 OK
{
  "emails": [
    {
      "id": "1788604492961-uu13nmj",
      "to": "demo@mhankbarbar.dev",
      "from": "verify@service.com",
      "subject": "Your Login Verification Code: 489102",
      "text": "Hello! Your one-time verification code is 489102. Valid for 10 minutes.",
      "html": "<div style=\"font-family:sans-serif;\"><h2>489102</h2></div>",
      "sent_at": "2026-09-05T10:34:52.000Z"
    }
  ]
}
GET /api/domains
Public • No Auth

Returns the currently active custom domains accepted by JoyMail, along with the configured Cloudflare MX host.

curl -s "https://tmail.mhankbarbar.dev/api/domains"
RESPONSE: 200 OK
{
  "enabled": true,
  "customDomains": [
    "mhankbarbar.dev",
    "inbox.example.org"
  ],
  "mxHost": "mx.mhankbarbar.dev"
}
POST /api/domains
Public (Limit: 10/hr)

Register a custom domain, re-check DNS MX verification via DNS-over-HTTPS (DoH), or remove pending domain registrations.

REQUEST BODY (JSON)
action "add" | "check" | "remove" required
Operation to execute on the custom domain.
domain string required
FQDN of your custom domain (e.g. mycustominbox.com).
curl -s -X POST "https://tmail.mhankbarbar.dev/api/domains" \
  -H "Content-Type: application/json" \
  -d '{"action": "add", "domain": "mycustominbox.com"}'
RESPONSE: 200 OK
{
  "domain": "mycustominbox.com",
  "status": "pending",
  "mxHost": "mx.mhankbarbar.dev",
  "message": "MX record not detected yet. DNS changes can take a few minutes to propagate."
}

GET /api/v1/inbox/{address}
Bearer Token Required

Retrieve inbox emails with total counter. Requires a valid API key passed in the Authorization: Bearer header.

curl -s "https://tmail.mhankbarbar.dev/api/v1/inbox/demo@mhankbarbar.dev" \
  -H "Authorization: Bearer YOUR_API_KEY"
RESPONSE: 200 OK
{
  "emails": [
    {
      "id": "1788604492961-uu13nmj",
      "to": "demo@mhankbarbar.dev",
      "from": "notifications@github.com",
      "subject": "[GitHub] Security alert detected",
      "sent_at": "2026-09-05T11:20:15.000Z"
    }
  ],
  "count": 1
}
GET /api/v1/inbox/{address}/{id}
Bearer Token Required

Fetch complete details of an individual email, including parsed HTML, plaintext body, recipient headers, and attachment manifest.

curl -s "https://tmail.mhankbarbar.dev/api/v1/inbox/demo@mhankbarbar.dev/1788604492961-uu13nmj" \
  -H "Authorization: Bearer YOUR_API_KEY"
RESPONSE: 200 OK
{
  "email": {
    "id": "1788604492961-uu13nmj",
    "to": "demo@mhankbarbar.dev",
    "from": "noreply@bank.com",
    "subject": "Statement for September 2026",
    "text": "Please find attached your account statement.",
    "html": "<p>Please find attached your account statement.</p>",
    "sent_at": "2026-09-05T11:20:15.000Z",
    "attachments": [
      {
        "filename": "statement.pdf",
        "mimeType": "application/pdf",
        "size": 42080
      }
    ]
  }
}
DEL /api/v1/inbox/{address}/{id}
Bearer Token Required

Permanently delete an email message from the Cloudflare KV store.

curl -s -X DELETE "https://tmail.mhankbarbar.dev/api/v1/inbox/demo@mhankbarbar.dev/1788604492961-uu13nmj" \
  -H "Authorization: Bearer YOUR_API_KEY"
RESPONSE: 200 OK
{
  "success": true,
  "message": "Email deleted"
}

Rate Limits & Retention Policy

To ensure system stability across Cloudflare Worker Free and Paid tiers:

  • Dual Storage Architecture (D1 + KV): JoyMail natively supports both Cloudflare D1 SQL Database (100,000 writes/day free limit) and Cloudflare KV (1,000 writes/day free limit) with seamless auto-detection and fallback.
  • Public Inbox Polling: We recommend a polling frequency of 3–5 seconds when awaiting verification emails. For continuous listening, use JoyMail's built-in 10-second auto-refresh.
  • Custom Domain Registrations: Limited to 10 domain additions per IP per hour to mitigate abuse.
  • Configurable Retention (1 – 30 Days): Email retention is fully configurable in your Admin Settings (from 1 day up to 30 days). Expired messages are automatically and permanently purged via native Cloudflare KV TTL or daily scheduled background cron on Cloudflare D1.

HTTP Error Reference

CodeStatusDescription
200OKThe request succeeded.
400Bad RequestInvalid domain, malformed JSON payload, or unsupported action.
401UnauthorizedMissing or invalid Authorization: Bearer <KEY> token.
404Not FoundTarget email ID or custom domain does not exist.
429Too Many RequestsExceeded rate limit for custom domain additions.
500Internal Server ErrorCloudflare KV storage or server binding temporarily unavailable.