# Melay POST /v1/emails requires Idempotency-Key: reuse the same key for the same logical send. queued is acceptance only. No automatic retries on unknown outcomes; inspect the existing record before deciding any next action. Internal SaaS transactional mail and verified Gmail forwarding at https://melay.go100m.com. Read /openapi.json for the API contract and /capabilities for live provider readiness. Web console: /. Google-authenticated operator console: /admin (header entrypoint visible only for database operators). Discovery: /api. Users sign up or log in with Firebase Google Authentication. GET /auth/config exposes whitelisted public Firebase client configuration only. POST /auth/google {idToken} requires the exact same Origin and exchanges a verified Google-provider Firebase ID token for an HttpOnly Secure SameSite=Strict browser session. The server verifies Google RSA signature, issuer, audience, expiry, issuance/authentication times and verified email; do not trust client role claims. Firebase handles authentication only; application accounts/roles remain in Melay SQLite, not Firestore. Never log ID tokens. In GOOGLE_AUTH_ONLY deployments, legacy POST /auth/start, /auth/complete, password/token POST /admin/session and old relay_session browser sessions are disabled. Gmail destination POST /auth/receive/complete proof remains supported. Melay account authentication is separate from caller applications' OTP, consent and authentication sessions. New Google-verified ordinary users have approvalStatus:pending and require operator approval. GET /account/session shows their masked identity and approvalStatus; DELETE /account/session logs out. pending/rejected/suspended accounts cannot access project/token management, /v1 mail APIs or incoming forwarding. Do not retry or bypass account_pending/account_rejected/account_suspended. Approval creates no project. An approved account starts with zero projects and can issue rt_ for AI onboarding without creating any project manually. Suspension and reapproval preserve keys, domains and history. Approved signed-in users issue one-time rt_ access tokens at POST /account/v1/tokens {label}. Use Authorization: Bearer in server-side AI tools. GET /account/v1/tokens never returns secrets; DELETE /account/v1/tokens/{id} revokes. Never log or commit tokens, or put them in browser/mobile bundles. rt_ tokens control only the issuing user's projects and domains; they are broad account management credentials. Prefer narrower mk_ sending keys in application runtimes. GET /account/v1/projects lists own projects. POST creates a project with id,appName,allowedSenders,allowedTemplates,dailyLimit,minuteLimit; owner/provider are server-selected. GET/PATCH /account/v1/projects/{id}, POST .../keys {revision,kind,label}, DELETE .../keys/{keyId} {revision}. Policy/key changes require current revision; reload on 409. Projects may be explicitly created with allowedSenders:[]; no sender is authorized until configured. No project is created by signup, approval or login. A valid rt_ without any project gets 404 from project-scoped /v1/* until explicit creation. /account/v1/projects/{id}/domains, /inbound and /emails mirror project APIs. /v1/* accepts rt_ or mk_ keys; optional X-Relay-Project selects an own enabled project for rt_. Project keys remain project-scoped. New user projects use Melay's shared Cloudflare account. Users provide no AWS/Cloudflare credentials. Supported domains must be a zone or subdomain managed in Melay's operator Cloudflare account; arbitrary external DNS TXT alone is insufficient. A shared provider connection does not share Melay domain ownership or project privileges. Never give a new user the operator's go100m.com domain; authenticate their exact domain independently. Prefer POST /account/v1/onboarding {projectId,appName,domain,from?} with one rt_ account token, even when there is no project. The user connects that token via an AI tool server secret and only publishes returned DNS. The AI handles project/domain/initial sending keys and application server secret configuration. Default from is noreply@. New project creation returns issuedKeys once: save immediately in approved secret configuration, never chat/log/commit. Identical calls resume the same project/domain; never automatically issue or rotate keys after a lost response. For an existing project with empty allowedSenders, append only the requested sender using its current revision, preserving templates/limits/other policy. A same-ID appName mismatch or a nonempty sender list missing the requested from returns 409 onboarding_project_conflict; inspect current policy and explicitly use revision-based APIs only within the authorized request or choose a different project ID. Call the same onboarding request after every DNS publication and read canSend; ownership proof alone is insufficient. This endpoint does not send mail. Request explicit authorization separately for live test mail. Melay prepares the shared Cloudflare provider only after public exact-domain ownership proof. Existing settings are reused; creation may add bounce MX/SPF, DKIM and DMARC only when reserved DNS locations are empty. Existing _dmarc. blocks new automatic creation for Melay operator review. Cloudflare creation provides no skip-DNS/CAS option: preflight is not atomic protection against concurrent external DNS edits; do not edit the same domain concurrently. Never overwrite root MX, SPF, DMARC or receiving rules. Missing zone, permissions, conflicts and unknown provider outcomes are Melay operations blockers, not requests for user Cloudflare credentials. Do not blindly retry an uncertain provider write. Only canSend:true permits new sending, requiring public DKIM/SPF/bounce MX, enabled provider and preview disabled. The existing granular /v1/domains and preview/apply APIs remain available. /capabilities describes configuration, not delivery proof. Cloudflare-owner login linking/OAuth and user DNS auto-registration are NOT implemented. Being on Cloudflare does not itself authorize Melay to write user DNS. Users currently publish returned DNS themselves. POST /v1/inbound {domainId,localPart,destination} requests an exact receiving address. Destination currently supports Gmail/googlemail only. Recipient personally confirms Melay's emailed proof via POST /auth/receive/complete {id,proof}; proof is one-time and expires in 24h. POST /v1/inbound/{id}/destination-verification requests another Melay proof when needed. GET /v1/inbound returns masked routes and forwarding metadata. POST /v1/inbound/{id}/prepare {} previews a Cloudflare DNS/provider plan; reviewed {apply:true,confirmationToken} prepares the destination and returns DNS without touching DNS. Cloudflare may send its own destination verification email, in addition to Melay's proof email. The recipient must confirm every required link; Melay proof alone does not imply provider verification. Existing Cloudflare-verified destinations may need no additional provider email. Publish returned receiving MX/TXT manually, preferably on a dedicated receiving subdomain if the root already has email. Existing incompatible MX causes existing_mx_conflict; Melay never overwrites or combines other-provider MX. POST /v1/inbound/{id}/verify only reads ownership, Melay Gmail proof, Cloudflare destination verification, public receiving DNS and Email Routing readiness. routing_rule_missing means the reviewed prepare plan must be applied again to activate the exact-address Worker rule. operator_activation_required or operator_setup_required means an operator must prepare Email Routing for that zone. operator_routing_subdomain_required means the subdomain needs exact receiving-zone support from the operator; parent-zone ownership alone is insufficient. Exact-address Worker rules are scoped to the managed route; no unrelated rules or catch-all changes. DELETE /v1/inbound/{id} pauses forwarding without changing DNS; POST /v1/inbound/{id}/resume resets a paused route, then explicitly POST .../verify to recheck readiness and activate. A paused route does not forward incoming mail. Incoming mail including attachments is limited to 25 MiB including headers. The Cloudflare Email Worker forwards the original message preserving attachments, without AWS or temporary body storage. No mailbox/archive or body viewing API. Destination configuration is encrypted; responses show masked destinations. Reserve forwarding execution before provider forwarding; unknown results never trigger automatic re-forwarding. queued means Cloudflare forwarding acceptance, not Gmail arrival. Provider configuration, public DNS proof and actual mailbox delivery are separate facts. Never log credentials, verification proofs, mail bodies, codes or raw recipient addresses. No newsletters, contacts, consent management or caller OTP verification. /health and mock tests do not prove real delivery. Operators use separate ra_ credentials for /admin/v1/*; these control all projects. Do not give ra_ to tenants. Admin project endpoints mirror account project endpoints, with operator-owned owner/provider policy fields. After the first seed, registry policy and key revocations persist and override bootstrap config. Browser cookies require same-origin mutations. Key issuance and activation confirmation are not automatically retried after uncertain outcomes. GET /admin/v1/users returns masked users, whole-population counts by pending/approved/rejected/suspended, and nextCursor. Optional status,limit(up to100),cursor. POST /admin/v1/users/{id}/approve|reject|suspend {revision} changes status; stale revision returns409. In Google-only deployments, POST /admin/session legacy password/key login and old console cookies are disabled. Operators use their verified Google relay_user session; ra_ Bearer server credentials remain supported. Tenant rt_ tokens never grant admin access. Melay runs with PROJECTS_JSON:[] and zero users/projects. GET /admin/v1/service is an authenticated read-only operational configuration endpoint: service,serviceUrl,systemSender,mode,stateVersion,cloudflare{sharedConnection,configured},signup{configured,approvalRequired,automaticProjectCreation:false,googleConfigured,legacyEmailLogin},receiving{configured},initialProjectsConfigured. No provider token/account ID, password or credential hashes. RELAY_SYSTEM_FROM is for Melay authentication emails only, separate from tenant sender/domain privileges. Nexus is optional application example data, never a required system project. SERVICE_STATE_VERSION isolates all service Durable Object names. Change only for an explicitly authorized fresh reset; preserve FINGERPRINT_SECRET and historical dedupe data. Old users/sessions/tokens/project keys/domains/routes/history cannot resolve in the new generation. Historical objects remain isolated, not physically deleted; restoring an old generation may expose them again. The service:setup command configures zero projects; --fresh-state explicitly creates a new generation and requires separate deployment. External DNS/provider rules require separately scoped cleanup; this command never changes them. A designated verified Google account is registered as users.role=operator and approved on first login. All subsequent admin requests require its current database role and approval. Operator header links to /admin; the operator own-project workspace remains separate. Database downgrade/suspension blocks existing browser admin access immediately. Even an operator rt_ access token MUST NOT access admin APIs. Separate ra_ Bearer credentials remain an explicit server/break-glass mechanism.