> For an agent: the map of this documentation is at https://escouade.io/en/mail/docs/llms.txt; every page exists in Markdown, at the same address with `.md` appended.

# Unsubscribes and blocks

> Every e-mail carries a one-click unsubscribe link. A person who unsubscribes, replies “STOP” or reports a message receives nothing more from the space. An agent cannot lift that block.

## How a person unsubscribes

- **Through the one-click link.** Every outgoing message carries the `List-Unsubscribe` and `List-Unsubscribe-Post` headers (RFC 8058): the recipient's mail client shows its own unsubscribe button. The link is unique per message.
- **Through the link's page.** Opening the link shows a page that asks for confirmation. Merely loading the page does not unsubscribe: it takes the button, or the mail client's click.
- **Through a reply.** “STOP”, “désinscrivez-moi”, “merci de me désabonner”, “unsubscribe”, “retirez-moi de votre liste”, “je souhaite ne plus recevoir vos messages”: in the new text of a reply, these requests count as unsubscribing. Quoted text and automatic replies do not count.
- **Only a short request is recognised**: a reply of twelve words at most, once the quotation and the signature are removed. One of these words in the middle of a longer sentence is not a request for the server. If the correspondent asks to stop in a longer message, it is up to the agent to block them, with `add_suppression`.

As long as the correspondent has not written in the thread, the server adds in the message's footer a notice “Pour ne plus recevoir nos messages” (to stop receiving our messages), followed by the link. To place the link yourself, write `{{unsubscribe_url}}` in the text. As soon as the correspondent has written, it is a conversation: no more visible footer, the link stays in the headers.

The link of a test send (`test`) unsubscribes nobody.

## What an unsubscribe does

- The address enters the space's block list: no inbox of the space writes to it any more.
- Messages that were waiting to leave towards it are cancelled.
- The thread moves to the `unsubscribed` status.
- Any new send to it is refused with the code `recipient_suppressed`.

## The block list

| Reason | Origin | Scope | Lifted |
|---|---|---|---|
| `unsubscribe` | One-click link, unsubscribe page, “STOP” reply. | The space | By an Escouade Mail administrator, at the person's written request. |
| `complaint` | The person reported a message as spam. | The space | By an Escouade Mail administrator, at the person's written request. |
| `hard_bounce` | Dead address: a hard bounce. | The whole platform, when the mail server refuses the address at sending. The space, when it is a non-delivery notice received by the inbox. | It stays blocked. |
| `manual` | Added through `add_suppression`. | The space | Through `remove_suppression`, with the `approve` permission. |

An entry blocks an address, or a whole domain.

## `add_suppression`

Adds an address or a domain to the space's block list: nothing more will be sent to them, and whatever was waiting to leave towards them is cancelled. Call it as soon as a correspondent asks not to be contacted again. Permission: `send` or `approve`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `address` | text | yes | An address (`marie@example.com`) or a whole domain (`@example.com`). |
| `note` | text | no | The reason, for the log. 300 characters at most. |

```text
Bloqué julien.roux@exemple.com : plus aucun envoi de l’espace. 1 message(s) en attente annulé(s). Ce blocage ne se lève pas avec cette clé : remove_suppression demande la permission approve, celle de votre humain.
```

A public mail service cannot be blocked as a whole: a domain such as `gmail.com` is refused with the code `public_mail_domain`. Block the addresses one by one.

A block can only be lifted with the `approve` permission (`remove_suppression`). The key returned by `sign_up` does not carry it: an agent that blocks an address by mistake cannot undo it alone. The response tells it so. Its human lifts it from their assistant, connected at `https://mail.escouade.io/mcp`.

## `remove_suppression`

Removes from the list an entry added by hand. Permission: `approve`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `address` | text | yes | The address or the domain (`@example.com`) to unblock. |

An unsubscribe, a complaint or a dead address cannot be lifted with this tool: the call is refused with the code `suppression_protected`.

## `list_suppressions`

Lists the addresses and domains blocked for the space, newest first. Permission: `read`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `query` | text | no | Part of an address or a domain. With a full address, the response also says whether it is a dead address known across the platform. |
| `cursor` | text | no | The cursor of the next page: the `next_cursor` value from the previous call. |
| `limit` | integer | no | The number of items returned, from 1 to 100. 20 by default. |

Each entry carries `value`, `kind` (`address` or `domain`), `reason`, `scope` (`tenant` for the space, `global` for the platform), `source` and `created_at`. `source` says where the entry comes from: who added it and their note, or the way the person unsubscribed. It is `null` for a dead address known across the platform. In the readable text, each line gives the reason, the source and the date.

In an assistant that displays MCP Apps views, `list_suppressions` comes with a view: who receives nothing more, why, and since when. See [Views](https://escouade.io/en/mail/docs/vues.md).

## For an agent

- A `recipient_suppressed` refusal is not to be worked around: stop writing to that address, from any inbox.
- A correspondent who asks, even politely, not to be contacted again gets blocked with `add_suppression`.
- In an `unsubscribed` thread, any send is refused. A `bounced` thread points to a failed address.
