mxgate

Send as your domain

Send mail as an address at your domain: SMTP logins for a mail client, or one call to the send API with thread headers and idempotency keys.

mxgate sends mail as addresses at your domain in two ways: through SMTP from a mail client, or through one API call. Each domain signs with its own DKIM key.

Before you send

Two things must be true for the domain:

  • The domain is verified.
  • The DKIM record mxgate._domainkey.example.com is published, and a check confirmed it: dkim is ok in checks.

mxgate setup writes the DKIM record. If you added the records by hand, add the DKIM record from mxgate domain show example.com, then run mxgate domain verify example.com. See DNS setup.

$ npx mxgate smtp example.com
Send-as is ready: smtp.mxgate.io, port 587 (STARTTLS) or 465 (TLS).

When send-as is not ready, the command gives the reasons. The API call is GET /v1/domains/example.com/smtp, with ready and reasons.

SMTP logins

$ npx mxgate smtp create example.com
host      smtp.mxgate.io
port      587 (STARTTLS) or 465 (TLS)
username  mxg-1a2b3c4d@example.com
password  ...

The password is shown once. mxgate stores only a hash, so store the password now. A login sends only as addresses of its own domain: the envelope sender and the From header must be at that domain. A domain has at most 5 logins. Remove one with mxgate smtp rm example.com mxg-1a2b3c4d@example.com.

The API calls are POST /v1/domains/example.com/smtp and DELETE /v1/domains/example.com/smtp/{username}.

Settings for Gmail or a mail client

In Gmail, the settings go in "Send mail as". Other mail clients have the same fields for an outgoing server.

SettingValue
SMTP serversmtp.mxgate.io
Port587 with STARTTLS, or 465 with TLS
UsernameThe login, for example mxg-1a2b3c4d@example.com
PasswordThe password from mxgate smtp create
From addressAn address at the domain, for example ada@example.com

The send API

mxgate send, the MCP tool send_email and POST /v1/send send one message with no SMTP login. The From address must be at a domain of your account that is ready for send-as.

npx mxgate send --from "Ada <ada@example.com>" --to client@example.org \
  --subject "Hello" --text "Hi"

npx mxgate send --from ada@example.com --to client@example.org \
  --subject "Re: Offer" --file reply.txt \
  --in-reply-to '<id-of-their-mail@example.org>' --copy --key offer-reply-1

--file - reads the body from stdin. The same call with curl:

curl -X POST https://api.mxgate.io/v1/send \
  -H "Authorization: Bearer $MXGATE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "Ada <ada@example.com>",
    "to": ["client@example.org"],
    "subject": "Re: Offer",
    "text": "Hello. Here is the answer to your question.",
    "in_reply_to": "<id-of-their-mail@example.org>",
    "copy_to_owner": true,
    "idempotency_key": "offer-reply-1"
  }'

The answer is 202:

{
  "message_id": "5f0c2a9e41b7d3680a1f9c2e7b4d6a13@example.com",
  "from": "ada@example.com",
  "to": ["client@example.org"],
  "cc": [],
  "bcc": ["you@gmail.com"],
  "status": "queued",
  "replayed": false,
  "message": "Queued for 2 recipients. What each mail server answered: GET /v1/logs?direction=out&domain=example.com."
}

queued means that the mail server took the message. The message log shows what the server of each recipient answered: mxgate logs example.com --out.

Fields

FieldRequiredMeaning
fromYes"Name <you@example.com>" or an address only.
toYesOne address or a list.
ccNoCopy recipients. The message shows them.
bccNoHidden copy recipients. No header shows them.
reply_toNoWhere replies go, when it is not the sender.
subjectYes1 to 255 characters.
textYesThe body as plain text.
in_reply_toNoThe Message-ID of the message that you answer.
referencesNoOlder Message-IDs of the thread, oldest first. At most 50. The default is in_reply_to.
copy_to_ownerNotrue adds your account address as a hidden copy.
idempotency_keyNo1 to 200 characters. The header Idempotency-Key does the same.

Plain text only

The send API takes plain text. There is no HTML and no tracking: a link arrives as you wrote it. One message goes to at most 50 addresses: To, Cc and Bcc together. An address that is in two lists gets one copy.

Idempotency

Give an idempotency_key when a retry must not send a second copy. The same key with the same message sends once: the second call answers 200 with the first answer and "replayed": true. The same key with a different message is 409 idempotency_key_reused. mxgate keeps a key for 7 days.

Thread headers

To answer a message and keep the thread, give its Message-ID in in_reply_to and start the subject with "Re: ". The Message-ID is message_id in mxgate logs --json. Angle brackets are not necessary.

Limits

PlanLimit
Free50 recipients a day. The count starts again at 00:00 UTC.
Paid3,000 recipients a calendar month.

Each recipient counts. SMTP and the send API use the same count. A call above the limit is 402 plan_limit, and an SMTP login above the limit gets a refusal with the reason. GET /v1/account shows sent_today and sent_this_month. See Plans and limits.

When sending is paused

All customers send from one IP address. If 10% or more of the mail you send bounces, or receiving servers refuse it as spam, mxgate pauses sending for your account. You get an email with the reason, and a person looks at each pause. Forwarding continues.

While sending is paused, send_hold in GET /v1/account has the reason, the send API answers 409 send_as_not_ready, and mail from an SMTP login is refused with the reason. Write to abuse@mxgate.io.

On this page