Turn it on for a verified domain
email.domain.receiving.set with enabled: true adds an MX record to the domain’s record list. The domain has to be verified first — receiving on an unproved domain is refused with domain_not_verified.
The record is on the apex, not a subdomain, and MX is not additive. Publishing it makes Lath the destination for every message sent to that domain, which is why this is a separate opt-in and not part of verification: turned on for a domain that already receives company mail, it takes that mail over.
Turning receiving off removes the record from the list Lath gives you, but your DNS is yours — take the record down at your host too, or mail keeps arriving at a door that now refuses it.
Every address, one mailbox
Receiving is a catch-all for the whole domain. Anything sent to any address there arrives; there are no per-address rules, aliases or forwarding, so routing by recipient is something your own code does after the fact. The address used for routing is the envelope recipient the sending server gave, not theTo header — which is how a message you were blind-copied on still arrives, and still tells you it was addressed to you.
Inbound mail always lands in the live environment. There is no test-mode inbound.
Reading what arrived
email.inbound.list pages summaries newest first, filterable by domain, sender and recipient, each with a 280-character preview and an attachment count. email.inbound.get returns one whole message: text, HTML, recipients, headers, the spf, dkim and dmarc verdicts as the receiving edge reported them, and attachments inline as base64.
Those verdicts are recorded, not enforced. A message that fails DMARC is still delivered to you with the failure attached, because deciding what to do about it is your policy and not Lath’s.
A message that arrives twice with the same id for the same recipient is stored once, and the duplicate raises no second event.
Attachments and size
A whole message may be 25 MB, of which attachments may total 10 MB; over either is refused at the door withinbound_too_large or inbound_attachments_too_large, and an empty message with inbound_empty.
Attachments come back inside email.inbound.get as base64 rather than from a download URL — there is no separate attachment endpoint. For a large attachment that means the message read is large too, so list first and fetch the one you want.
Deleting, and how long it is kept
email.inbound.delete redacts a message in place: the subject, both bodies, the attachments and the headers are cleared and the recipient list is reduced to the one address it arrived at. The row stays so the timeline still shows that something arrived and was deleted. It is idempotent, and says whether it had already been done.
Inbound mail is not swept on a retention schedule the way message logs are — it stays until you delete it, and it is erased when an account is closed.
email.inbound.received is the event to subscribe to. email.inbound.refused exists for mail that was turned away at the door, which is deliberately never stored.
