# Mail.td API — LLM Reference > Developer email platform. Create email addresses and receive emails via REST API. ## Base URL https://api.mail.td ## Authentication All authenticated requests require: `Authorization: Bearer ` Use a Pro API Token (prefix `td_`, never expires) for all API requests. Sign in with Google or GitHub at https://mail.td/pro/login (first login creates your account). Create tokens in the Pro Dashboard at https://mail.td/pro/dashboard. ## API Pattern All email operations follow: ``` /api/accounts/{account_id}/messages ``` Free and Pro users use the SAME endpoints. The only difference is what accounts a token can access. Note: {account_id} in all paths accepts either a UUID or the full email address (e.g. demo@mail.td). ## Public Endpoints (no auth required) ### List Available Domains GET /api/domains → 200: { "domains": [{ "id": "uuid", "domain": "mail.td", "default": true }] } ## Account Endpoints (auth required) ### Create Account POST /api/accounts Body: { "address": "user@mail.td", "password": "string" } → 201: { "id": "account_id", "address": "user@mail.td" } IMPORTANT: Save the `id` — it is used as {account_id} in all paths below. {account_id} accepts either a UUID or the full email address. ### Get Account Info GET /api/accounts/{account_id} → 200: { "id", "address", "role", "quota", "used", "created_at" } ### Delete Account DELETE /api/accounts/{account_id} → 204 ### Reset Password PUT /api/accounts/{account_id}/reset-password Body: { "password": "newpassword" } → 200: { "message": "password_reset" } ## Message Endpoints (auth required) ### List Messages GET /api/accounts/{account_id}/messages?page=1 → 200: { "messages": [{ "id", "sender", "from", "subject", "preview_text", "size", "is_read", "created_at" }], "page": 1 } Pagination: 30 per page. Fewer than 30 = last page. ### Get Message Detail GET /api/accounts/{account_id}/messages/{id} → 200: { "id", "sender", "from", "subject", "address", "size", "created_at", "text_body", "html_body", "attachments": [{ "index", "filename", "content_type", "size" }] } ### Delete Message DELETE /api/accounts/{account_id}/messages/{id} → 204 ### Download Raw Source (.eml) GET /api/accounts/{account_id}/messages/{id}/source → 200: Content-Type: message/rfc822 ### Download Attachment GET /api/accounts/{account_id}/messages/{id}/attachments/{index} → 200: binary content ### Mark as Read PUT /api/accounts/{account_id}/messages/{id}/read → 204 ### Batch Mark as Read PUT /api/accounts/{account_id}/messages/read Body: { "ids": ["id1", "id2"] } or { "all": true } → 200: { "updated": 5 } ## Pro User Endpoints (Pro auth required) ### Get Pro Profile GET /api/user/me → 200: { "id", "email", "plan", "role", "status", "max_domains", "ops_used", "ops_limit", "domain_count", "created_at", "downgraded" } ### List All Accounts GET /api/user/accounts → 200: { "accounts": [{ "id", "address", "quota", "used", "created_at" }] } ### List Account Messages GET /api/user/accounts/{id}/messages?page=1 → 200: { "messages": [...], "page": 1 } ### Delete Account DELETE /api/user/accounts/{id} → 204 ### Reset Mailbox Password PUT /api/user/accounts/{id}/reset-password Body: { "password": "newpassword" } → 200: { "message": "password_reset" } ### Create API Token POST /api/user/tokens Body: { "name": "my-token" } → 201: { "id", "name", "token": "td_..." } IMPORTANT: Token value is shown only once. ### List API Tokens GET /api/user/tokens → 200: { "tokens": [{ "id", "name", "last_used_at", "created_at" }] } ### Revoke API Token DELETE /api/user/tokens/{id} → 204 ### Add Custom Domain POST /api/user/domains Body: { "domain": "example.com" } → 201: { "id", "domain", "verify_token", "dns_records": [{ "type": "TXT", "host": "_tempmail.example.com", "value": "tempmail-verify=" }, { "type": "MX", "host": "example.com", "value": "smtp.mail.td", "priority": 10 }] } ### List Custom Domains GET /api/user/domains → 200: { "domains": [{ "id", "domain", "verify_status", "verify_token", "mx_configured", "created_at" }] } ### Verify Domain POST /api/user/domains/{id}/verify → 200: { "verify_status": "verified"|"pending", "txt_record": bool, "mx_record": bool } ### Delete Domain DELETE /api/user/domains/{id} → 204 ### Create Webhook POST /api/user/webhooks Body: { "url": "https://example.com/hook", "events": ["email.received"] } → 201: { "id", "url", "events", "secret": "whsec_...", "created_at" } IMPORTANT: Secret is shown only once. ### List Webhooks GET /api/user/webhooks → 200: { "webhooks": [{ "id", "url", "events", "status", "failure_count", "created_at" }] } ### Delete Webhook DELETE /api/user/webhooks/{id} → 204 ### Rotate Webhook Secret POST /api/user/webhooks/{id}/rotate → 200: { "id", "secret": "whsec_..." } ### List Webhook Deliveries GET /api/user/webhooks/{id}/deliveries → 200: { "deliveries": [{ "id", "event_type", "status_code", "error", "attempt", "duration_ms", "created_at" }] } ## SMTP Sandbox (Pro) Capture outgoing emails without delivering to real recipients. SMTP: smtp.mail.td:25, AUTH PLAIN, username: any, password: your API token (td_...) ### Get Sandbox Status GET /api/user/sandbox → 200: { "enabled", "account_id", "address", "smtp_host", "smtp_port", "quota", "used" } ### List Sandbox Messages GET /api/user/sandbox/messages?page=1 → 200: { "messages": [...], "page": 1 } ### Get Sandbox Message GET /api/user/sandbox/messages/{id} → 200: { "id", "sender", "from", "subject", "text_body", "html_body", "attachments": [...] } ### Download Sandbox Message Source GET /api/user/sandbox/messages/{id}/source → 200: Content-Type: message/rfc822 ### Download Sandbox Attachment GET /api/user/sandbox/messages/{id}/attachments/{index} → 200: binary content ### Delete Sandbox Message DELETE /api/user/sandbox/messages/{id} → 200: { "deleted": true } ### Purge All Sandbox Messages DELETE /api/user/sandbox/messages → 200: { "deleted": 42 } ## Rate Limits - Free authenticated: 4 req/s per user - Pro authenticated: 10 req/s per user - Account creation (free): 1 per 8 seconds per user - Account creation (Pro): 1 req/s per user - Pro users have a monthly ops quota (check via GET /api/user/me: ops_used / ops_limit) ## Error Format All errors return: { "error": "error_code", "message": "human-readable description" } Common codes: - 400: invalid_address, invalid_domain, password_too_short - 401: invalid_or_expired_token, account_revoked - 403: access_denied, pro_required, account_limit_reached - 404: not_found - 409: address_taken, domain_already_exists - 410: expired - 429: rate_limit_exceeded, ops_quota_exceeded ## Quick Start Example (Python) ```python from mailtd import MailTD client = MailTD("td_xxxxxxxxxxxxxxxxxxxx") account = client.accounts.create("test@mail.td", password="secret123") messages, page = client.messages.list(account.id) for m in messages: detail = client.messages.get(account.id, m.id) print(detail.subject, detail.text_body) ```