MailLandDocs
Marketing

Campagnes

Créez, planifiez et envoyez des campagnes d'e-mail marketing avec suivi et analytiques

Créez et gérez des campagnes d'e-mail marketing. MailLand gère la sélection des destinataires, l'envoi, le suivi des livraisons et les analytiques d'engagement pour chaque campagne.

Cycle de vie d'une campagne

Chaque campagne suit un flux d'états défini :

StatutValeurDescription
Draft0État initial : modifiable, pas encore envoyée
Scheduled1En attente pour une livraison future
Sending2En cours d'envoi aux destinataires
Sent3Tous les destinataires traités
Paused4Envoi suspendu en cours de route
Cancelled5Envoi annulé
Failed6Erreur système lors de l'envoi

Transitions autorisées :

  • Draft → Scheduled (planifier) ou Sending (envoyer immédiatement) ou Cancelled (annuler)
  • Scheduled → Sending ou Cancelled : la replanification d'une campagne Scheduled n'est pas prise en charge
  • Sending → Sent, Paused, Cancelled ou Failed
  • Paused → Sending (reprendre)
  • Sent ou Cancelled → archivée

Types de campagnes

TypeValeurDescription
Regular0Campagne standard unique
Automated1Déclenchée par des automatisations
ABTest2Campagne de test A/B

Personnalisation

Les lignes d'objet et le contenu des campagnes prennent en charge les balises de fusion {{variable}}, substituées par destinataire à partir du propre enregistrement de cet abonné.

BaliseValeur
{{firstName}}Prénom de l'abonné
{{lastName}}Nom de famille de l'abonné
{{fullName}}Prénom et nom réunis
{{email}}Adresse e-mail de l'abonné
{{subscriberId}}Identifiant opaque de l'abonné
{{custom_<field>}}Tout champ personnalisé de l'abonné : également disponible sous la forme {{<field>}}
Contenu de campagne personnalisé
<p>Hi {{firstName}}, here's what's new this month.</p>

Une balise sans valeur est laissée exactement telle qu'écrite : {{firstName}} pour un abonné sans prénom reste {{firstName}} dans l'e-mail livré plutôt que de devenir un espace vide. Rédigez un contenu qui se lit correctement dans les deux cas, par exemple Hi there{{firstName}} est mal adapté mais "Your account" est sûr. Utilisez une salutation de repli lorsque vous n'êtes pas sûr que chaque abonné possède le champ.

Les valeurs sont échappées selon l'endroit où elles atterrissent : le contenu HTML est échappé en HTML (de sorte qu'un nom contenant & ou < ne peut pas casser votre balisage), tandis que la ligne d'objet et le corps en texte brut ne sont jamais échappés, Ben & Jerry's reste exactement tel quel.

Les anciennes orthographes en snake_case ({{first_name}}, {{last_name}}, {{full_name}}, {{subscriber_id}}) continuent de fonctionner comme alias.

Créer une campagne

L'espace de travail doit être Business Verified avant de pouvoir créer ou mettre à jour une campagne : une vérification antérieure et distincte du contrôle de fromEmail ci-dessous. Si ce n'est pas le cas, la requête échoue avec 400 INVALID_REQUEST (« Marketing campaigns require Business Verified status… »).

Le domaine de fromEmail doit déjà être ajouté et entièrement vérifié (SPF + DKIM + DMARC) au moment de la création et de la mise à jour, sinon la requête est rejetée (400/404). Cette vérification a lieu ici, pas à l'envoi, voir Envoyer immédiatement.

POST https://api.mail.land/v1/marketing/campaigns
Create campaign request
{
  "name": "February Newsletter",
  "subject": "What's new in February",
  "previewText": "Product updates and tips",
  "fromName": "MailLand Team",
  "fromEmail": "[email protected]",
  "replyTo": "[email protected]",
  "htmlContent": "<html>...</html>",
  "textContent": "Plain text version...",
  "type": 0,
  "mailingListId": "ddv6ou6kz4wbto",
  "segmentId": "x4xa3ep1zmqq0b"
}
ChampTypeRequisDescription
namestringOuiNom de la campagne
subjectstringOuiObjet de l'e-mail
previewTextstringNonTexte d'aperçu affiché dans la boîte de réception
fromNamestringOuiNom d'affichage de l'expéditeur
fromEmailstringOuiAdresse e-mail de l'expéditeur
replyTostringNonAdresse de réponse
htmlContentstringOuiCorps HTML de l'e-mail
textContentstringNonVersion en texte brut de secours
templateIdstringNonIdentifiant du modèle à utiliser
typeintNonType de campagne (défaut : 0 Régulière)
mailingListIdstringNon*Liste de diffusion cible
segmentIdstringNon*Segment cible

* Fournissez mailingListId ou segmentId : l'un des deux est requis sauf si templateId est défini.

Create a campaign
curl -X POST https://api.mail.land/v1/marketing/campaigns \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "February Newsletter",
    "subject": "What'\''s new in February",
    "fromName": "MailLand Team",
    "fromEmail": "[email protected]",
    "htmlContent": "<html><body><h1>Hello!</h1></body></html>",
    "mailingListId": "ddv6ou6kz4wbto"
  }'

Réponse

Campaign response
{
  "id": "uivozyvucowj9w",
  "name": "February Newsletter",
  "subject": "What's new in February",
  "previewText": "Product updates and tips",
  "fromName": "MailLand Team",
  "fromEmail": "[email protected]",
  "status": "draft",
  "statusName": "Draft",
  "type": 0,
  "typeName": "Regular",
  "mailingListId": "ddv6ou6kz4wbto",
  "mailingListName": "Main Newsletter",
  "segmentId": null,
  "segmentName": null,
  "createdAt": "2026-02-17T12:00:00Z",
  "updatedAt": "2026-02-17T12:00:00Z"
}

Lister les campagnes

GET https://api.mail.land/v1/marketing/campaigns
ParamètreTypeDéfautDescription
cursorstring-Curseur opaque issu du nextCursor de la page précédente. À omettre pour la première page.
limitint20Éléments par page (max 100)
searchstring-Rechercher par nom
statusint-Filtrer par CampaignStatus
typeint-Filtrer par CampaignType
mailingListIdstring-Filtrer par liste de diffusion
sortBystring-Champ de tri
sortDescboolfalseTri décroissant
includeArchivedboolfalseInclure les campagnes archivées
List campaigns
curl "https://api.mail.land/v1/marketing/campaigns?limit=20&status=3" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
Campaign list response
{
  "items": [
    {
      "id": "uivozyvucowj9w",
      "name": "February Newsletter",
      "subject": "What's new in February",
      "status": "sent",
      "statusName": "Sent",
      "type": 0,
      "typeName": "Regular",
      "mailingListId": "ddv6ou6kz4wbto",
      "mailingListName": "Main Newsletter",
      "totalRecipients": 5000,
      "totalSent": 4980,
      "totalDelivered": 4900,
      "totalOpened": 1520,
      "totalClicked": 195,
      "totalBounced": 45,
      "totalUnsubscribed": 12,
      "sentAt": "2026-02-15T10:00:00Z",
      "completedAt": "2026-02-15T10:35:00Z",
      "createdAt": "2026-02-14T08:00:00Z"
    }
  ],
  "nextCursor": "eyJ2IjoxLCJzIjoiY3JlYXRlZGF0OmRlc2MiLCJrIjoi...",
  "hasMore": true
}

Obtenir les détails d'une campagne

GET https://api.mail.land/v1/marketing/campaigns/{id}

Retourne le CampaignDetailDto complet incluant le contenu HTML, toutes les statistiques et les taux d'engagement calculés :

Get campaign details
curl https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
Campaign detail response
{
  "id": "uivozyvucowj9w",
  "name": "February Newsletter",
  "subject": "What's new in February",
  "previewText": "Product updates and tips",
  "fromName": "MailLand Team",
  "fromEmail": "[email protected]",
  "replyTo": "[email protected]",
  "status": "sent",
  "statusName": "Sent",
  "type": 0,
  "typeName": "Regular",
  "htmlContent": "<html>...</html>",
  "textContent": "Plain text...",
  "mailingListId": "ddv6ou6kz4wbto",
  "mailingListName": "Main Newsletter",
  "totalRecipients": 5000,
  "totalSent": 4980,
  "totalDelivered": 4900,
  "totalOpened": 1520,
  "totalClicked": 195,
  "totalBounced": 45,
  "totalUnsubscribed": 12,
  "totalComplaints": 2,
  "deliveryRate": 98.39,
  "openRate": 31.02,
  "clickRate": 3.98,
  "clickToOpenRate": 12.83,
  "bounceRate": 0.9,
  "unsubscribeRate": 0.24,
  "openTrackingEnabled": true,
  "clickTrackingEnabled": true,
  "sentAt": "2026-02-15T10:00:00Z",
  "completedAt": "2026-02-15T10:35:00Z",
  "createdAt": "2026-02-14T08:00:00Z",
  "updatedAt": "2026-02-15T10:35:00Z"
}

Taux d'engagement

TauxFormule
deliveryRatetotalDelivered / totalSent * 100
openRatetotalOpened / totalDelivered * 100
clickRatetotalClicked / totalDelivered * 100
clickToOpenRatetotalClicked / totalOpened * 100
bounceRatetotalBounced / totalSent * 100
unsubscribeRatetotalUnsubscribed / totalDelivered * 100

Les taux sont calculés côté serveur à partir des compteurs bruts (ouvertures et clics sont uniques par destinataire). deliveryRate et bounceRate sont des taux sur les messages envoyés ; openRate, clickRate et unsubscribeRate sont des taux sur les messages délivrés ; clickToOpenRate (CTOR) rapporte les clics aux ouvertures et reste une mesure distincte de clickRate. Un taux est un pourcentage sans plafond (clickToOpenRate peut dépasser 100) et vaut null, jamais 0, lorsqu'il est indisponible : son dénominateur est 0 ou le suivi nécessaire est désactivé sur le compte (openTrackingEnabled / clickTrackingEnabled indiquent le réglage actuel). Pour combiner des campagnes, additionnez les compteurs et divisez une seule fois ; ne faites pas la moyenne des pourcentages. La liste renvoie les mêmes champs pour chaque campagne.

Mettre à jour une campagne

PUT https://api.mail.land/v1/marketing/campaigns/{id}

Seules les campagnes à l'état Draft ou Scheduled peuvent être mises à jour. Le corps de la requête correspond à la requête de création, à l'exception de type, qui ne peut pas être modifié.

StatutCodeDescription
200-Campagne mise à jour
400INVALID_REQUESTSeules les campagnes brouillon peuvent être modifiées
404RESOURCE_NOT_FOUNDCampagne introuvable
Update a campaign
curl -X PUT https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "February Newsletter (Updated)",
    "subject": "What'\''s new in February - updated",
    "fromName": "MailLand Team",
    "fromEmail": "[email protected]",
    "htmlContent": "<html><body><h1>Updated!</h1></body></html>",
    "mailingListId": "ddv6ou6kz4wbto"
  }'

Planifier une campagne

POST https://api.mail.land/v1/marketing/campaigns/{id}/schedule
Schedule request
{
  "scheduledAt": "2026-02-20T14:00:00Z"
}

L'heure scheduledAt doit être dans le futur. Le statut de la campagne passe à Scheduled et le CampaignWorker la prend en charge à l'heure planifiée.

La planification n'est autorisée que depuis le statut Draft : une campagne déjà Scheduled ne peut pas être replanifiée via cet endpoint.

StatutCodeDescription
200-Campagne planifiée
400VALIDATION_FAILEDL'heure de planification doit être dans le futur
404RESOURCE_NOT_FOUNDCampagne introuvable ou impossible à planifier
403MARKETING_NOT_YET_ALLOWEDLe marketing n'est pas encore ouvert pour le compte (voir Codes d'erreur) ; /send le renvoie aussi
403MARKETING_SUSPENDEDLe marketing est indisponible sur toute la plateforme ; /send le renvoie aussi
422CAMPAIGN_LINK_BLOCKEDUn lien de la campagne pointe vers une destination signalée comme dangereuse ; /send le renvoie aussi. Rien n'est planifié ni envoyé
Schedule a campaign
curl -X POST https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w/schedule \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{ "scheduledAt": "2026-02-20T14:00:00Z" }'

Envoi immédiat

POST https://api.mail.land/v1/marketing/campaigns/{id}/send

Envoie la campagne immédiatement. Le statut de la campagne passe à Sending et le CampaignWorker commence à traiter les destinataires.

/send lui-même ne vérifie pas la vérification du domaine : cette vérification a lieu à la création/mise à jour (voir Créer une campagne). /send renvoie 422 CAMPAIGN_NO_ELIGIBLE_RECIPIENTS si personne dans la liste/le segment cible n'est éligible pour recevoir la campagne (par exemple si tout le monde est supprimé ou désabonné).

Send a campaign immediately
curl -X POST https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w/send \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Pause et reprise

Mettre en pause une campagne en cours d'envoi :

POST https://api.mail.land/v1/marketing/campaigns/{id}/pause
Pause a campaign
curl -X POST https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w/pause \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Reprendre une campagne en pause :

POST https://api.mail.land/v1/marketing/campaigns/{id}/resume
Resume a campaign
curl -X POST https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w/resume \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

La mise en pause arrête le CampaignWorker de traiter les destinataires restants. Les e-mails déjà envoyés ne sont pas affectés. La reprise continue là où elle s'était arrêtée.

Annuler une campagne

POST https://api.mail.land/v1/marketing/campaigns/{id}/cancel

Annule une campagne Draft, Scheduled ou Sending. Les e-mails déjà envoyés ne sont pas rappelés.

Cancel a campaign
curl -X POST https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w/cancel \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Dupliquer une campagne

POST https://api.mail.land/v1/marketing/campaigns/{id}/duplicate?name=Copy%20of%20Newsletter

Crée une nouvelle campagne Draft avec tous les paramètres copiés de l'original. Le paramètre de requête name est optionnel.

Duplicate a campaign
curl -X POST "https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w/duplicate?name=Copy%20of%20Newsletter" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Archiver et désarchiver

Archiver une campagne Sent ou Cancelled :

POST https://api.mail.land/v1/marketing/campaigns/{id}/archive
Archive a campaign
curl -X POST https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w/archive \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Désarchiver une campagne archivée :

POST https://api.mail.land/v1/marketing/campaigns/{id}/unarchive
Unarchive a campaign
curl -X POST https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w/unarchive \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Les campagnes archivées sont masquées de la vue de liste par défaut sauf si includeArchived=true est passé.

Destinataires de la campagne

Obtenez les destinataires paginés avec le statut de livraison pour une campagne :

GET https://api.mail.land/v1/marketing/campaigns/{id}/recipients
ParamètreTypeDéfautDescription
cursorstring-Curseur opaque issu du nextCursor de la page précédente. À omettre pour la première page.
limitint20Éléments par page (max 100)
statusstring-Filtrer par statut de destinataire
searchstring-Rechercher par e-mail
Get campaign recipients
curl "https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w/recipients?limit=20" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
Campaign recipients response
{
  "items": [
    {
      "email": "[email protected]",
      "status": "Opened",
      "sentAt": "2026-02-15T10:00:30Z",
      "deliveredAt": "2026-02-15T10:00:32Z",
      "openedAt": "2026-02-15T11:15:00Z",
      "clickedAt": "2026-02-15T11:16:30Z",
      "bouncedAt": null,
      "complainedAt": null,
      "unsubscribedAt": null,
      "openCount": 2,
      "clickCount": 1,
      "bounceReason": null
    }
  ],
  "nextCursor": "eyJ2IjoxLCJzIjoiY3JlYXRlZGF0OmRlc2MiLCJrIjoi...",
  "hasMore": true
}

Statuts des destinataires

StatutValeurDescription
Pending0En attente, pas encore envoyé
Sent1Accepté par le MTA
Delivered2Livré au destinataire
Opened3Le destinataire a ouvert
Clicked4Le destinataire a cliqué sur un lien
Bounced5Rebond dur
Unsubscribed6Le destinataire s'est désabonné
Complained7Plainte pour spam
Failed8Échec de livraison

openedAt/openCount et clickedAt/clickCount incluent une activité automatisée, le préchargement d'Apple Mail Privacy Protection et les scanners de liens de sécurité, que MailLand ne filtre pas aujourd'hui. Considérez les taux dérivés des ouvertures/clics comme une limite supérieure, pas comme un chiffre précis d'engagement humain.

Supprimer une campagne

DELETE https://api.mail.land/v1/marketing/campaigns/{id}

Supprime définitivement une campagne et ses données de destinataires. Seules les campagnes au statut Draft ou Scheduled peuvent être supprimées ; la suppression de tout autre statut renvoie 404, archivez plutôt une campagne envoyée.

Delete a campaign
curl -X DELETE https://api.mail.land/v1/marketing/campaigns/uivozyvucowj9w \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Réponses d'erreur

StatutCodeDescription
400VALIDATION_FAILEDChamps obligatoires manquants
400INVALID_REQUESTSeules les campagnes brouillon peuvent être modifiées
403FORBIDDENPermissions insuffisantes
404RESOURCE_NOT_FOUNDCampagne introuvable

Étapes suivantes

  • Abonnés : gérer vos contacts abonnés
  • Listes : organiser les abonnés en listes de diffusion
  • Segments : cibler les campagnes avec des segments dynamiques
  • Automatisations : configurer des séquences d'e-mails basées sur des déclencheurs

Sur cette page