Lists and suppressions
Allow and block lists control who can email your inboxes and who they can send to. Suppressions stop sending to addresses that bounced or complained.
Two mechanisms decide which addresses an inbox may talk to:
- Lists are allow and block lists you manage, for inbound (
receive) and outbound (send) mail, at organization, pod or inbox level. - Suppressions are addresses MachineMail will not send to, mostly added automatically after hard bounces and spam complaints.
Lists
A list is addressed by a direction and a type:
| Path segment | Values |
|---|---|
direction | receive (who may send to you) or send (who you may send to) |
type | allow or block |
An entry is either an email address or a domain:
ada@example.comis anemailentry and matches that address only.example.com,@example.comand*@example.comall become thedomainentryexample.com. A domain entry also matches its subdomains, such asmail.example.com.
Entries are lowercased. Adding an entry that already exists returns the existing one.
Levels
The same endpoints exist at three levels. The path decides where the entry lives:
| Level | Path |
|---|---|
| Organization | /v0/lists/{direction}/{type} |
| Pod | /v0/pods/{pod_id}/lists/{direction}/{type} |
| Inbox | /v0/inboxes/{inbox_id}/lists/{direction}/{type} |
Each level supports GET (list entries), POST (add, body { entry, reason? }), GET .../{entry} and DELETE .../{entry}. Listing shows only the entries stored at that exact level.
When mail is checked against an inbox, the entries from all three levels apply together: the organization’s, the inbox’s pod’s and the inbox’s own.
How lists decide
For a given address and direction:
- If it matches an allow entry, it is allowed.
- Otherwise, if it matches a block entry, it is blocked.
- Otherwise, if any allow entries exist for that direction, it is blocked. A non-empty allow list means “only these”.
- Otherwise it is allowed.
So an allow entry always beats a block entry, and adding one allow entry turns that direction into an allowlist.
What blocking does
Receive. Mail from a blocked sender is still stored, but labelled BLOCKED only (no INBOX), and emits message.received.blocked instead of message.received. It is hidden from lists unless you pass include_blocked=true with a key that has label_blocked_read. This keeps an audit trail without putting the message in front of your agent.
Send. Sending to a blocked recipient fails with 403 forbidden (“Sending to … is blocked by a send list”). Nothing is sent to any recipient.
Lists and trust
Receive lists also feed the trust report. trust.sender.on_allow_list and on_block_list reflect them. An allowlisted sender whose mail passes aligned DMARC can reach the verified level without prior correspondence, and a blocklisted sender is always quarantined.
A receive allow list is a strong control for agents that should only take instructions from known people: everything else is blocked before the agent sees it. It is not a way to raise trust for a few senders while still receiving other mail.
Warning
The first receive allow entry at the organization, a pod or an inbox switches that scope to allow-only: mail from every sender that does not match an allow entry is labelled BLOCKED and withheld
from agents. An allow-listed sender reaches verified only with an aligned DMARC pass. To reach verified in normal use, write to the sender first: prior correspondence counts as the relationship.
Suppressions
A suppression stops all sending to an address from every inbox in the organization. Sending to a suppressed recipient fails with 403 forbidden (“Recipient … is suppressed (bounce)”).
MachineMail adds suppressions automatically:
reason | Added when |
|---|---|
bounce | A message to the address hard-bounced. Soft (transient) bounces do not suppress. |
complaint | The recipient marked a message as spam. |
manual | You added it. |
| Method | Path | Notes |
|---|---|---|
GET | /v0/suppressions | Paginated. |
POST | /v0/suppressions | Body { email, reason? }. Always stored with reason: "manual"; your reason text goes into detail. An existing complaint suppression is returned unchanged. |
GET | /v0/suppressions/{email} | One entry. |
DELETE | /v0/suppressions/{email} | Allow sending again. Organization-scoped keys only. bounce and manual suppressions only: a complaint returns 403. |
Suppressions are organization-wide and use the list_entry_read, list_entry_create and list_entry_delete permissions. Bounces and complaints also emit message.bounced and message.complained events.
A complaint suppression (the recipient reported your mail as spam) cannot be removed through the API, the CLI, MCP or the dashboard: DELETE returns 403 forbidden with Complaint suppressions can only be removed by MachineMail support; email support@machinemail.dev. Email support@machinemail.dev if the recipient has asked for your mail again. A later bounce for the same address does not replace a complaint.
Only remove a suppression when you know the address works again. Repeated sends to dead or complaining addresses hurt deliverability for everyone on the same domain.