messages:send)
Sending is a separate permission from everything else. messages:write lets a
key file and star mail that already exists; it does not let it send. Mail
sent here leaves under your domain’s reputation and spends your plan’s daily
allowance, so granting it is a deliberate choice.
Request
Address fields accept either an array or a comma-separated string. Both are
common in the wild and neither is wrong.
from must be a mailbox, not an alias. Aliases are sendable in the web app
but are not accepted here yet — an alias is refused rather than quietly sent as
its owner. Use an address from GET /v1/mailboxes.Private mailboxes cannot send through the API at all: the message would have to
be encrypted with a key only the owner’s browser holds.Attachments
Each entry isfilename, base64 content, and an optional content_type
(defaults to application/octet-stream).
Response
202 Accepted. The message has been handed to the mail server, which is not
the same as delivered — remote servers accept and bounce on their own schedule.
rejected was refused by the mail server outright — usually a
malformed address. Recipients in accepted were taken for delivery.
A copy is filed in the Sent folder automatically. If that filing fails the send
still reports success: the message has already gone, and reporting failure would
invite you to send it twice.
Limits
Sending passes several ceilings, and they fail differently:
The per-mailbox limits are the ones that decide whether a leaked key can burn
your domain’s reputation before you notice, so an API key does not get a more
generous version of them than the web app has. The daily allowance is the
entitlement your plan sells, and it is shared: messages sent from the dashboard
and through the API draw on the same counter.
rate_limited carries a Retry-After header. quota_exceeded does not — the
allowance resets at midnight UTC.
Errors
See Errors for the full response shape.