> For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://www.agentmail.to/docs/llms.txt.

# How do I set up allowlists and blocklists?

Allowlists and blocklists let you control who your AI agent can communicate with. This is a critical safety feature for autonomous agents running in production with minimal human oversight.

## How Lists work

AgentMail provides six list types based on two dimensions, **direction** (send, receive, or reply) and **type** (allow or block):

| List          | What it does                                                                                        |
| ------------- | --------------------------------------------------------------------------------------------------- |
| Receive allow | Only mail from these addresses or domains arrives normally; mail from anyone else is marked blocked |
| Receive block | Mail from these addresses or domains is marked blocked                                              |
| Send allow    | Only these addresses or domains can be emailed; sends to anyone else are rejected                   |
| Send block    | Sends to these addresses or domains are rejected                                                    |
| Reply allow   | Only replies from these addresses or domains arrive normally; other replies are marked blocked      |
| Reply block   | Replies from these addresses or domains are marked blocked                                          |

Each entry can be either a full email address (e.g., `partner@example.com`) or an entire domain (e.g., `example.com`). An allow list takes effect as soon as it has an entry: from then on, any address that does not match an allow entry is treated as blocked for that direction.

## What happens when a list blocks a message

**Inbound mail (receive and reply lists).** A blocked message is not dropped. AgentMail still stores it in the inbox, but:

* It gets the `blocked` label.
* It fires the `message.received.blocked` event instead of `message.received`. A message that also failed sender authentication fires `message.received.unauthenticated` instead.
* It is left out of message and thread lists unless you pass `include_blocked=True` with an API key that has the `label_blocked_read` permission. The same permission is required to subscribe to `message.received.blocked`.

Because blocked mail never fires `message.received`, an agent that reacts to that event never sees it.

**`Python`**

```python title="Python"
# review mail that your lists blocked
blocked = client.inboxes.messages.list(
    inbox_id="agent@yourdomain.com",
    labels=["blocked"],
    include_blocked=True
)
```

**`TypeScript`**

```typescript title="TypeScript"
// review mail that your lists blocked
const blocked = await client.inboxes.messages.list("agent@yourdomain.com", {
  labels: ["blocked"],
  includeBlocked: true,
});
```

**Outbound mail (send lists).** The send is refused with a `403` and error code `message_rejected`, and no email goes out. This applies to every send path, including replies, forwards, and `drafts.send`.

## Setting up lists via the SDK

### Add an entry

**`Python`**

```python title="Python"
from agentmail import AgentMail

client = AgentMail()

# allow receiving from a specific domain
client.lists.create("receive", "allow", entry="trusted-corp.com")

# block a specific sender (with optional reason)
client.lists.create("receive", "block", entry="spam@example.com", reason="spam")

# restrict sending to only certain addresses
client.lists.create("send", "allow", entry="customer@example.com")

# prevent sending to a domain
client.lists.create("send", "block", entry="competitor.com")
```

### List entries

**`Python`**

```python title="Python"
# view entries in a list (one page per call)
entries = client.lists.list("receive", "allow")
```

### Remove an entry

**`Python`**

```python title="Python"
client.lists.delete("receive", "block", entry="spam@example.com")
```

### Inbox-scoped lists

Lists can be applied at the inbox level for per-inbox filtering. For example, one inbox might only accept emails from `meta.com`, while another inbox in the same pod accepts from `partner.com`.

**`Python`**

```python title="Python"
# this inbox only accepts emails from meta.com
client.inboxes.lists.create(
    "support@yourdomain.com", "receive", "allow", entry="meta.com"
)

# a different inbox accepts from partner.com
client.inboxes.lists.create(
    "sales@yourdomain.com", "receive", "allow", entry="partner.com"
)
```

Inbox-level lists override pod-level and org-level lists. If the inbox-level list has a match, pod and org lists are not checked.

### Reply lists

Reply lists control filtering for inbound emails that are replies to previous outbound messages. When an inbound email arrives, AgentMail checks the `In-Reply-To` header:

* If the email **is a reply** to a previous outbound message, only the reply lists are checked. Receive lists are skipped.
* If the email **is not a reply**, only the receive lists are checked. Reply lists are skipped.

By default, when reply lists are empty, all replies are allowed. This is useful for agents that initiate outbound emails (such as making reservations or sending inquiries) and need to receive the responses.

**`Python`**

```python title="Python"
# block replies from a specific sender
client.inboxes.lists.create(
    "agent@yourdomain.com", "reply", "block", entry="spam-restaurant.com"
)
```

## Common patterns for agents

**Customer-facing agent:** Use a send allowlist to restrict your agent to only email your existing customers. This prevents the agent from accidentally emailing the wrong people.

**`Python`**

```python title="Python"
# only allow sending to existing customers
for customer in customers:
    client.lists.create("send", "allow", entry=customer.email)
```

**Personal Agent (Openclaw, Manus, etc.):** Use a receive allowlist to restrict your agent to only respond to emails from specific people or domains.

**`Python`**

```python title="Python"
# only accept emails from your own address and trusted domains
client.lists.create("receive", "allow", entry="you@yourcompany.com")
client.lists.create("receive", "allow", entry="trusted-partner.com")
```

**Anti-spam:** Use a receive blocklist to filter out known spam senders or unwanted automated emails.

**`Python`**

```python title="Python"
# block known spam domains
client.lists.create("receive", "block", entry="spam-domain.com", reason="spam")
```

**Task-oriented agent (making reservations, bookings, etc.):** Use a receive allowlist to restrict inbound to your organization's domain, but leave reply lists open (default) so replies to agent-initiated outbound emails come through.

**`Python`**

```python title="Python"
# only accept unsolicited emails from your org
client.inboxes.lists.create(
    "agent@yourdomain.com", "receive", "allow", entry="yourdomain.com"
)

# replies to emails the agent sends (e.g., restaurant reservations)
# are allowed by default, no reply list configuration needed.
# optionally block specific reply senders:
client.inboxes.lists.create(
    "agent@yourdomain.com", "reply", "block", entry="spam-restaurant.com"
)
```

## Why this matters for agents

Without guardrails, an autonomous agent could email the wrong people, respond to phishing attempts, or get caught in infinite email loops with another bot. Lists are your safety rails. They are especially important for:

* **Production agents** operating with minimal human oversight
* **Customer-facing agents** that should only contact approved recipients
* **Support agents** that should only respond to known customers
* **Task-oriented agents** that send outbound emails and need replies to come through
* **Any agent** that needs protection from spam, phishing, or abuse

For more details on the Lists API, see the [Lists core concept](https://docs.agentmail.to/lists) documentation.