# email.campaigns.get

Lire une campagne, ses messages, ses liens, son calendrier et ses résultats.

POST `/api/mcp/v1/email.campaigns.get` · contrat 2.0.0 · OAuth `mcp:read` · **aucune offre requise**.

Outil MCP : [`prescriptio_campagne`](/docs/api/prescriptio_campagne.md) avec action=statut ; même handler métier.

## Entrée

```json
{
  "additionalProperties": false,
  "properties": {
    "campagne_id": {
      "description": "UUID de la campagne. Requis partout sauf lister, creer, stats (global), desinscrits, expediteur et quota.",
      "type": "string"
    }
  },
  "required": [
    "campagne_id"
  ],
  "type": "object"
}
```

## Exemple synthétique

```json
{
  "campagne_id": "00000000-0000-0000-0000-000000000001"
}
```

## Sortie

```json
{
  "properties": {
    "action": {
      "enum": [
        "campagne_lue"
      ],
      "type": "string"
    },
    "fields": {
      "properties": {
        "calendrier": {
          "description": "Au plus 200 touches dans l'ordre du calendrier ; cette liste est un aperçu borné. Les statistiques et le suivi agrègent toute la campagne.",
          "items": {
            "properties": {
              "clics": {
                "type": "integer"
              },
              "email": {
                "type": "string"
              },
              "entreprise_cle": {
                "type": "string"
              },
              "envoye_le": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "erreur": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "fonction": {
                "type": "string"
              },
              "id": {
                "type": "string"
              },
              "livraison": {
                "type": "string"
              },
              "mode": {
                "type": "string"
              },
              "nom": {
                "type": "string"
              },
              "ouvertures": {
                "type": "integer"
              },
              "palier": {
                "type": "integer"
              },
              "planifie_le": {
                "type": "string"
              },
              "prenom": {
                "type": "string"
              },
              "rang": {
                "type": "integer"
              },
              "societe": {
                "type": "string"
              },
              "source": {
                "type": "string"
              },
              "statut": {
                "type": "string"
              },
              "variante": {
                "type": "string"
              },
              "ville": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "email",
              "prenom",
              "nom",
              "societe",
              "ville",
              "fonction",
              "entreprise_cle",
              "statut",
              "mode",
              "source",
              "variante",
              "planifie_le",
              "livraison",
              "rang",
              "palier",
              "clics",
              "ouvertures",
              "envoye_le",
              "erreur"
            ],
            "type": "object"
          },
          "maxItems": 200,
          "type": "array"
        },
        "campagne": {
          "properties": {
            "cree_le": {
              "type": "string"
            },
            "demarre_le": {
              "type": [
                "string",
                "null"
              ]
            },
            "equipe_jours": {
              "type": "integer"
            },
            "expediteur": {
              "type": "string"
            },
            "expediteur_etat": {
              "type": "string"
            },
            "expediteur_nom": {
              "type": "string"
            },
            "id": {
              "type": "string"
            },
            "nom": {
              "type": "string"
            },
            "organisation_nom": {
              "type": "string"
            },
            "relance_jours": {
              "type": "integer"
            },
            "relances_max": {
              "type": "integer"
            },
            "repondre_a": {
              "type": "string"
            },
            "statut": {
              "type": "string"
            }
          },
          "required": [
            "id",
            "nom",
            "statut",
            "expediteur",
            "expediteur_nom",
            "repondre_a",
            "expediteur_etat",
            "organisation_nom",
            "cree_le",
            "equipe_jours",
            "relance_jours",
            "relances_max",
            "demarre_le"
          ],
          "type": "object"
        },
        "champs_disponibles": {
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "champs_sans_valeur": {
          "items": {
            "properties": {
              "champ": {
                "type": "string"
              },
              "manquants": {
                "type": "integer"
              }
            },
            "required": [
              "champ",
              "manquants"
            ],
            "type": "object"
          },
          "type": "array"
        },
        "liens": {
          "items": {
            "properties": {
              "idx": {
                "type": "integer"
              },
              "libelle": {
                "type": "string"
              },
              "url": {
                "type": "string"
              }
            },
            "required": [
              "url",
              "libelle",
              "idx"
            ],
            "type": "object"
          },
          "type": "array"
        },
        "stats": {
          "properties": {
            "annules": {
              "type": "integer"
            },
            "clics": {
              "type": "integer"
            },
            "contacts_ayant_clique": {
              "type": "integer"
            },
            "desinscrits": {
              "type": "integer"
            },
            "destinataires": {
              "type": "integer"
            },
            "echecs": {
              "type": "integer"
            },
            "en_journal": {
              "type": "integer"
            },
            "envoyes": {
              "type": "integer"
            },
            "planifies": {
              "type": "integer"
            },
            "repondus": {
              "type": "integer"
            }
          },
          "required": [
            "destinataires",
            "planifies",
            "envoyes",
            "echecs",
            "annules",
            "desinscrits",
            "repondus",
            "clics",
            "contacts_ayant_clique",
            "en_journal"
          ],
          "type": "object"
        },
        "suivi": {
          "description": "Mesures enregistrées par campagne. Ouvertures : destinataires uniques, indicatives. Livraisons : statuts fournisseur (sent = livré, failed = échec), distincts de l'acceptation. Une liste vide ne confirme aucune livraison. Le relevé global ne liste que les campagnes ayant une mesure.",
          "items": {
            "properties": {
              "campagne_id": {
                "type": "string"
              },
              "contacts_ayant_ouvert": {
                "type": "integer"
              },
              "livraisons": {
                "items": {
                  "properties": {
                    "nombre": {
                      "type": "integer"
                    },
                    "statut": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "statut",
                    "nombre"
                  ],
                  "type": "object"
                },
                "type": "array"
              }
            },
            "required": [
              "campagne_id",
              "contacts_ayant_ouvert",
              "livraisons"
            ],
            "type": "object"
          },
          "type": "array"
        },
        "variantes": {
          "items": {
            "properties": {
              "contenu": {
                "description": "Contenu du constructeur, avec blocs quand le message a été composé par blocs.",
                "type": "object"
              },
              "corps": {
                "type": "string"
              },
              "etiquette": {
                "type": "string"
              },
              "format": {
                "type": "string"
              },
              "id": {
                "type": "string"
              },
              "objet": {
                "type": "string"
              },
              "ordre": {
                "type": "integer"
              }
            },
            "required": [
              "id",
              "etiquette",
              "objet",
              "corps",
              "format",
              "ordre",
              "contenu"
            ],
            "type": "object"
          },
          "type": "array"
        }
      },
      "required": [
        "campagne",
        "variantes",
        "liens",
        "stats",
        "calendrier",
        "suivi",
        "champs_disponibles",
        "champs_sans_valeur"
      ],
      "type": "object"
    },
    "note": {
      "type": "string"
    },
    "ok": {
      "const": true
    },
    "url": {
      "type": "string"
    }
  },
  "required": [
    "ok",
    "action",
    "fields"
  ],
  "type": "object"
}
```

## 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 (`prescriptio_dce`, `prescriptio_mairies` 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.

[Authentification, quotas, pagination et erreurs](/docs/reference/concepts.md). Les propriétés additionnelles des résultats historiques restent autorisées ; ce schéma n'invente pas les champs manquants.
