# mxgate > Email for a domain, set up by an agent. mxgate receives mail for domains the user owns and forwards it to confirmed mailboxes. It sends mail as addresses at those domains (SMTP or one API call). Free plan: 1 domain, 10 aliases and a catch-all, send-as to 50 recipients a day, no card. The paid plan has no checkout yet: the user writes to hello@mxgate.io. API base: https://api.mxgate.io (GET / lists every endpoint) Auth: Authorization: Bearer CLI and MCP server (MIT): npx mxgate --help | npx mxgate mcp MCP install: claude mcp add mxgate -- npx -y mxgate mcp ## The flow 1. POST /v1/signup {"email"} -> 201 {api_key, account, next_steps}. No auth. The key is shown once and mailed. The mail has a link: the owner opens it and presses "Confirm forwarding", and the address becomes a forwarding destination. 2. POST /v1/domains {"name":"example.com"} -> {domain: {records: [...]}}. The records to publish: TXT _mxgate. (ownership, required), MX -> mx1.mxgate.io priority 10 (required), TXT mxgate._domainkey. (DKIM, for send-as only), TXT _dmarc. (only if the domain has none). 3. Publish the records at the DNS host. `npx mxgate setup --to ` does steps 2 to 5 for Cloudflare (CLOUDFLARE_API_TOKEN), Vercel (VERCEL_TOKEN) and Porkbun (PORKBUN_API_KEY, PORKBUN_SECRET_API_KEY); the token stays on the user's machine. An existing MX is a conflict until --replace-mx; --dry-run shows the plan. 4. POST /v1/domains/{domain}/verify -> {verified, domain: {checks: {ownership, mx, dkim, problems}}}. Repeat until verified is true; DNS can take minutes. 5. PUT /v1/domains/{domain}/aliases/{alias} {"to":["you@example.org"]} -> the alias. The alias "*" is the catch-all. A new destination gets a confirmation mail; no mail is forwarded to it before its owner confirms. ## Endpoints - GET /v1/account -> plan, limits, usage, status. - GET /v1/domains | GET /v1/domains/{domain} | DELETE /v1/domains/{domain} - GET /v1/domains/{domain}/aliases | DELETE /v1/domains/{domain}/aliases/{alias} - GET /v1/destinations | POST /v1/destinations {"email"} (mails a confirmation link) - GET /v1/domains/{domain}/smtp -> send-as readiness, host smtp.mxgate.io, ports 587 (STARTTLS) and 465 (TLS), logins. - POST /v1/domains/{domain}/smtp -> a new SMTP login; the password is shown once. DELETE /v1/domains/{domain}/smtp/{username} removes it. - POST /v1/send {"from":"Name ","to":["a@b.c"],"subject","text"} -> 202 {message_id, status:"queued"}. Optional: cc, bcc, reply_to, in_reply_to, references, copy_to_owner, idempotency_key (or the Idempotency-Key header). Plain text only. At most 50 recipients. The domain must be verified with its DKIM record. - GET /v1/logs?domain=&direction=in|out&status=forwarded|sent|deferred|bounced|expired|rejected&address=&before=&limit= -> {entries, next_before, retention_days}. One row per message with the reply of the other server and a plain explanation. No subject, no body. - GET /v1/notifications | PUT /v1/notifications {"email":true,"events":["bounced","expired"],"webhook_url":"https://..."} | POST /v1/notifications/test. A webhook call is signed: header mxgate-signature: t=,v1=." with webhook_secret>. Webhooks are for mail that failed; there is no webhook for each received message. - POST /v1/keys/recover {"email"} -> mails a recovery token to the account address. No auth. POST /v1/keys/recover/confirm {"token"} -> {api_key}; the older keys stop working. POST /v1/keys/rotate (Bearer) -> {api_key}; the key of the call stops working. ## Errors Every error is JSON {error, message, fix}: a code to switch on, a sentence for a person, and the next step. 401 missing_api_key or invalid_api_key. 402 plan_limit (with upgrade_url; show it to the user). 403 account_suspended. 409 domain_taken, send_as_not_ready, already_registered. 422 forwarding_loop, recipient_refused, message_refused. 429 rate_limited (with retry_after_seconds). ## Limits Free: 1 domain; 10 aliases per domain plus a catch-all; 3 destinations per alias; log kept 7 days; send-as to 50 recipients a day (resets at 00:00 UTC). Paid: no domain or alias limit; 10 destinations per alias; log kept 90 days; 3,000 recipients a month. One message is at most 25 MB. mxgate tries a delivery for 2 days. ## What mxgate does not do No mailbox, no IMAP, no webmail. No HTML and no tracking in POST /v1/send. No bounce message to the sender of forwarded mail (it would show the mailbox behind the alias); the account owner gets the notification. MCP tools: signup, recover_key, confirm_key_recovery, rotate_key, get_account, list_domains, add_domain, get_domain, verify_domain, remove_domain, setup_domain, list_aliases, set_alias, remove_alias, list_destinations, add_destination, get_send_as, create_smtp_credential, remove_smtp_credential, send_email, get_logs, get_notifications, set_notifications, test_webhook, check_dns. Privacy and terms: https://mxgate.io/terms Contact: hello@mxgate.io. Abuse: abuse@mxgate.io.