> 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`.

# `save_campaign`

> Crée ou modifie un brouillon : une boîte, une audience et une séquence de 1 à 4 étapes, avec 1 à 3 variantes par étape.

## En bref

| Propriété | Valeur |
|---|---|
| Titre | Préparer une campagne |
| Outil MCP | `save_campaign`, sur `https://api.subagent.fr/mcp` |
| Appelé par | l’assistant et la vue |
| Appel HTTP | `POST https://api.subagent.fr/v1/save_campaign` |
| Accès | permission `send` |
| État de l'espace | vérifié : sinon, refus `space_unverified` |
| Effet | écriture |
| Vue dans l'assistant | non |

## Ce que fait l'outil

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

> Crée ou modifie un brouillon : une boîte, une audience et une séquence de 1 à 4 étapes, avec 1 à 3 variantes par étape. Les champs `{{prenom}}`, `{{societe}}`… viennent des contacts. Un champ vide bloque l’envoi. Seul `{{unsubscribe_url}}` est remplacé au départ.

## Paramètres

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

| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
| `campaign_id` | identifiant `cmp_…` | non | Brouillon à modifier, facultatif. |
| `name` | texte | oui | Nom. 160 caractères au plus. |
| `inbox_id` | identifiant `inb_…` | oui | Boîte expéditrice. |
| `from_address` | texte | non | Adresse principale ou alias de cette boîte. |
| `audience_id` | identifiant `aud_…` | non | Audience. |
| `reply_to` | texte | non | Adresse de réponse facultative. |
| `steps` | liste | oui |  |

## 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 |
|---|---|---|
| `campaign` | objet | Une campagne : id (cmp_…), name, status (draft, scheduled, running, paused, completed, stopped), archived, `inbox_id`, `from_address`, `audience_id`, `reply_to`, steps (de 1 à 4 étapes : `delay_days` et variants, chacune avec subject, text, html), `starts_at`, `status_reason`, source, previous (dans `get_campaign` : les étapes qu’une correction a remplacées, avec l’auteur et l’heure de la correction), `created_at`, `updated_at`. |

## Exemple d'appel

Les valeurs sont fictives.

HTTP :

```sh
curl -X POST https://api.subagent.fr/v1/save_campaign \
  -H "Authorization: Bearer $SUBAGENT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Rentrée",
  "inbox_id": "inb_3f9c2a7e5b1d4c8e9a0f6b2d7c4e1a95",
  "audience_id": "aud_3c8f1a5e9d2b47c6a0e4f81b7d5c9e26",
  "steps": [
    {
      "variants": [
        {
          "subject": "Vos chantiers de la rentrée",
          "text": "Bonjour {{prenom}},\n\nUn mot sur vos chantiers.\n\n{{unsubscribe_url}}"
        }
      ]
    }
  ]
}'
```

MCP (`tools/call`) :

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "save_campaign",
    "arguments": {
      "name": "Rentrée",
      "inbox_id": "inb_3f9c2a7e5b1d4c8e9a0f6b2d7c4e1a95",
      "audience_id": "aud_3c8f1a5e9d2b47c6a0e4f81b7d5c9e26",
      "steps": [
        {
          "variants": [
            {
              "subject": "Vos chantiers de la rentrée",
              "text": "Bonjour {{prenom}},\n\nUn mot sur vos chantiers.\n\n{{unsubscribe_url}}"
            }
          ]
        }
      ]
    }
  }
}
```

## Refus possibles

| Code | HTTP | Ce qui s'est passé | Que faire |
|---|---|---|---|
| `campaign_not_editable` | 409 | La campagne n'est plus un brouillon (lancée, terminée, arrêtée) ou vient d'un autre outil : elle ne se modifie plus. | La dupliquer avec `campaign_action` (`duplicate`), puis corriger la copie. |
| `audience_scope` | 403 | Les audiences demandent un accès à toutes les boîtes de l'espace ; cette clé est limitée à certaines. | Passer par une clé qui accède à tout l'espace, ou par l'assistant de l'humain. |
| `client_domain_required` | 422 | Une application de la famille n'écrit un premier message, ne prépare et ne lance une campagne que depuis une boîte et une adresse d'un domaine vérifié de l'espace. Le domaine commun et celui de la marque restent aux agents et aux humains de l'espace. | Choisir une boîte d'un domaine que l'espace a prouvé : `list_domains`, puis `list_inboxes`. |

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

## Voir aussi

- [Campagnes : save_campaign](https://escouade.io/mail/docs/campagnes.md#save_campaign)
- [Campagnes : le parcours](https://escouade.io/mail/docs/campagnes.md#parcours)
- [`preview_campaign`](https://escouade.io/mail/docs/reference/preview_campaign.md)
- [`campaign_action`](https://escouade.io/mail/docs/reference/campaign_action.md)
- [Tous les outils](https://escouade.io/mail/docs/reference/index.md)
