> Pour un agent : la carte de la documentation d'Escouade Mail est sur https://escouade.io/mail/docs/llms.txt ; chaque page existe en Markdown, à la même adresse suffixée `.md`.

# Règles d'envoi

> Le serveur règle les envois. Chaque règle retient un message ou le refuse, et la réponse dit pourquoi. Les règles s'appliquent deux fois : à la création du message, puis au moment de l'envoi.

## Vue d'ensemble

| Règle | Seuil | Effet |
|---|---|---|
| [Montée progressive](#montee-progressive) | 5, 10, 15, puis 20 e-mails par jour et par boîte, semaine après semaine. | Retient : au-delà du palier, le message attend le jour ouvré suivant. |
| [Quota du jour](#quota-du-jour) | Par boîte : son palier, borné par son quota maximal. Par clé : un plafond, si elle en porte un. | Retient à la boîte. Refuse à la clé : `key_daily_cap`. |
| [Heures ouvrées](#heures-ouvrees) | Par défaut du lundi au vendredi, de 9 h à 18 h, heure de Paris, jours fériés exclus. | Retient : le message part au premier moment ouvert. |
| [Validation humaine](#validation-humaine) | Demandée par message, ou imposée par l'espace. | Retient : le message reste brouillon jusqu'à `approve_message`. |
| [Désinscription](#desinscription) | Un lien en un clic dans chaque e-mail ; une réponse « STOP ». | Refuse tout nouvel envoi à l'adresse : `recipient_suppressed`. |
| [Coupe-circuit](#coupe-circuit) | 5 % de rebonds (3 % pendant la montée progressive), ou 0,1 % de plaintes. | Suspend la boîte. Refuse : `inbox_suspended`. |

- **Retient** : le message attend, et la réponse donne le départ au plus tôt. Ce n'est pas une erreur : il ne faut pas le renvoyer.
- **Refuse** : la réponse porte un `code` stable, un `message` en français et une piste (`hint`). Voir [Erreurs](https://escouade.io/mail/docs/erreurs.md).

S'y ajoutent quatre contrôles : le [forfait](#forfait) de l'espace, le [doublon](#doublon), le [champ de fusion](#champ-de-fusion) oublié et l'[idempotence](https://escouade.io/mail/docs/messages.md#idempotence).

Dans les réponses du serveur, la montée progressive s'appelle « réchauffage », et les heures ouvrées « créneau d'envoi ».

## Montée progressive

Chaque boîte démarre à 5 e-mails par jour, puis passe à 10, 15 et 20 : un palier par semaine, à partir du jour de sa création. Le dernier palier tient ensuite.

| Semaine | Envois par jour |
|---|---|
| 1 | 5 |
| 2 | 10 |
| 3 | 15 |
| 4 et suivantes | 20 |

Un agent ne peut ni lever ni accélérer la montée. `inbox_status` rend la semaine en cours, le palier et les paliers à venir (`warmup`).

## Quota du jour

**Par boîte.** Le quota du jour est le plus petit de deux nombres : le palier de la semaine et le quota maximal de la boîte (20 par défaut). Il compte les messages partis depuis minuit, heure de Paris. Un brouillon ou un message en file ne le consomme qu'au moment de partir.

Quand le quota est atteint, le message suivant reste en file et part le jour ouvré suivant :

```text
Message msg_7f2a91c4e8b34d0fa6c25e1b9d3f7a48 en file dans le fil thr_0e5a7c2b9f1d48e6a3c7b5d0e2f9a814 : de agent@exemple.fr à nadia.morel@exemple.com, « Rendez-vous de jeudi ». Départ au plus tôt : mercredi 14 octobre à 9 h. Quota du jour de la boîte : 5/5 (semaine 1 du réchauffage, palier de 5 par jour).
```

**Par clé.** Une clé peut porter un plafond de messages par jour, toutes boîtes confondues. Il compte les messages créés dans la journée, brouillons compris. Au-delà, la création est refusée avec le code `key_daily_cap`, jusqu'au lendemain 0 h. La clé rendue par `sign_up` n'a pas de plafond.

## Heures ouvrées

Un message part dans le créneau d'envoi de l'espace. Par défaut : du lundi au vendredi, de 9 h à 18 h, heure de Paris, hors des onze jours fériés français. Hors créneau, le message attend le premier moment ouvert : un e-mail écrit le dimanche part le lundi.

- **Étalement.** Deux envois d'une même boîte sont espacés : 10 minutes par défaut, plus une part d'aléa.
- **Une réponse dans une conversation n'attend pas.** Dès que le correspondant a écrit dans le fil, `reply_to_thread` part sans attendre le créneau et passe devant les premiers messages en file. Elle compte toujours dans le quota du jour et respecte l'étalement. Une relance sans réponse, elle, attend le créneau.
- **`send_after`** repousse un départ : le créneau et les quotas s'appliquent ensuite.

Le créneau, les jours sans envoi et l'étalement sont des réglages de l'espace : son humain les change depuis son assistant, avec `update_settings`. `inbox_status` rend le créneau en clair (`send_window`), `get_settings` le détaille. Voir [Réglages de l'espace](https://escouade.io/mail/docs/espace.md).

## Validation humaine

Avec `requires_approval`, ou si l'espace l'impose, un message reste brouillon (`draft`). Seul un accès qui porte la permission `approve` le valide, avec `approve_message` : celui de l'humain, depuis son assistant branché à `https://mail.escouade.io/mcp`. La clé rendue par `sign_up` ne la porte pas : un agent ne valide pas ses propres envois. Voir [Brouillons et validation](https://escouade.io/mail/docs/brouillons.md).

## Désinscription

- Chaque e-mail porte un lien de désinscription en un clic (RFC 8058), dans ses en-têtes.
- Tant que le correspondant n'a pas écrit dans le fil, une mention de désinscription est ajoutée en pied du message.
- Une réponse « STOP » vaut désinscription.
- Une adresse désinscrite, une plainte ou une adresse morte ferment tout nouvel envoi : `recipient_suppressed`. Ce qui attendait de partir vers elle est annulé.

Voir [Désinscription et blocages](https://escouade.io/mail/docs/desinscription.md).

## Coupe-circuit

Le serveur juge les derniers envois de chaque boîte, par tranche de 100 au plus.

| Mesure | Seuil | Pendant la montée progressive |
|---|---|---|
| Rebonds | au-delà de 5 % | au-delà de 3 % |
| Plaintes (message signalé comme indésirable) | au-delà de 0,1 % | au-delà de 0,1 % |

Les parts se calculent sur 40 envois au moins : deux rebonds sur dix envois comptent pour 5 %, pas pour 20 %.

Au-delà d'un seuil, la boîte est suspendue : `status` = `suspended`, et la raison est écrite dans `status_reason`. Tout envoi est refusé avec le code `inbox_suspended`. La boîte continue de recevoir. La reprise est manuelle, par un administrateur d'Escouade Mail : avant de la demander, vérifiez la liste de destinataires.

## Forfait

Le forfait de l'espace décide de ce qu'une boîte peut envoyer, avant les autres règles.

| Situation | Ce qui part | Sinon |
|---|---|---|
| Avant le paiement | Un envoi de test (`test`), vers l'humain de l'espace ou une autre de ses boîtes. Un brouillon se prépare, mais ne se valide pas. | Refus : `payment_required`. |
| Forfait payé, boîte du domaine commun `subagentmail.fr` | Une réponse à un correspondant qui a écrit dans le fil. | Refus : `own_domain_required`. |
| Forfait payé, boîte du domaine du client | Un premier message, une réponse, une relance. | — |
| Volume du mois atteint | Rien, jusqu'à la période suivante. Un envoi de test part toujours. | Retient : le message reste en file. |

- **Le volume du mois** compte les e-mails partis depuis le début de la période payée : 800, 2 000 ou 6 000 selon le forfait. Un envoi de test ne compte pas.
- **Le volume atteint n'est pas un refus.** Les messages attendent, réponses comprises, et partent à la période suivante. `billing_status` donne le volume parti et la fin de la période.
- **Le quota du jour ne dépend pas du forfait** : 20 e-mails par jour et par boîte, après la montée progressive.
- **Un paiement en retard** laisse l'envoi ouvert trois jours. Ensuite, l'espace est traité comme avant le paiement.

Les forfaits, leurs prix et le paiement : [Prix et paiement](https://escouade.io/offre).

## Doublon

Une boîte n'écrit pas deux premiers messages au même destinataire en 30 jours. Le second `send_email` est refusé avec le code `duplicate_recipient`, et la piste donne le fil existant. Pour relancer, répondez dans ce fil avec `reply_to_thread` : une réponse dans un fil n'est pas un doublon. Un envoi de test (`test`) échappe à la règle.

## Champ de fusion

Un champ entre doubles accolades resté dans le sujet, le texte ou le HTML, comme `{{prenom}}`, bloque l'envoi : code `unresolved_placeholder`. Seul `{{unsubscribe_url}}` est accepté : le serveur le remplace par le lien de désinscription.

## Ce qu'un agent ne peut pas faire

- Lever ou accélérer la montée progressive.
- Envoyer hors du créneau, sauf une réponse dans une conversation.
- Valider ses propres brouillons.
- Payer le forfait, ou le résilier.
- Écrire un premier message depuis une boîte du domaine commun.
- Lever une désinscription, une plainte ou une adresse morte.
- Reprendre une boîte suspendue.
- Régler l'espace, créer ou révoquer une clé, déclarer un webhook, clore l'espace.
