Skip to content

Quick Start

Get up and running with Mail.td API in under a minute. No API key required.

Base URL

https://api.mail.td

Unified API

Free and Pro users use the same endpoints. The only difference is what your token can access.

GET  /api/domains                              → pick a domain
GET  /api/challenge                            → get PoW challenge (free users)
POST /api/accounts                             → create account, get token + account_id
GET  /api/accounts/{account_id}/messages       → read emails

TIP

Pro users get higher rate limits, custom domains, webhooks, and multi-account management — but the core email API is identical.


Step 1: Get Available Domains

bash
curl https://api.mail.td/api/domains
json
{
  "domains": [
    { "id": "...", "domain": "mail.td", "default": true, "sort_order": 0 },
    { "id": "...", "domain": "fexbox.org", "default": false, "sort_order": 1 }
  ]
}

Step 2: Solve PoW Challenge (Free Users)

Free users must solve a proof-of-work challenge before creating an account. Pro users with an API token can skip this step.

bash
curl https://api.mail.td/api/challenge
json
{
  "id": "a1b2c3d4...",
  "salt": "e5f6a7b8...",
  "difficulty": 20,
  "expires_at": 1700000000
}

Find a nonce such that SHA-256(salt + nonce) has at least difficulty leading zero bits, then include the solution in the next step.

Step 3: Create an Account

bash
curl -X POST https://api.mail.td/api/accounts \
  -H "Content-Type: application/json" \
  -d '{
    "address": "demo@mail.td",
    "password": "supersecret",
    "pow": { "id": "a1b2c3d4...", "nonce": "00000abc..." }
  }'
json
{
  "id": "a1b2c3d4-e5f6-7890-abcd-1234567890ab",
  "address": "demo@mail.td",
  "token": "eyJhbGciOiJIUzI1NiIs..."
}

INFO

Save both id (account ID) and token. The id is used as {account_id} in all subsequent API calls.

Step 4: Fetch Messages

Use the token and account ID to list and read emails:

bash
# List messages
curl https://api.mail.td/api/accounts/a1b2c3d4-e5f6-7890-abcd-1234567890ab/messages \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

# Read a specific message
curl https://api.mail.td/api/accounts/a1b2c3d4-e5f6-7890-abcd-1234567890ab/messages/f5e6d7c8-... \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
json
{
  "id": "f5e6d7c8-...",
  "sender": "noreply@example.com",
  "from": "Example <noreply@example.com>",
  "subject": "Verify your email",
  "address": "demo@mail.td",
  "size": 4523,
  "created_at": "2025-01-15T10:30:00Z",
  "text_body": "Click the link below to verify your email...",
  "html_body": "<html>...</html>",
  "attachments": []
}

That's it — three steps, zero setup.

Code Examples

Python

python
import hashlib
import requests

API = "https://api.mail.td/api"

# 1. Get PoW challenge
challenge = requests.get(f"{API}/challenge").json()

# 2. Solve PoW (find nonce where SHA-256(salt+nonce) has N leading zero bits)
def solve_pow(salt, difficulty):
    target = difficulty
    nonce = 0
    while True:
        hash_input = salt + str(nonce)
        hash_bytes = hashlib.sha256(hash_input.encode()).digest()
        bits = int.from_bytes(hash_bytes[:4], "big")
        if bits >> (32 - target) == 0:
            return str(nonce)
        nonce += 1

nonce = solve_pow(challenge["salt"], challenge["difficulty"])

# 3. Create account with PoW solution
r = requests.post(f"{API}/accounts", json={
    "address": "demo@mail.td",
    "password": "supersecret",
    "pow": {"id": challenge["id"], "nonce": nonce}
})
data = r.json()
token = data["token"]
account_id = data["id"]

# 4. Fetch messages
headers = {"Authorization": f"Bearer {token}"}
messages = requests.get(f"{API}/accounts/{account_id}/messages", headers=headers).json()

for msg in messages["messages"]:
    print(f"{msg['from']}: {msg['subject']}")
    detail = requests.get(
        f"{API}/accounts/{account_id}/messages/{msg['id']}", headers=headers
    ).json()
    print(detail["text_body"])

JavaScript (Node.js)

javascript
import { createHash } from "crypto";

const API = "https://api.mail.td/api";

// 1. Get PoW challenge
const challenge = await (await fetch(`${API}/challenge`)).json();

// 2. Solve PoW
function solvePow(salt, difficulty) {
  for (let nonce = 0; ; nonce++) {
    const hash = createHash("sha256").update(salt + nonce).digest();
    if (hash.readUInt32BE(0) >>> (32 - difficulty) === 0) return String(nonce);
  }
}

const nonce = solvePow(challenge.salt, challenge.difficulty);

// 3. Create account with PoW solution
const res = await fetch(`${API}/accounts`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    address: "demo@mail.td",
    password: "supersecret",
    pow: { id: challenge.id, nonce },
  }),
});
const { id: accountId, token } = await res.json();

// 4. Fetch messages
const headers = { Authorization: `Bearer ${token}` };
const { messages } = await (
  await fetch(`${API}/accounts/${accountId}/messages`, { headers })
).json();

for (const msg of messages) {
  console.log(`${msg.from}: ${msg.subject}`);
  const detail = await (
    await fetch(`${API}/accounts/${accountId}/messages/${msg.id}`, { headers })
  ).json();
  console.log(detail.text_body);
}

What's Next?

Mail.td API Documentation