# Mail Hub — Temporary Email Aggregation API > Version: 0.10.1 | Base URL: https://claude.111316.xyz Mail Hub is a multi-provider temporary/disposable email aggregation service. It creates inboxes from multiple email providers, polls for incoming messages, and extracts verification codes — all through a unified REST API. ## Authentication All /api/* endpoints require a Bearer token in the Authorization header: Authorization: Bearer ## ⚠️ CRITICAL: Two Mandatory Requirements ⚠️ ### 1. Always provide the target service domain ("for") When creating an inbox, you MUST include the "for" field with the target service's domain name (e.g. "twitter.com", "discord.com"). This is essential for statistics, management, smart routing, and avoiding blocked domains. Do NOT omit this field. ### 2. Always report results after use After you finish using an inbox (whether the email arrived successfully or not), you MUST call POST /api/inbox/:id/report to report the outcome. This is NOT optional. The reporting mechanism is the backbone of service quality: - It tracks provider reliability (success/failure statistics) - It helps the operator identify unreliable providers and domains - It prevents Outlook pool accounts from being reused for the same service Failing to report results degrades the service for everyone. ALWAYS report. ## Typical Workflow 1. POST /api/inbox → Create a temporary inbox 2. GET /api/inbox/:id/code → Wait for & extract verification code (recommended) — OR — GET /api/inbox/:id/messages → Poll for raw messages 3. POST /api/inbox/:id/report → ⚠️ REPORT the result (MANDATORY!) 4. DELETE /api/inbox/:id → Close the inbox when done ## Endpoints ### POST /api/inbox Create a new temporary inbox. Request body (JSON): { "for": "twitter.com", // ⚠️ REQUIRED — target service domain for routing & statistics "provider": "mailtm", // (optional) force a specific provider "domain": "example.com", // (optional) request a specific email domain "subdomain": "team-a", // (optional) wildcard child domain prefix (YYDS provider only) "account": "me@icloud.com", // (optional) which pooled account to draw from (iCloud provider only) "alias": true, // (optional) ask for a sub-address — see "Aliases" below "duration": 600, // (optional) desired lifetime in seconds "needPolling": true // (optional, default true) whether inbox must support polling } Response 201: { "id": "abc123", "address": "random@tmpmail.org", "provider": "mailtm", "expiresAt": "2025-01-01T01:00:00Z", // always set; defaults to 24h when neither provider nor "duration" specify one "features": { "pollInbox": true, "attachments": false, ... } } ⚠️ The "for" field MUST be the target service's domain name (e.g. "twitter.com", "discord.com", "steam.com"). It is used for: - Avoiding domains already blocked by that service - Preventing Outlook accounts from being reused for the same service (unless "alias" is set — see below) - Statistics and management tracking by the service operator Do NOT omit this field. The service operator requires it for management purposes. #### Aliases ("alias": true) Asks for a sub-address instead of the plain one. The tag is generated server-side — do NOT try to supply it. Only providers advertising "features.alias" honour it (currently Outlook, which returns account+tag@outlook.com); others ignore it silently, so with auto-dispatch you may still receive a plain address. Always read "address" from the response. Normally one Outlook account is handed to a given "for" service only once. An aliased request bypasses that limit, so the same account can register at the same service repeatedly, each time with a fresh address. Two things to know: - Many signup forms reject addresses containing "+". This is why the flag is opt-in per request rather than always on — use it only for services you know accept sub-addressing. - An alias is a different address, NOT extra capacity: the inbox still holds one pooled account, so repeat registrations are sequential. Close the current inbox before creating the next one. ### GET /api/inboxes List your inboxes. Query parameters: ?status=active|closed — filter by status ?provider=mailtm — filter by provider ?for=twitter — filter by target service Response 200: { "inboxes": [ { "id", "provider", "address", "target_service", "created_at", "expires_at", "status" }, ... ] } ### GET /api/inbox/:id/messages Poll the inbox for messages. Response 200: { "messages": [ { "id", "from", "subject", "excerpt", "receivedAt" }, ... ] } ### GET /api/inbox/:id/messages/:mid Get full message content. Response 200: { "id", "from", "subject", "excerpt", "receivedAt", "text": "...", "html": "..." } ### GET /api/inbox/:id/code Extract verification codes from the latest email. Supports long-polling. Query parameters: ?wait=true — long-poll until a message arrives (recommended) ?timeout=60 — max wait time in seconds (default 60, max 120) ?type=numeric — filter code type (numeric, alphanumeric, link) ?since=ISO_TIME — only consider messages received after this timestamp Response 200: { "codes": [ { "code": "123456", "type": "numeric", "source": "body", "context": "verification code" } ], "email": { "from": "noreply@service.com", "subject": "Your code" }, "messageId": "message-123", "receivedAt": "2025-01-01T00:01:00Z" } This is the recommended endpoint for most use cases — it handles polling, message retrieval, and code extraction in a single call. For repeated retrieval, pass the previous response "receivedAt" as "since" to avoid returning the same message again. ### POST /api/inbox/:id/report ⚠️ MANDATORY — Report the outcome of using this inbox. Request body (JSON): { "success": true, // whether the email was received and usable "service": "twitter.com" // target service domain — include if not set via "for" at creation } Response 200: { "ok": true, "action": "stats_updated" } // on success=true { "ok": true, "action": "fail_recorded" } // on success=false, no auto-block triggered { "ok": true, "action": "auto_blocked", "blocked": [ { "service": "twitter.com", "domain": "tmpmail.org", "rule": 1 } ] } // on success=false, auto-block rule triggered (domain banned for that service) YOU MUST CALL THIS ENDPOINT. Every inbox usage MUST end with a report. - success=true → provider gets a success point, Outlook account records this service - success=false → failure logged; if configurable auto-block rules are met, the domain is automatically banned for the service (e.g. 3 failures in 24 hours) - "service" should be the same domain you passed as "for" when creating the inbox ### DELETE /api/inbox/:id Close and release the inbox. Response 200: { "ok": true } ### GET /api/providers List available email providers and their capabilities. Response 200: { "providers": [ { "name": "mailtm", "displayName": "Mail.tm", "type": "api", "tier": "free", "trustLevel": 3, "features": { "customUsername": true, "pollInbox": true, "realtime": false, "attachments": true }, "rateStatus": { ... } }, ... ] } ## Error Responses All errors follow this format: { "error": "Human-readable error message" } Common HTTP status codes: 401 — Missing or invalid Bearer token 404 — Inbox not found 410 — Inbox already closed 429 — Rate limit exceeded (includes retryAfter) 502 — Upstream provider error 503 — All providers exhausted ## Provider Notes Mail Hub aggregates multiple upstream email providers. The dispatcher selects the best available provider automatically. Two providers use pool-based resources: Paid providers (tier "paid") have auto-dispatch disabled by default — they are only used when explicitly requested via the "provider" field in POST /api/inbox. The operator can enable auto-dispatch for any provider through the admin panel. ### Outlook Uses a pool of pre-imported Microsoft accounts (1:1 assignment per inbox). Accounts are returned to the pool when the inbox is closed. Auto-dispatch: off by default (paid). Use provider: "outlook" to request explicitly. ### iCloud / Hide My Email Mints @icloud.com addresses through iCloud+ Hide My Email, so the Apple ID must have an iCloud+ subscription. An admin configures the Apple ID and authenticates Hide My Email with either a pasted iCloud cookie blob or the SRP sign-in flow. The account also needs IMAP credentials, including the app-specific password, for the mailbox Hide My Email forwards to. Mail Hub reads mail over IMAP from the operator's own forwarding mailbox and sorts the shared mailbox by exact recipient. Each inbox therefore sees only messages addressed to its assigned alias. Inbox creation claims an address from a pre-minted pool, and a background task tops the pool up. Addresses return to the pool when an inbox is closed: each Apple ID has a lifetime cap of 750 Hide My Email addresses, so aliases are recycled rather than burned. Retiring an address deactivates it at Apple and is irreversible; use it only for an address that must never be issued again. When multiple Apple IDs are configured, use the optional "account" field documented under POST /api/inbox to choose which account's pool to draw from. Omit it to draw from any usable account. Auto-dispatch: off by default (paid). Use provider: "icloud" to request explicitly. #### iCloud Pool Management (admin only) GET /api/icloud/accounts — List accounts (secrets excluded) POST /api/icloud/accounts — Add an account with pasted cookies and forwarding-mailbox IMAP credentials DELETE /api/icloud/accounts/:id — Remove an account POST /api/icloud/accounts/:id/test — Test Hide My Email and IMAP access POST /api/icloud/accounts/:id/cookies — Replace an expired pasted cookie blob POST /api/icloud/accounts/:id/srp/begin — Begin or renew an SRP sign-in (body: { "password": "..." }) GET /api/icloud/srp/:sessionId/phones — List trusted phones for SMS verification POST /api/icloud/srp/:sessionId/sms — Send an SMS code (body: { "phoneId": 1 }) POST /api/icloud/accounts/:id/srp/complete — Complete SRP sign-in (body: { "sessionId": "...", "code": "123456" }) GET /api/icloud/addresses — List the pre-minted address pool POST /api/icloud/accounts/:id/generate — Mint addresses now (body: { "count": 1 }, maximum 5) POST /api/icloud/addresses/:hme/retire — Irreversibly deactivate and retire an address GET /api/icloud/addresses/:hme/messages — Read mail for one address GET /api/icloud/addresses/:hme/messages/:uid — Read one message for that address ### YYDS Mail Uses a pool of API keys to call the YYDS Mail upstream API. Supports both fixed domains and wildcard subdomains (pass "subdomain" field). Each key has a daily quota of 20,000 API calls, managed automatically. Upstream API documentation: https://maliapi.215.im/v1/llms.txt #### YYDS-specific inbox creation To create an inbox via YYDS with a wildcard subdomain: POST /api/inbox { "provider": "yyds", "for": "twitter.com", "domain": "example.com", "subdomain": "team-a" } → address: "randomuser@team-a.example.com" If "subdomain" is omitted, a fixed domain address is created. If "provider" is omitted, the dispatcher may still select YYDS automatically (it is a free-tier provider and participates in auto-dispatch by default). #### YYDS Pool Management (admin only) GET /api/yyds/stats — Pool statistics (total, active, invalid keys) POST /api/yyds/import — Import API keys (body: { "accounts": "KEY1----name1\nKEY2----name2" }) GET /api/yyds/accounts — List all keys with status, wildcard support, daily usage DELETE /api/yyds/accounts — Delete keys (body: { "keys": ["KEY1", "KEY2"] }) POST /api/yyds/check — Validate keys against upstream (body: { "keys": [...] } or empty for all) PATCH /api/yyds/accounts/wildcard — Set wildcard support (body: { "keys": [...], "wildcard": true }) ### IMAP / Custom Domain Email Connect your own domain email via IMAP. One IMAP account with catch-all enabled serves as a pool resource — the dispatcher invents an address under your domain for each inbox and sorts the shared mailbox by recipient, so one mailbox backs many concurrent inboxes. Generated local parts are name-shaped rather than a random string (nathanlambert, lisa.chen, d_watson91, vera.oconnell8); pass "username" to choose your own. Addresses in use by a live inbox are never reissued. Prerequisites (done outside Mail Hub): - A domain with catch-all email enabled - IMAP credentials for that mailbox Usage: POST /api/inbox { "provider": "imap", "for": "twitter.com", "domain": "mydomain.com" } → address: "juliahoffman@mydomain.com" The "domain" field is optional — if omitted, a random configured domain is picked. Auto-dispatch: on by default (free). IMAP is scored with high trust (trustLevel=10) since it's the user's own infrastructure. #### IMAP Pool Management (admin only) GET /api/imap/stats — Pool statistics (total, active) GET /api/imap/accounts — List all accounts (password excluded) POST /api/imap/accounts — Add an IMAP account Body: { "host", "port", "user", "password", "domain", "tls" } GET /api/imap/accounts/:id — Get account details PUT /api/imap/accounts/:id — Update account fields DELETE /api/imap/accounts/:id — Remove an account POST /api/imap/accounts/:id/test — Test IMAP connection ## Best Practices 1. ALWAYS provide "for" with the target service domain — this is REQUIRED for statistics 2. Prefer GET /api/inbox/:id/code?wait=true over manual polling 3. ALWAYS call POST /api/inbox/:id/report — this is the single most important step 4. DELETE the inbox when you're done to free pool resources 5. Handle 429 by waiting and retrying — the system manages per-provider rate limits automatically 6. Use full domain names for "for" and "service" fields (e.g. "twitter.com", not "twitter") 7. For IMAP: ensure catch-all is enabled and the IMAP account is active before relying on it for inbox creation