# Référence de l'API VaEmail

Générée depuis la spécification OpenAPI, elle-même dérivée des routes réellement servies.
Ne pas éditer à la main : `php artisan docs:generer`.

Spécification complète : https://app.vaemail.fr/openapi.json
Capacités du service : https://app.vaemail.fr/api/v1/capabilities

## Authentification

Toutes les routes, sauf `/api/v1/capabilities`, attendent la clé du compte en en-tête :

```
api-key: swm_votre_cle
```

`X-Api-Key` est accepté aussi, par compatibilité.

## Portées

Une clé peut être restreinte à certaines portées. Une clé qui n'en déclare aucune les a toutes.

| Portée | Ce qu'elle autorise |
| --- | --- |
| `email.send` | Envoyer des emails (transactionnel et campagnes). |
| `email.read_status` | Lire le statut de livraison des messages. |
| `domain.read` | Lire les domaines et leur authentification. |
| `domain.write` | Déclarer et vérifier un domaine. |
| `contacts.read` | Lire les contacts et les listes. |
| `contacts.write` | Créer et modifier les contacts et les listes. |
| `analytics.read` | Lire les statistiques et la délivrabilité. |
| `settings.write` | Modifier les réglages du tenant (filtres de stats, etc.). |
| `billing.read` | Lire la consommation et les quotas. |
| `smtp.send` | Envoyer par le relais SMTP entrant (smtp.vaemail.fr). |
| `events.write` | Envoyer des événements personnalisés (POST /v3/events). |

## Découverte

Ce que le service sait faire, sans authentification.

### `GET /api/v1/capabilities`

Ce que le service sait faire

Premier appel utile : décrit le produit, ses interfaces, ses limites et ses portées, sans clé d'API. Sert à décider si VaEmail couvre un besoin avant même d'ouvrir un compte.

### `GET /api/v1/health`

État du service

Base de données, file d'attente et transporteur. Répond 503 si la base est injoignable.

## Transactionnel

Envoi unitaire déclenché par une application ou un agent.

### `POST /api/v1/transactional/send`

Envoyer un email

Met un message en file et répond immédiatement 202 avec son identifiant : la réponse dit que le message est ACCEPTÉ, pas qu'il est arrivé. Pour la remise, interroger GET /api/v1/messages/{id}.

Portée de clé nécessaire : `email.send`.
Accepte l'en-tête `Idempotency-Key` : une relance rejoue la réponse au lieu de refaire l'action.
Débit : 60 requêtes par minute.

### `POST /v3/smtp/email`

Envoyer un email (schéma Brevo)

Même schéma que `POST https://api.brevo.com/v3/smtp/email`. Pour un nouveau développement, préférer `/api/v1/transactional/send`, qui rend des erreurs structurées.

Débit : 300 requêtes par minute.

### `GET /v3/smtp/templates`

Lister les templates transactionnels

Lister les templates transactionnels

### `POST /v3/transactionalSMS/sms`

Envoyer un SMS (schéma Brevo)

Même schéma que `POST https://api.brevo.com/v3/transactionalSMS/sms`. Envoi réel via AWS End User Messaging SMS. `type=marketing` est refusé hors 8h-20h heure de Paris, le dimanche et les jours fériés français.

Débit : 300 requêtes par minute.

## Messages

Suivi de livraison et vérification avant envoi.

### `GET /api/v1/messages`

Lister les messages

Du plus récent au plus ancien. Pagination par curseur : rappeler l'endpoint avec `cursor` = `next_cursor`.

Portée de clé nécessaire : `email.read_status`.

Paramètres :

- `status` : Filtre : queued, sent, delivered, failed, suppressed, held, cancelled.
- `tag` : Filtre sur l'étiquette posée à l'envoi.
- `to` : Filtre sur le destinataire.
- `limit` : Nombre de lignes, 1 à 200 (50 par défaut).
- `cursor` : Curseur de pagination renvoyé par un appel précédent.

### `POST /api/v1/messages/validate`

Essai à blanc d'un envoi

Dit si l'envoi passerait et nomme ce qui le bloquerait, SANS rien envoyer. À utiliser après une configuration, avant le premier vrai message.

Portée de clé nécessaire : `email.send`.

### `GET /api/v1/messages/{id}`

Statut d'un message

Statut de remise et suite des événements connus (remise, ouverture, clic, rebond, plainte).

Portée de clé nécessaire : `email.read_status`.

## Campagnes

Envoi en masse à une liste, et son cycle de vie.

### `POST /api/v1/automations/abandoned-cart`

Déclencher le scénario « panier abandonné »

Déclencher le scénario « panier abandonné »

Portée de clé nécessaire : `email.send`.

### `POST /api/v1/campaigns/conversion`

Déclarer une conversion

Rattache un achat ou une inscription à la campagne qui l'a précédé.

### `POST /api/v1/campaigns/preview`

Prévisualiser une campagne

Rend le HTML final d'une campagne, variables fusionnées, sans l'envoyer.

Portée de clé nécessaire : `email.send`.

### `POST /api/v1/campaigns/send`

Envoyer une campagne

Déclenche l'envoi à toute une liste.

Portée de clé nécessaire : `email.send`.
Accepte l'en-tête `Idempotency-Key` : une relance rejoue la réponse au lieu de refaire l'action.
Débit : 10 requêtes par minute.

### `GET /api/v1/campaigns/{id}/stats`

Statistiques d'une campagne

Statistiques d'une campagne

Portée de clé nécessaire : `analytics.read`.

### `GET /v3/emailCampaigns`

Lister les campagnes

Lister les campagnes

### `POST /v3/emailCampaigns`

Créer une campagne

Créer une campagne

### `GET /v3/emailCampaigns/{id}`

Lire une campagne

Lire une campagne

### `PUT /v3/emailCampaigns/{id}`

Modifier une campagne

Modifier une campagne

### `DELETE /v3/emailCampaigns/{id}`

Supprimer une campagne

Supprimer une campagne

### `POST /v3/emailCampaigns/{id}/cancel`

Annuler un envoi

Annuler un envoi

⚠ Action irréversible : à ne pas lancer sans validation humaine explicite.

> Action irréversible. À ne pas déclencher sans validation humaine explicite.

### `POST /v3/emailCampaigns/{id}/pause`

Interrompre un envoi en cours

Interrompre un envoi en cours

### `GET /v3/emailCampaigns/{id}/recipients`

Destinataires d'une campagne

Liste paginée, un destinataire par ligne, avec son statut d'envoi et ses évènements (ouverture, clic, rebond, désinscription). Filtrable par `status`.

### `POST /v3/emailCampaigns/{id}/resume`

Reprendre un envoi interrompu

Reprendre un envoi interrompu

### `POST /v3/emailCampaigns/{id}/schedule`

Programmer un envoi

Programmer un envoi

### `POST /v3/emailCampaigns/{id}/sendNow`

Envoyer maintenant

ACTION DESTRUCTIVE ET IRRÉVERSIBLE : les emails partent immédiatement à toute la liste. Exige une confirmation explicite dans le corps de la requête. Un appel sans corps a expédié 2 982 emails un samedi soir le 05/09/2026 ; la confirmation existe depuis.

⚠ Action irréversible : à ne pas lancer sans validation humaine explicite.
Débit : 10 requêtes par minute.

> Action irréversible. À ne pas déclencher sans validation humaine explicite.

### `POST /v3/emailCampaigns/{id}/sendTest`

Envoyer un test

À faire avant tout envoi réel.

Débit : 20 requêtes par minute.

### `GET /v3/emailCampaigns/{id}/statistics`

Statistiques d'une campagne

Statistiques d'une campagne

### `PUT /v3/emailCampaigns/{id}/status`

Changer le statut d'une campagne

Changer le statut d'une campagne

### `POST /v3/emailCampaigns/{id}/stop`

Interrompre un envoi en cours (synonyme de pause)

Interrompre un envoi en cours (synonyme de pause)

## Contacts

Contacts, listes et attributs personnalisés.

### `GET /v3/contacts`

Lister les contacts

Lister les contacts

### `POST /v3/contacts`

Créer ou mettre à jour un contact

Créer ou mettre à jour un contact

### `GET /v3/contacts/attributes`

Lister les attributs personnalisés

Lister les attributs personnalisés

### `POST /v3/contacts/attributes/{category}/{name}`

Créer un attribut

Créer un attribut

### `PUT /v3/contacts/attributes/{category}/{name}`

Modifier un attribut

Modifier un attribut

### `DELETE /v3/contacts/attributes/{category}/{name}`

Supprimer un attribut

Supprimer un attribut

### `GET /v3/contacts/folders`

Lister les dossiers de listes

Lister les dossiers de listes

### `POST /v3/contacts/folders`

Créer un dossier

Créer un dossier

### `GET /v3/contacts/folders/{id}`

Lire un dossier

Lire un dossier

### `PUT /v3/contacts/folders/{id}`

Renommer un dossier

Renommer un dossier

### `DELETE /v3/contacts/folders/{id}`

Supprimer un dossier

Ses listes sont conservées, sans dossier (contrairement à Brevo, qui les supprime).

### `GET /v3/contacts/folders/{id}/lists`

Listes d'un dossier

Listes d'un dossier

### `POST /v3/contacts/import`

Importer des contacts en lot

Colonnes CSV `CONSENT_DATE` (ISO 8601 ou `d/m/Y`) et `CONSENT_SOURCE`, ou champs `consentDate`/`consentSource` par entrée `jsonBody`, pour la preuve de consentement ligne par ligne. `consent_ip`/`consent_text` ne sont pas acceptés en masse : utiliser `POST`/`PUT /v3/contacts` pour un consentement complet. Limité à 20 000 lignes par appel, 413 `invalid_parameter` au-delà.

### `GET /v3/contacts/lists`

Lister les listes

Lister les listes

### `POST /v3/contacts/lists`

Créer une liste

Créer une liste

### `GET /v3/contacts/lists/{id}`

Lire une liste

Lire une liste

### `PUT /v3/contacts/lists/{id}`

Renommer une liste

Renommer une liste

### `DELETE /v3/contacts/lists/{id}`

Supprimer une liste

Supprimer une liste

### `GET /v3/contacts/{identifier}`

Lire un contact

L'identifiant est l'adresse email ou l'identifiant numérique.

### `PUT /v3/contacts/{identifier}`

Modifier un contact

Modifier un contact

### `DELETE /v3/contacts/{identifier}`

Supprimer un contact

Supprimer un contact

### `POST /v3/contacts/{identifier}/resubscribe`

Réinscrire un contact désinscrit

Repasse le statut à `subscribed` et retire la ligne de suppression correspondante (VaEmail et Amazon SES si configuré).

### `POST /v3/contacts/{identifier}/tags`

Ajouter des tags à un contact

Un tag inconnu est auto-créé : ce n’est qu’une valeur dans la liste de tags du contact, pas une entité à déclarer au préalable.

### `DELETE /v3/contacts/{identifier}/tags`

Retirer des tags à un contact

Retirer des tags à un contact

### `GET /v3/contacts/{id}/history`

Historique des changements d'attribut d'un contact

Une ligne par attribut modifié, plus récent en premier, paginé.

### `GET /v3/unsubscribe/{token}`

Valider un jeton de désinscription

Pour la page de désinscription hébergée par le client (`tenants.unsubscribe_url`), ne modifie rien. Le corps d'une campagne ou d'une automatisation peut aussi placer `{{preferences_url}}` : même jeton, vers la page de préférences hébergée VaEmail (`/preferences/{token}`), où le destinataire choisit ses listes plutôt que de tout arrêter.

### `POST /v3/unsubscribe/{token}`

Confirmer une désinscription

Même jeton HMAC, même effet que la page VaEmail par défaut `/u/{token}`.

## Segments

Segments dynamiques, recalculés à la volée sur un attribut de contact.

### `GET /v3/segments`

Lister les segments dynamiques

Lister les segments dynamiques

### `GET /v3/segments/{id}`

Lire un segment

Lire un segment

### `GET /v3/segments/{id}/contacts`

Contacts d'un segment

Recalculé à la volée à chaque appel, jamais matérialisé.

## Événements

Événements personnalisés et conversions envoyés par un site tiers, déclencheurs d'automatisation.

### `POST /v3/conversions`

Remonter une conversion (montant) pour un contact

Rattachée à `email` et, si `campaign_id` est fourni, à la campagne d'origine. Alimente `GET /api/v1/stats/revenue`. Portée requise : `events.write`.

### `POST /v3/events`

Envoyer un événement personnalisé

Compatible Brevo (`identifiers.email_id`, `event_properties`, `contact_properties`, `event_name`) ; déclenche les automatisations `trigger_type=custom_event` sur ce nom et rend les propriétés disponibles en `{{event.*}}` dans les emails de la séquence. Portée requise : `events.write`.

### `GET /v3/events/names`

Lister les noms d'événements déjà reçus

Alimente le sélecteur du déclencheur « événement » côté admin.

## Domaines

Authentification des domaines d'envoi (SPF, DKIM, DMARC).

### `GET /api/v1/domains`

Lister les domaines d'envoi

Chaque domaine déclaré, avec l'état réel de son SPF, DKIM et DMARC lu dans le DNS public.

Portée de clé nécessaire : `domain.read`.

### `POST /api/v1/domains`

Déclarer un domaine d'envoi

Deuxième étape d'une installation autonome, juste après la clé. Rend les enregistrements DNS à poser et l'état courant de l'authentification : sans SPF ni DMARC, tout ce qui part est classé en indésirable.

Portée de clé nécessaire : `domain.write`.
Accepte l'en-tête `Idempotency-Key` : une relance rejoue la réponse au lieu de refaire l'action.

### `POST /api/v1/domains/verify`

Vérifier l'authentification d'un domaine

Lit SPF, DKIM et DMARC dans le DNS public et rend le verdict enregistrement par enregistrement. Sans SPF et DMARC, les grands fournisseurs classent l'envoi en indésirable.

Portée de clé nécessaire : `domain.write`.

### `GET /api/v1/domains/{domain}/dns`

Enregistrements DNS attendus pour un domaine

Ce qu'il faut poser chez le registrar, enregistrement par enregistrement, avec le rôle de chacun.

Portée de clé nécessaire : `domain.read`.

## Délivrabilité

Diagnostic, réputation et statistiques de remise.

### `GET /api/v1/deliverability/diagnose`

Diagnostiquer la délivrabilité

Répond à « pourquoi mes emails partent mal ? » : authentification de chaque domaine, constats de réputation (rebonds durs, plaintes, provenance des contacts) et actions recommandées, chacune avec l'endpoint qui la réalise.

Portée de clé nécessaire : `analytics.read`.

Paramètres :

- `domain` : Restreint le diagnostic à un domaine déclaré.

### `GET /api/v1/stats/cohorts`

Cohortes d'envoi par mois

Cohortes d'envoi par mois

Portée de clé nécessaire : `analytics.read`.

### `GET /api/v1/stats/deliverability`

Statistiques de remise par domaine destinataire

Statistiques de remise par domaine destinataire

Portée de clé nécessaire : `analytics.read`.

### `GET /api/v1/stats/engagement`

Ouvertures/clics/désinscriptions, filtrables par liste, tag ou source

Paramètres optionnels `listId`, `tag`, `source` (source de consentement). Sans filtre : comportement inchangé (compte entier).

Portée de clé nécessaire : `analytics.read`.

### `GET /api/v1/stats/revenue`

Revenu agrégé par campagne

Somme des conversions remontées par `POST /v3/conversions`, groupées par campagne.

Portée de clé nécessaire : `analytics.read`.

### `GET /api/v1/suppressions`

Lister les adresses sorties du circuit

Rebonds durs, plaintes et désinscriptions. Un envoi vers une de ces adresses est refusé : les lire évite de réessayer une adresse morte et de faire monter le taux de rebonds.

Portée de clé nécessaire : `contacts.read`.

Paramètres :

- `reason` : Filtre : hard_bounce, soft_bounce_limit, complaint, unsubscribe, manual.
- `since` : Date ISO 8601 à partir de laquelle lire.
- `email` : Filtre sur une adresse exacte (normalisée en minuscules).
- `limit` : Nombre de lignes, 1 à 200.
- `cursor` : Curseur de pagination.

### `DELETE /api/v1/suppressions/{email}`

Retirer une adresse de la liste de suppression

Rend la main au compte sans passer par nous : un rebond ou une désinscription enregistrés par erreur, ou une adresse redevenue valide, peuvent être retirés directement.

Portée de clé nécessaire : `contacts.write`.

### `GET /v3/smtp/statistics/aggregatedReport`

Rapport agrégé des envois

Rapport agrégé des envois

## Compte

Consommation, quotas, expéditeurs, journal des actions.

### `GET /api/v1/audit-logs`

Journal des actions

Une ligne par appel : quelle clé, quelle opération, quels paramètres, quel résultat. Le corps des messages n'y figure jamais.

Portée de clé nécessaire : `analytics.read`.

Paramètres :

- `operation` : Filtre sur le nom d'opération (email.send, campaign.send...).
- `since` : Date ISO 8601 à partir de laquelle lire.
- `limit` : Nombre de lignes, 1 à 200.
- `cursor` : Curseur de pagination.

### `GET /api/v1/settings`

Réglages du tenant pour les stats fiables

Filtres appliqués au calcul des statistiques (jamais aux événements bruts, toujours conservés) : exclusion des ouvertures Apple Mail Privacy Protection et des clics/ouvertures de robots (scanners de sécurité).

Portée de clé nécessaire : `analytics.read`.

### `PUT /api/v1/settings`

Modifier les réglages de filtres de stats

Active ou désactive l'exclusion MPP/robots. Les deux filtres sont activés par défaut.

Portée de clé nécessaire : `settings.write`.

### `GET /api/v1/usage`

Consommation et plafonds

Quota mensuel, envois du jour, et pour la clé utilisée : ses portées, son plafond journalier et ce qu'il en reste. Un agent qui ne sait pas ce qu'il lui reste ne peut pas décider de s'arrêter.

Portée de clé nécessaire : `billing.read`.

### `GET /v3/account`

Informations du compte

Informations du compte

### `GET /v3/senders`

Lister les expéditeurs

Lister les expéditeurs

### `POST /v3/senders`

Déclarer un expéditeur

Déclarer un expéditeur

### `DELETE /v3/senders/{id}`

Supprimer un expéditeur

Supprimer un expéditeur

⚠ Action irréversible : à ne pas lancer sans validation humaine explicite.

> Action irréversible. À ne pas déclencher sans validation humaine explicite.

## Webhooks

Abonnement aux événements d'envoi.

### `GET /v3/webhooks`

Lister les webhooks

Lister les webhooks

### `POST /v3/webhooks`

Créer un webhook

Créer un webhook

### `GET /v3/webhooks/{id}`

Lire un webhook

Lire un webhook

### `PUT /v3/webhooks/{id}`

Modifier un webhook

Modifier un webhook

### `DELETE /v3/webhooks/{id}`

Supprimer un webhook

Supprimer un webhook

⚠ Action irréversible : à ne pas lancer sans validation humaine explicite.

> Action irréversible. À ne pas déclencher sans validation humaine explicite.

## Prospection

Séquences à froid : boîtes d'envoi, réponses relevées, désinscriptions. Module activable par compte.

### `GET /v3/outreach/campaigns`

Lister les séquences

Lister les séquences

### `POST /v3/outreach/campaigns`

Créer une séquence

Créer une séquence

### `GET /v3/outreach/campaigns/{id}`

Lire une séquence

Lire une séquence

### `PUT /v3/outreach/campaigns/{id}`

Modifier une séquence

Modifier une séquence

### `DELETE /v3/outreach/campaigns/{id}`

Supprimer une séquence

Supprimer une séquence

⚠ Action irréversible : à ne pas lancer sans validation humaine explicite.

> Action irréversible. À ne pas déclencher sans validation humaine explicite.

### `POST /v3/outreach/campaigns/{id}/enroll`

Inscrire des prospects dans une séquence

Inscrire des prospects dans une séquence

Débit : 60 requêtes par minute.

### `GET /v3/outreach/campaigns/{id}/stats`

Statistiques d'une séquence

Statistiques d'une séquence

### `POST /v3/outreach/campaigns/{id}/status`

Démarrer, mettre en pause ou arrêter une séquence

Passer en « running » déclenche des envois réels aux prospects inscrits.

### `GET /v3/outreach/identity`

Lire l'identification légale de l'expéditeur

Lire l'identification légale de l'expéditeur

### `PUT /v3/outreach/identity`

Déclarer l'identification légale de l'expéditeur

Raison sociale et adresse postale, reprises au pied de chaque message (L.34-5 du CPCE). Tant qu'elles sont vides, l'inscription en campagne et le démarrage sont refusés.

### `GET /v3/outreach/inbox`

Lister les réponses reçues

Réponses relevées en IMAP sur les boîtes d'envoi du compte, classées (intéressé, refus, absence, désinscription). C'est la seule voie entrante de VaEmail à ce jour : elle est rattachée à une séquence, ce n'est pas une boîte générique.

### `GET /v3/outreach/inbox/{id}`

Lire une réponse

Lire une réponse

### `PUT /v3/outreach/inbox/{id}`

Changer le classement ou l'état d'une réponse

Changer le classement ou l'état d'une réponse

### `POST /v3/outreach/inbox/{id}/reply`

Répondre à un prospect

Envoie la réponse depuis la boîte qui a reçu le message, dans le même fil.

Débit : 30 requêtes par minute.

### `GET /v3/outreach/mailboxes`

Lister les boîtes d'envoi et leur santé

Lister les boîtes d'envoi et leur santé

### `POST /v3/outreach/mailboxes`

Déclarer une boîte d'envoi

Déclarer une boîte d'envoi

### `GET /v3/outreach/mailboxes/{id}`

Lire une boîte d'envoi

Lire une boîte d'envoi

### `PUT /v3/outreach/mailboxes/{id}`

Modifier une boîte d'envoi

Modifier une boîte d'envoi

### `DELETE /v3/outreach/mailboxes/{id}`

Supprimer une boîte d'envoi

Supprimer une boîte d'envoi

⚠ Action irréversible : à ne pas lancer sans validation humaine explicite.

> Action irréversible. À ne pas déclencher sans validation humaine explicite.

### `GET /v3/outreach/prospects`

Lister les prospects

Lister les prospects

### `POST /v3/outreach/prospects`

Ajouter des prospects

Ajouter des prospects

Débit : 60 requêtes par minute.

### `DELETE /v3/outreach/prospects`

Supprimer des prospects en lot

Supprimer des prospects en lot

⚠ Action irréversible : à ne pas lancer sans validation humaine explicite.

> Action irréversible. À ne pas déclencher sans validation humaine explicite.

### `GET /v3/outreach/prospects/{id}`

Lire un prospect

Lire un prospect

### `PUT /v3/outreach/prospects/{id}`

Modifier un prospect

Modifier un prospect

### `DELETE /v3/outreach/prospects/{id}`

Supprimer un prospect

Supprimer un prospect

⚠ Action irréversible : à ne pas lancer sans validation humaine explicite.

> Action irréversible. À ne pas déclencher sans validation humaine explicite.

## Médiathèque

Images hébergées pour les campagnes.

### `GET /v3/media`

Lister les images

Lister les images

### `POST /v3/media`

Téléverser une image

Téléverser une image

Débit : 60 requêtes par minute.

### `GET /v3/media/{uuid}`

Lire une image

Lire une image

### `DELETE /v3/media/{uuid}`

Supprimer une image

Supprimer une image

⚠ Action irréversible : à ne pas lancer sans validation humaine explicite.

> Action irréversible. À ne pas déclencher sans validation humaine explicite.

## RGPD

Export et effacement des données d'un contact.

### `POST /api/v1/contacts/erase`

Effacer les données d'un contact

Action irréversible : les données personnelles sont supprimées, l'adresse reste en liste de suppression pour ne pas être recontactée.

Portée de clé nécessaire : `contacts.write`.

### `GET /api/v1/contacts/export`

Exporter les données d'un contact

Exporter les données d'un contact

Portée de clé nécessaire : `contacts.read`.
