# campagne_email_modeles

Gérer les modèles de campagnes e-mail, en texte, HTML assaini ou blocs. Distinct des trames d'e-mails individuels.

| | |
|---|---|
| Effets | lecture et écriture dans l'espace du compte |
| Portée OAuth | `mcp:write` |
| Offre requise | aucune — ouvert à tous les comptes |
| Données lues | l'espace du compte authentifié (ses alertes, ses dossiers, sa base) |
| Distribution | MCP historique |

Cet outil est aussi distribué en REST : `POST /api/mcp/v1/email.templates.list` (portée `mcp:read`), documenté sur [email.templates.list](/docs/api/email.templates.list.md).

## Paramètres

| Paramètre | Type | Requis | Bornes | Description |
|---|---|---|---|---|
| `action` | `lister` · `enregistrer` · `appliquer` · `supprimer` · `creer` · `modifier` | — | défaut `"lister"` | — |
| `adresse_test` | texte | — | — | tester : adresse destinataire du test (5 essais maximum en 10 minutes par espace). En local, le message est compose sans envoi reel. |
| `audience_id` | texte | — | format `^[0-9a-fA-F-]{36}$` | — |
| `blocs` | liste de objet | — | min. éléments 1, max. éléments 30 | variante avec format=builder : blocs dans l'ordre. Images HTTPS, boutons HTTPS ou [lien1] à [lien3]. |
| `boite` | texte | — | — | expediteur : la partie avant l'arobase proposee pour ce domaine (defaut contact). |
| `campagne_id` | texte | — | — | UUID de la campagne. Requis partout sauf lister, creer, stats (global), desinscrits, expediteur et quota. |
| `cle_idempotence` | texte | — | format `^[!-~]+$`, min. caractères 1, max. caractères 128 | Clé stable pour un envoi unitaire. Un rejeu du même contenu retrouve le même message ; un autre contenu est refusé. Ne pas renouveler la clé après un délai dépassé. |
| `contacts` | liste de texte | — | max. éléments 2000 | Identifiants base:<UUID> ou crm:<UUID> déjà détenus par l'organisation. |
| `corps` | texte | — | — | creer/variante : le message. Memes champs. Pour un lien mesure, ecrire [lien1], [lien2] et les declarer par action liens. |
| `curseur` | texte | — | format `^[0-9]+$`, max. caractères 19 | Dernier identifiant traité ; 0 pour commencer. Conserver le curseur uniquement après traitement réussi de toute la page. |
| `decalage` | entier | — | min 0, max 1000000 | — |
| `depart` | texte | — | — | planifier : date et heure locales de Paris, AAAA-MM-JJTHH:MM (ex. 2026-09-22T09:00). Future. Les week-ends sont repousses au lundi. |
| `domaine` | texte | — | — | expediteur : le domaine a declarer ou a retirer ; verifier_domaine : le domaine declare a controler (ex. masociete.fr). |
| `email` | texte | — | — | desinscrits : adresse a ajouter a la liste de suppression. |
| `envoi_id` | texte | — | format `^[0-9a-fA-F-]{36}$` | — |
| `equipe_jours` | entier | — | min 0, max 30 | modifier : nombre de jours entre le decideur et son equipe (defaut 3). |
| `etiquette` | texte | — | — | variante : etiquette courte (B, C, « version courte »). Avec objet et corps, ajoute une variante ; avec variante_id, reecrit celle-ci. |
| `expediteur` | texte | — | — | creer/modifier : adresse d'expedition. Doit appartenir a un domaine VERIFIE pour cet espace (action expediteur les liste) ou au domaine de repli de la plateforme. Laisser vide prend l'adresse par defaut de l'espace. Un domaine seulement declare est refuse : sans SPF/DKIM le message part en indesirable. |
| `expediteur_nom` | texte | — | — | creer/modifier : le nom affiche par la messagerie du destinataire. |
| `filtre` | texte | — | — | destinataires : texte libre sur le nom, la societe, la ville ou l'adresse. |
| `format` | `texte` · `html` · `builder` | — | — | variante : format d'une version existante. html est assaini ; builder compile les blocs comme l'interface. |
| `liens` | liste de texte | — | max. éléments 10 | liens : les adresses http(s) mesurees, dans l'ordre. La premiere est [lien1]. Remplace la liste existante. |
| `limite` | entier | — | min 1, max 2000 | destinataires : nombre maximum de personnes (defaut 100). |
| `liste_id` | texte | — | — | UUID d'une liste de la base, ou audience:<UUID> pour une audience enregistrée. |
| `mode` | `apercu` · `constituer` | — | — | destinataires : apercu compte sans rien ecrire, constituer ajoute a la campagne. |
| `modele_id` | texte | — | — | modele_appliquer/modele_supprimer : identifiant rendu par modeles, y compris catalogue:<nom> pour appliquer un modèle fourni. |
| `nature` | `liste` · `segment` | — | — | — |
| `nom` | texte | — | — | creer/modifier : nom de la campagne (120 caracteres au plus). |
| `nom_modele` | texte | — | — | modele_sauver : nom du modèle enregistré à partir d'une variante existante (120 caractères maximum). |
| `objet` | texte | — | — | creer/variante : objet du message. Champs : [prenom] [nom] [entreprise] [ville] [fonction] (l'accent est optionnel : [prenom] et [prénom] valent pareil, [societe] vaut [entreprise]). |
| `periode` | `campagne` · `canal` | — | — | stats : campagne (le detail d'une campagne, par contact) ou canal (les chiffres du jour, des 7 et des 30 jours, forme commune aux canaux de prospection). |
| `personnalisation` | objet | — | — | — |
| `personnalisation.fonction` | texte | — | max. caractères 200 | — |
| `personnalisation.nom` | texte | — | max. caractères 200 | — |
| `personnalisation.prenom` | texte | — | max. caractères 200 | — |
| `personnalisation.societe` | texte | — | max. caractères 200 | — |
| `personnalisation.ville` | texte | — | max. caractères 200 | — |
| `plafond_jour` | entier | — | min 1, max 20000 | quota : envois au plus par jour pour cet espace. |
| `plafond_mois_inclus` | entier | — | min 0, max 200000 | quota : envois compris dans l'offre, par mois. |
| `prefere` | booléen | — | — | expediteur : faire de ce domaine celui d'ou l'espace ecrit par defaut. Un seul par espace. |
| `prix_unitaire_cents` | entier | — | min 0, max 1000 | quota : prix HT en centimes de l'envoi au-dela du forfait. |
| `rang_max` | entier | — | min 1, max 4 | destinataires : 1 decideurs seuls, 2 jusqu'a prioritaire, 3 jusqu'a secondaire, 4 tout le monde (defaut). |
| `relance_jours` | entier | — | min 1, max 60 | modifier : intervalle entre relances (defaut 4). |
| `relances_max` | entier | — | min 0, max 3 | modifier : nombre de relances (defaut 2). |
| `repondre_a` | texte | — | — | creer/modifier : la boite ou arrivent les reponses (celle de l'utilisateur). Obligatoire avant de planifier. |
| `retirer` | booléen | — | — | expediteur : avec domaine, supprime la declaration. Les campagnes deja ecrites sous ce domaine ne sont pas reecrites : elles passent en refus a l'envoi. |
| `source` | `tous` · `crm` · `base` | — | — | destinataires : ou chercher. crm = le carnet de contacts, base = Ma base (coordonnees REVELEES seulement), tous = les deux. |
| `taille_page` | entier | — | min 1, max 200 | — |
| `variante_id` | texte | — | — | variante : UUID d'une variante existante a reecrire. |

Tout autre paramètre est refusé (`additionalProperties: false`).

## Exemple d'appel

_exemple synthétique du contrat REST, adapté à l'action MCP._

```json
{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "action": "lister"
    },
    "name": "campagne_email_modeles"
  }
}
```

En HTTP, c'est ce corps que l'on poste :

```bash
curl -sS https://prescriptio.fr/api/mcp \
  -H 'Authorization: Bearer <jeton>' \
  -H 'Content-Type: application/json' \
  -d '{"id":1,"jsonrpc":"2.0","method":"tools/call","params":{"arguments":{"action":"lister"},"name":"campagne_email_modeles"}}'
```

## Forme de la réponse

Le résultat est enveloppé par le protocole : un bloc `content[0].text` qui porte le JSON sérialisé, et `structuredContent` qui porte le même objet. Le squelette ci-dessous donne les **types**, jamais des valeurs réelles.

```json
{
  "action": "modeles_lus",
  "fields": {
    "modeles": [
      {
        "contenu": {},
        "corps": "<texte>",
        "format": "<texte>",
        "id": "<texte>",
        "nom": "<texte>",
        "objet": "<texte>"
      }
    ]
  },
  "ok": true,
  "url": "<texte>"
}
```

Un champ absent ou `null` n'est ni un zéro ni une estimation : la source ne l'a pas renseigné. Les propriétés additionnelles restent autorisées ; ce squelette n'invente pas les champs manquants.

## Erreurs

Le connecteur MCP renvoie une erreur JSON-RPC pour ce qui empêche l'appel, et une erreur *métier* (`isError`) lisible par le modèle pour ce que l'appel n'a pas pu faire.

| Code JSON-RPC | Quand | Que faire |
|---|---|---|
| `-32601` | Outil inconnu | Appeler `tools/list` ; ne pas deviner un nom |
| `-32602` | Argument absent ou hors schéma | Corriger l'argument nommé dans le message |
| `-32003` | Portée OAuth absente de l'autorisation | Reconnecter en acceptant `mcp:read` ou `mcp:write` |
| `-32004` | Quota dépassé | Attendre le délai indiqué ; ne jamais boucler |
| `-32603` | Dépendance indisponible | Réessayer plus tard ; ne pas rejouer une écriture sans vérifier |

Sur les routes REST `/api/mcp/v1/*`, les mêmes situations sont des codes HTTP : `400 invalid_arguments` / `invalid_cursor`, `401 unauthenticated`, `403 insufficient_scope` / `access_denied` / `user_required` / `organization_required` / `role_denied`, `404 not_found`, `409 conflict`, `429 quota_exceeded` (avec `Retry-After` quand il est connu), `503 unavailable`, `504 timeout`. Le corps porte `error.code`, `error.message`, `error.retry_after_seconds` et `api_contract_version`.

⚠ Un message d'erreur n'est jamais une donnée : ne pas le recopier comme un fait, et ne pas inventer un identifiant ou une URL qu'il ne contient pas.

## Quotas

Un appel compte pour **une unité** dans les deux compteurs d'appels, partagés entre le connecteur MCP et les routes REST :

| Compteur | Compte gratuit | Abonné | Accès interne |
|---|---|---|---|
| Appels / 24 h glissantes | 100 | 5000 | illimité |
| Appels / 60 s (anti-rafale) | 5 | 30 | illimité |
| Dossiers distincts / jour civil (Paris) | 5 | 500 | illimité |

Cet outil ne consomme aucune unité de dossier : chercher est gratuit, c'est la lecture d'un dossier (`marches_dce`, `mairies_deliberations` et leurs téléchargements) qui est décomptée.

**Aucun outil n'est réservé à une offre** (décision du 2026-09-17) : un compte gratuit voit et appelle le catalogue entier, ce sont ces plafonds qui bornent son usage.

## Voir aussi

[Référence technique](/docs/reference/concepts.md) · [Tous les outils](/docs/api/index.md) · [OpenAPI](/openapi.json) · [Texte pour agents](/llms-full.txt)
