POST /api/v1/campaigns
Crée une campagne en draft. Répond 201.
Le contenu est copié depuis le modèle, il ne fait pas partie du corps de la requête. Modifiez le modèle, puis
créez la campagne — une campagne ne s'écarte jamais de ce que vous avez rendu.
tagId attend un id, pas un
nom : résolvez-le avec GET /api/v1/tags.topicId fonctionne de la même façon, résolu avec GET /api/v1/topics. Un contenu qui porte
{{topicOptOutUrl}} sur une campagne sans sujet rend l'envoi refusé — le lien serait
mort. Voir Sujets.sendingIdentityId attend un id de votre carnet d'adresses — listez-les avec
GET /api/v1/settings/identities, où chaque entrée porte son id, son senderEmail et
indique si elle est l'adresse par défaut. Une adresse appartenant à une autre organisation est refusée avec 403.L'omettre n'équivaut pas à figer l'adresse par défaut. Une campagne sans
sendingIdentityId suit l'adresse par défaut telle qu'elle est au moment de l'envoi : promouvez une autre adresse et cette
campagne la suit. Une campagne qui nomme une adresse la garde, quelle que soit la future adresse par défaut.
Voir Paramètres et domaines pour le carnet d'adresses lui-même.Autorisation
| Rôle dans l'organisation | Cet endpoint |
|---|---|
OWNER | Autorisé |
ADMIN | Autorisé |
MEMBER | Refusé — 403 |
Corps de la requête
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
name | string | oui | 1 à 100 caractères, nom interne |
subject | string | oui | 1 à 200 caractères, l'objet que voient les destinataires |
previewText | string | null | non | Texte d'aperçu, jusqu'à 200 caractères après suppression des espaces de début et de fin. null l'efface ; omis dans un PATCH, il est conservé. Rendu à l'emplacement de {{previewText}} ou {{preheader}} |
preheader | string | null | non | Alias compatible de previewText. Si les deux sont fournis, ils doivent être identiques après suppression des espaces, sinon 400 |
templateId | string | oui | Modèle de votre organisation |
listId | string | oui | Liste destinataire de l'envoi |
tagId | string | non | Restreint la liste aux contacts qui portent ce tag |
topicId | string | non | Sujet éditorial que porte cette campagne. Requis pour que {{topicOptOutUrl}} soit rendu |
sendingIdentityId | string | non | L'adresse qui signe cette campagne. Omis ou null : l'adresse par défaut de l'organisation |
json
{
"name": "August newsletter",
"subject": "What shipped in August",
"previewText": "Timely m’a bloqué mes paiements Stripe pendant 5 jours.",
"templateId": "2b2b2b2b-3333-4ddd-8eee-ffff00001111",
"listId": "9f8e7d6c-1111-4bbb-8ccc-ddddeeeeffff"
}null compris ;
des valeurs contradictoires renvoient 400. Une chaîne vide supprime aussi le texte d'aperçu.
Exemple
bash
curl -X POST -H "x-api-key: $AGENTMAIL_API_KEY" -H "content-type: application/json" \
-d '{
"name": "August newsletter",
"subject": "What shipped in August",
"previewText": "Timely m’a bloqué mes paiements Stripe pendant 5 jours.",
"templateId": "'$TEMPLATE_ID'",
"listId": "'$LIST_ID'",
"sendingIdentityId": "'$IDENTITY_ID'"
}' \
"https://www.agentsmail.io/api/v1/campaigns"Réponse
-
400 Bad Request— champs invalides, texte d'aperçu de plus de 200 caractères, ou alias contradictoires. -
201 Created— la ressource créée. -
401 Unauthorized— clé absente ou invalide, ou son propriétaire a quitté l'organisation. -
403 Forbidden— le propriétaire de la clé estmemberde l'organisation, pasadmin. -
429 Too Many Requests— plus de 120 requêtes en une minute pour cette clé.
Champs de la réponse
| Champ | Type | Description |
|---|---|---|
success | boolean | Indique si l'opération a réussi |
data | object | Objet campagne. |
data.campaignUrl | string | null | Page de la campagne. |
data.campaignEditorUrl | string | null | Éditeur du contenu pour un brouillon modifiable. |
data.campaignStatsUrl | string | null | Statistiques d’une campagne envoyée. |
data.campaignPreviewUrl | string | null | Aperçu interne d’une campagne envoyée. |
data.publicCampaignUrl | string | null | Archive partageable d’une campagne envoyée dont les archives publiques sont activées. |
data.id | string | Identifiant unique de la campagne |
data.name | string | Son nom interne |
data.subject | string | L'objet que voient les destinataires |
data.previewText | string | null | Texte d'aperçu enregistré ; égal à data.preheader |
data.preheader | string | null | Le texte d'aperçu affiché après l'objet, null s'il n'y en a pas |
data.status | string | draft, scheduled, paused, sending, sent, failed |
data.listId | string | La liste qu'elle cible |
data.tagId | string | null |
data.topicId | string | null |
data.scheduledAt | string | null |
data.sentAt | string | null |
data.createdAt | string | Date de création ISO |
data.updatedAt | string | Date ISO de la dernière modification |
en par défaut). Les liens indisponibles valent null ; ils sont tous null si l’organisation n’a pas de slug d’URL. Les liens internes nécessitent une connexion et les droits sur l’organisation ; seul publicCampaignUrl est public. Les agents API et MCP affichent les liens pertinents non nuls en Markdown cliquable, par exemple [Ouvrir la campagne](campaignUrl) en utilisant l’URL reçue. Créer ou consulter une campagne ne la publie pas.
Exemple de réponse
json
{
"success": true,
"data": {
"id": "4d19c0a2",
"name": "Newsletter",
"subject": "August news",
"previewText": "Three new things this month",
"preheader": "Three new things this month",
"status": "draft",
"listId": "0b7c51e8",
"tagId": "7c2ef4b1",
"topicId": null,
"scheduledAt": null,
"sentAt": null,
"createdAt": "2026-08-23T10:22:05.000Z",
"updatedAt": "2026-08-23T10:22:05.000Z",
"campaignUrl": "https://www.agentsmail.io/fr/team/my-team/campaigns/4d19c0a2",
"campaignEditorUrl": "https://www.agentsmail.io/fr/team/my-team/campaigns/4d19c0a2/content",
"campaignStatsUrl": null,
"campaignPreviewUrl": null,
"publicCampaignUrl": null
}
}Remarques
Le HTML doit contenir{{previewText}} ou {{preheader}}, généralement dans un bloc masqué.
AgentsMail n'insère aucun bloc. Voir Balises de fusion.