> Ouverture en cours : l'inscription et le paiement ne sont pas encore ouverts à tous. L'état du jour : https://subagent.fr/docs/etat.md
>
> Pour un agent : la carte du site est sur https://subagent.fr/llms.txt ; chaque page existe en Markdown, à la même adresse suffixée `.md`.

# `reply_to_thread`

> Répond dans un fil existant, au correspondant du fil : sujet « Re: … » et en-têtes In-Reply-To / References corrects, pour que la réponse s’affiche dans la même conversation chez le destinataire.

## En bref

| Propriété | Valeur |
|---|---|
| Titre | Répondre dans un fil |
| Outil MCP | `reply_to_thread`, sur `https://api.subagent.fr/mcp` |
| Appel HTTP | `POST https://api.subagent.fr/v1/reply_to_thread` |
| Accès | permission `send` |
| État de l'espace | vérifié : sinon, refus `space_unverified` |
| Effet | écriture |
| Vue dans l'assistant | oui : voir [Vues](https://subagent.fr/docs/vues.md) |

## Ce que fait l'outil

Le serveur décrit l'outil ainsi à l'agent qui se branche :

> Répond dans un fil existant, au correspondant du fil : sujet « Re: … » et en-têtes In-Reply-To / References corrects, pour que la réponse s’affiche dans la même conversation chez le destinataire. Sert aussi à relancer : une réponse dans un fil n’est pas soumise à la règle de doublon, mais reste soumise au blocage, aux quotas, au créneau et à la validation humaine. Dès que le correspondant a écrit dans le fil, c’est une conversation : la réponse part sans attendre le créneau et sans pied de désinscription (le lien en un clic reste dans ses en-têtes) ; elle compte toujours dans le quota du jour, respecte l’étalement entre deux envois et reste soumise au blocage et à la validation humaine.

## Paramètres

`reply_to_thread` accepte ces paramètres. Un paramètre inconnu est refusé avec le code `invalid_argument`.

| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
| `thread_id` | identifiant `thr_…` | oui | Le fil (thr_…, voir `list_threads`). |
| `subject` | texte | non | Sujet, facultatif : « Re: » + sujet du fil par défaut. 300 caractères au plus. |
| `text` | texte | oui | Texte brut du message (obligatoire). Écrivez `{{unsubscribe_url}}` pour placer vous-même le lien de désinscription ; sinon Subagent ajoute une mention en pied, tant que le correspondant n’a pas écrit dans le fil. Aucun autre `{{champ}}` n’est accepté : remplacez-les avant. |
| `html` | texte | non | Version HTML facultative, même contenu que text. |
| `reply_to` | texte | non | Adresse de réponse, si elle diffère de la boîte. |
| `metadata` | objet | non | Données libres de l’agent (8 000 caractères au plus), rendues telles quelles dans les lectures et les webhooks. |
| `requires_approval` | booléen | non | `true` : le message reste brouillon jusqu’à ce qu’un humain le valide (`approve_message`). Certains espaces l’imposent toujours. |
| `send_after` | date | non | Pas avant cette date (ISO 8601, ou heure de Paris sans fuseau). Le créneau (sauf pour une réponse dans une conversation) et les quotas s’appliquent ensuite. |
| `idempotency_key` | texte | non | Clé unique de cet envoi (1 à 255 caractères). Rejouer la même clé avec le même contenu rend le message déjà créé ; avec un contenu différent, refus explicite. Recommandée pour tout réessai. |

## Résultat

L'outil rend un texte lisible en français et un objet structuré (`structuredContent`). En HTTP, la réponse est cet objet.

| Champ | Type | Contenu |
|---|---|---|
| `estimated_send_at` | texte ou `null` | Départ au plus tôt (estimation : créneau, étalement, quota). |
| `inbox` | objet | Une boîte. Voir [les champs d'une boîte](https://subagent.fr/docs/boites.md#champs). |
| `message` | objet | Un message. Voir [les champs d'un message](https://subagent.fr/docs/messages.md#champs). |
| `replayed` | booléen | `true` : même clé d’idempotence et même contenu, rien de nouveau n’a été créé. |
| `thread` | objet | Un fil. Voir [les champs d'un fil](https://subagent.fr/docs/fils.md#champs). |

## Exemple d'appel

Les valeurs sont fictives.

HTTP :

```sh
curl -X POST https://api.subagent.fr/v1/reply_to_thread \
  -H "Authorization: Bearer $SUBAGENT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "thread_id": "thr_b81f4c6a2d9e47035c1a8e6f0b4d2c97",
  "text": "Bonjour Madame Morel,\n\nC'\''est noté pour vendredi, à la même heure.\n\nAtelier Exemple",
  "idempotency_key": "rdv-morel-reponse-1"
}'
```

MCP (`tools/call`) :

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "reply_to_thread",
    "arguments": {
      "thread_id": "thr_b81f4c6a2d9e47035c1a8e6f0b4d2c97",
      "text": "Bonjour Madame Morel,\n\nC'est noté pour vendredi, à la même heure.\n\nAtelier Exemple",
      "idempotency_key": "rdv-morel-reponse-1"
    }
  }
}
```

## Refus possibles

| Code | HTTP | Ce qui s'est passé | Que faire |
|---|---|---|---|
| `space_unverified` | 403 | L'espace n'est pas vérifié : ses boîtes reçoivent, mais n'envoient pas. | Demander à l'humain le code à 6 chiffres, puis appeler `verify`. S'il n'a rien reçu, ou si aucun e-mail n'est rattaché à l'espace : `attach_human`. |
| `payment_required` | 402 | L'espace n'a pas de forfait en cours : sa boîte reçoit, prépare des brouillons et n'écrit qu'à son humain. Le refus vaut pour un envoi à un tiers, la validation d'un brouillon, une seconde boîte et `add_domain`. | Appeler `subscribe`, après l'accord de l'humain, et lui remettre le lien de paiement. Ensuite, `billing_status` dit si le forfait est en cours. |
| `own_domain_required` | 422 | La boîte est sur le domaine commun : elle ne fait que répondre à qui lui a écrit. Un premier message, ou une relance sans réponse, n'en part pas. | Enregistrer le domaine de l'humain (`add_domain`), le faire vérifier (`verify_domain`), y créer une boîte (`create_inbox`) et écrire depuis elle. |
| `not_found` | 404 | L'objet n'existe pas pour cette clé. | Vérifier l'identifiant : il vient de `list_inboxes`, `list_threads`, `get_thread` ou `list_drafts`. |
| `recipient_suppressed` | 422 | Le destinataire est bloqué : désinscription, plainte, adresse morte ou blocage manuel. | Ne plus écrire à cette adresse, depuis aucune boîte. |
| `key_daily_cap` | 429 | Le plafond de messages par jour de la clé est atteint. | Reprendre le lendemain, à partir de 0 h, heure de Paris. |
| `inbox_suspended` | 409 | Le coupe-circuit a suspendu la boîte. La raison est dans le message. | Vérifier la liste de destinataires. La reprise est manuelle, par un administrateur de Subagent : l'humain la demande avec `request_inbox_review`. |
| `domain_not_verified` | 409 | Le domaine de la boîte n'est pas encore vérifié. | Publier ses enregistrements DNS, puis appeler `verify_domain`. |
| `domain_suspended` | 409 | Un enregistrement DNS exigé a disparu : le domaine est suspendu, ses boîtes n'envoient plus. | Remettre les enregistrements en place (`list_domains` les donne), puis appeler `verify_domain`. |
| `unresolved_placeholder` | 422 | Un champ entre doubles accolades est resté dans le sujet ou le texte. | Remplacer chaque champ par sa valeur. Seul `{{unsubscribe_url}}` est accepté. |
| `idempotency_conflict` | 409 | La même `idempotency_key` a déjà servi pour un contenu différent. | Même message : réutiliser la clé telle quelle. Nouveau message : en prendre une nouvelle. |
| `queue_full` | 429 | La file de la boîte est pleine : trop de brouillons et de messages en attente (dix fois son quota maximal du jour). | Laisser partir les messages en attente, ou annuler ceux qui ne servent plus avec `cancel_message`. |

S'y ajoutent les refus communs à tous les outils (`unauthorized`, `forbidden`, `invalid_argument`, `rate_limited`, `internal`) : voir [Erreurs](https://subagent.fr/docs/erreurs.md#acces).

## Voir aussi

- [Fils : reply_to_thread](https://subagent.fr/docs/fils.md#reply_to_thread)
- [Guide : répondre à un correspondant](https://subagent.fr/docs/guide-repondre.md)
- [`get_thread`](https://subagent.fr/docs/reference/get_thread.md)
- [`send_email`](https://subagent.fr/docs/reference/send_email.md)
- [`cancel_message`](https://subagent.fr/docs/reference/cancel_message.md)
- [Tous les outils](https://subagent.fr/docs/reference/index.md)
