# Campagnes API

> Créez des campagnes, choisissez leurs listes de contacts, puis envoyez-les ou programmez-les.

URL de base : `https://api.emailit.com/v2`. Authentifiez-vous avec `Authorization: Bearer <API key>`.

## Créer une campagne — POST /campaigns

> Créez une campagne e-mail en brouillon avec son expéditeur, son objet et son corps HTML ou texte, prête à cibler des listes de contacts et à être envoyée.

# Créer une campagne

Crée une campagne au statut `draft`. Nécessite une clé API avec la portée `full`. Émet l’événement `campaign.created`.

Une nouvelle campagne n’a aucun destinataire. Choisissez ses listes de contacts avec [Mettre à jour une campagne](/fr/docs/api-reference/campaigns/update/), puis [envoyez-la ou programmez-la](/fr/docs/api-reference/campaigns/send/). Les crédits sont débités à l’envoi de la campagne : 2 crédits par e-mail.

`POST /campaigns`

## Paramètres du corps

- `name` (string, obligatoire): Nom interne de la campagne. Les destinataires ne le voient pas. Les autres endpoints de campagne acceptent le nom à la place de l’ID : gardez des noms uniques si vous les utilisez ainsi.

- `subject` (string): Ligne d’objet. Prend en charge les [balises de fusion](/fr/docs/campaigns/merge-tags/) comme `{{first_name}}`.

- `from_email` (string): Adresse de l’expéditeur. Elle doit appartenir à un domaine d’envoi vérifié de l’espace de travail, par exemple `news@acme.com`.

- `from_name` (string): Nom d’affichage de l’expéditeur, par exemple `Acme`. Le message est envoyé depuis `Acme <news@acme.com>`.

- `reply_to` (string): Adresse de réponse (Reply-To). Vaut `from_email` par défaut lors de l’envoi de la campagne.

- `html` (string): Corps HTML envoyé par Emailit. Prend en charge les balises de fusion `{{first_name}}`, `{{last_name}}`, `{{email}}`, `{{unsubscribe_url}}` et `{{cf.<key>}}` pour les champs personnalisés. Définissez le corps lors de la création de la campagne.

- `text` (string): Corps en texte brut. Prend en charge les mêmes balises de fusion que `html`.

- `preview_text` (string): Texte d’aperçu enregistré avec la campagne. Emailit ne l’insère pas dans le message ; ajoutez un pré-en-tête (preheader) masqué à `html` si vous en avez besoin.

- `content` (string): Source du corps dans l’éditeur (par exemple MJML), enregistrée telle quelle. Emailit envoie `html` et `text`, pas `content`.

- `content_type` (string): Format de `content` : `html`, `text` ou `mjml`. Emailit ne compile pas le MJML ; envoyez le HTML compilé dans `html`.

## Réponse

Renvoie `201 Created` avec l’objet campagne. `status` vaut `draft`. La réponse ne renvoie pas `html`, `text` ni `content`.

Renvoie `400` si `name` est absent et `403` si la clé API n’a pas la portée `full`.

**Requête** `POST /campaigns`

**cURL**

```bash
curl -X POST https://api.emailit.com/v2/campaigns \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "October newsletter",
    "subject": "October news for {{first_name}}",
    "from_email": "news@acme.com",
    "from_name": "Acme",
    "reply_to": "support@acme.com",
    "html": "<p>Hi {{first_name}},</p><p>Here is what changed this month.</p><p><a href=\"{{unsubscribe_url}}\">Unsubscribe</a></p>",
    "text": "Hi {{first_name}}, here is what changed this month. Unsubscribe: {{unsubscribe_url}}"
  }'
```

**Node.js**

```javascript
const res = await fetch('https://api.emailit.com/v2/campaigns', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.EMAILIT_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'October newsletter',
    subject: 'October news for {{first_name}}',
    from_email: 'news@acme.com',
    from_name: 'Acme',
    reply_to: 'support@acme.com',
    html: '<p>Hi {{first_name}},</p><p>Here is what changed this month.</p><p><a href="{{unsubscribe_url}}">Unsubscribe</a></p>',
    text: 'Hi {{first_name}}, here is what changed this month. Unsubscribe: {{unsubscribe_url}}',
  }),
});
const campaign = await res.json();
```

**Python**

```python
import os, requests

r = requests.post(
    "https://api.emailit.com/v2/campaigns",
    headers={"Authorization": f"Bearer {os.environ['EMAILIT_API_KEY']}"},
    json={
        "name": "October newsletter",
        "subject": "October news for {{first_name}}",
        "from_email": "news@acme.com",
        "from_name": "Acme",
        "reply_to": "support@acme.com",
        "html": '<p>Hi {{first_name}},</p><p>Here is what changed this month.</p><p><a href="{{unsubscribe_url}}">Unsubscribe</a></p>',
        "text": "Hi {{first_name}}, here is what changed this month. Unsubscribe: {{unsubscribe_url}}",
    },
)
campaign = r.json()
```

**PHP**

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.emailit.com/v2/']);

$response = $client->post('campaigns', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('EMAILIT_API_KEY')],
    'json' => [
        'name' => 'October newsletter',
        'subject' => 'October news for {{first_name}}',
        'from_email' => 'news@acme.com',
        'from_name' => 'Acme',
        'reply_to' => 'support@acme.com',
        'html' => '<p>Hi {{first_name}},</p><p>Here is what changed this month.</p><p><a href="{{unsubscribe_url}}">Unsubscribe</a></p>',
        'text' => 'Hi {{first_name}}, here is what changed this month. Unsubscribe: {{unsubscribe_url}}',
    ],
]);
$campaign = json_decode($response->getBody(), true);
```

**201**

```json
{
  "object": "campaign",
  "id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
  "name": "October newsletter",
  "status": "draft",
  "subject": "October news for {{first_name}}",
  "from_email": "news@acme.com",
  "from_name": "Acme",
  "reply_to": "support@acme.com",
  "preview_text": null,
  "content_type": "html",
  "created_at": "2026-10-01T09:30:12.482193Z",
  "updated_at": "2026-10-01T09:30:12.482193Z"
}
```

**400**

```json
{
  "error": "Bad Request"
}
```

**403**

```json
{
  "statusCode": 403,
  "error": "Forbidden",
  "message": "Permission denied: campaigns:create"
}
```

---
Source: https://emailit.com/fr/docs/api-reference/campaigns/create/

## Récupérer une campagne — GET /campaigns/{id}

> Récupérez une campagne par son ID ou son nom, avec son statut, son expéditeur, sa programmation et les listes de contacts qu’elle cible.

# Récupérer une campagne

Récupère une campagne par son ID ou son nom. Nécessite une clé API avec la portée `full`.

`GET /campaigns/{id}`

## Paramètres de chemin

- `id` (string, obligatoire): L’ID de la campagne (`cmp_…`) ou son nom. Encodez pour l’URL les noms qui contiennent des espaces ou des caractères spéciaux.

## Réponse

Renvoie l’objet campagne.

- `object` (string): Toujours `campaign`.

- `id` (string): ID de la campagne, préfixé par `cmp_`.

- `status` (string): `draft`, `scheduled`, `queued`, `sending`, `sent`, `canceled` ou `archived`. `queued` signifie qu’une campagne programmée a atteint son heure d’envoi et attend un worker.

- `name` (string): Nom interne de la campagne.

- `subject` (string): Ligne d’objet, avec les balises de fusion non résolues.

- `from_email` (string): Adresse de l’expéditeur. `""` tant qu’elle n’est pas définie.

- `from_name` (string): Nom d’affichage de l’expéditeur. `""` tant qu’il n’est pas défini.

- `reply_to` (string): Adresse de réponse (Reply-To). `""` signifie que les réponses vont à `from_email`.

- `preview_text` (string | null): Texte d’aperçu enregistré avec la campagne.

- `content_type` (string): Libellé du format de la source dans l’éditeur : `html`, `text` ou `mjml` pour les campagnes créées via l’API.

- `scheduled_at` (string | null): Date d’envoi d’une campagne programmée, en UTC.

- `sent_at` (string | null): Date de début de l’envoi.

- `recipients` (object[]): Listes de contacts ciblées par la campagne. Chaque élément contient `audience_id` (`aud_…`) et `exclude` (`true` pour une liste exclue).

Le corps (`html`, `text` et `content`) n’est pas inclus dans la réponse. Les statistiques d’engagement sont disponibles dans le tableau de bord, sous **Email Marketing → Campaigns**.

Renvoie `404` si aucune campagne de l’espace de travail ne correspond à `id`.

**Requête** `GET /campaigns/{id}`

**cURL**

```bash
curl https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN \
  -H "Authorization: Bearer $EMAILIT_API_KEY"
```

**Node.js**

```javascript
const res = await fetch('https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN', {
  headers: { Authorization: `Bearer ${process.env.EMAILIT_API_KEY}` },
});
const campaign = await res.json();
```

**Python**

```python
import os, requests

r = requests.get(
    "https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
    headers={"Authorization": f"Bearer {os.environ['EMAILIT_API_KEY']}"},
)
campaign = r.json()
```

**PHP**

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.emailit.com/v2/']);

$response = $client->get('campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('EMAILIT_API_KEY')],
]);
$campaign = json_decode($response->getBody(), true);
```

**200**

```json
{
  "object": "campaign",
  "id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
  "name": "October newsletter",
  "status": "scheduled",
  "subject": "October news for {{first_name}}",
  "from_email": "news@acme.com",
  "from_name": "Acme",
  "reply_to": "support@acme.com",
  "preview_text": null,
  "content_type": "html",
  "sent_at": null,
  "scheduled_at": "2026-10-08 09:00:00+00",
  "created_at": "2026-10-01 09:30:12.482193+00",
  "updated_at": "2026-10-01 10:02:47.118204+00",
  "recipients": [
    { "audience_id": "aud_3Cz7WJ9GpvD7P0PQez50xOmkZSV", "exclude": false },
    { "audience_id": "aud_3hRmYTSQ4ca6y9tbPI0IQPjVTL9", "exclude": true }
  ]
}
```

**404**

```json
{
  "error": "Campaign not found"
}
```

---
Source: https://emailit.com/fr/docs/api-reference/campaigns/get/

## Mettre à jour une campagne — POST /campaigns/{id}

> Modifiez le nom, l’expéditeur, l’objet ou le texte d’aperçu d’une campagne, et définissez les listes de contacts auxquelles elle est envoyée ou qu’elle exclut.

# Mettre à jour une campagne

Met à jour les champs transmis et laisse les autres inchangés. Utilisez cet endpoint pour choisir les listes de contacts de la campagne avant de l’envoyer. Nécessite une clé API avec la portée `full`. Émet l’événement `campaign.updated`.

Une campagne programmée envoie le contenu enregistré à son heure d’envoi : vous pouvez donc encore la modifier après l’avoir programmée.

`POST /campaigns/{id}`

## Paramètres de chemin

- `id` (string, obligatoire): L’ID de la campagne (`cmp_…`) ou son nom.

## Paramètres du corps

- `name` (string): Nom interne de la campagne.

- `subject` (string): Ligne d’objet. Prend en charge les [balises de fusion](/fr/docs/campaigns/merge-tags/).

- `from_email` (string): Adresse de l’expéditeur, sur un domaine d’envoi vérifié.

- `from_name` (string): Nom d’affichage de l’expéditeur.

- `reply_to` (string): Adresse de réponse (Reply-To). Une chaîne vide signifie que les réponses vont à `from_email`.

- `preview_text` (string): Texte d’aperçu enregistré avec la campagne.

- `content` (string): Source du corps dans l’éditeur, enregistrée telle quelle.

- `content_type` (string): Format de `content` : `html`, `text` ou `mjml`.

- `recipients` (object[]): Les listes de contacts à cibler. Remplace la liste actuelle. Incluez au moins une liste avec `exclude` défini sur `false`. - `audience_id` (chaîne, obligatoire) : un ID de liste (`aud_…`) de cet espace de travail. - `exclude` (booléen, par défaut `false`) : `true` enregistre la liste comme exclusion. Le tableau de bord soustrait les listes exclues de son estimation du nombre de destinataires, mais l’envoi lui-même n’applique pas les exclusions pour le moment : retirez donc aussi ces contacts des listes incluses. Les ID de liste en double sont ignorés. Au moment de l’envoi, Emailit envoie un e-mail une seule fois à chaque contact abonné des listes incluses, et ignore les contacts désinscrits et les adresses bloquées.

Le corps HTML et le corps texte sont définis lors de la [création de la campagne](/fr/docs/api-reference/campaigns/create/). Les champs inconnus du corps de la requête sont ignorés.

## Réponse

Renvoie l’objet campagne mis à jour, avec `recipients`.

Renvoie `422` si `recipients` ne contient aucune liste incluse ou fait référence à une liste extérieure à l’espace de travail, et `404` si la campagne n’existe pas.

**Requête** `POST /campaigns/{id}`

**cURL**

```bash
curl -X POST https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "subject": "Your October update, {{first_name}}",
    "recipients": [
      { "audience_id": "aud_3Cz7WJ9GpvD7P0PQez50xOmkZSV" },
      { "audience_id": "aud_3hRmYTSQ4ca6y9tbPI0IQPjVTL9", "exclude": true }
    ]
  }'
```

**Node.js**

```javascript
const res = await fetch('https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.EMAILIT_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    subject: 'Your October update, {{first_name}}',
    recipients: [
      { audience_id: 'aud_3Cz7WJ9GpvD7P0PQez50xOmkZSV' },
      { audience_id: 'aud_3hRmYTSQ4ca6y9tbPI0IQPjVTL9', exclude: true },
    ],
  }),
});
const campaign = await res.json();
```

**Python**

```python
import os, requests

r = requests.post(
    "https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
    headers={"Authorization": f"Bearer {os.environ['EMAILIT_API_KEY']}"},
    json={
        "subject": "Your October update, {{first_name}}",
        "recipients": [
            {"audience_id": "aud_3Cz7WJ9GpvD7P0PQez50xOmkZSV"},
            {"audience_id": "aud_3hRmYTSQ4ca6y9tbPI0IQPjVTL9", "exclude": True},
        ],
    },
)
campaign = r.json()
```

**PHP**

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.emailit.com/v2/']);

$response = $client->post('campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('EMAILIT_API_KEY')],
    'json' => [
        'subject' => 'Your October update, {{first_name}}',
        'recipients' => [
            ['audience_id' => 'aud_3Cz7WJ9GpvD7P0PQez50xOmkZSV'],
            ['audience_id' => 'aud_3hRmYTSQ4ca6y9tbPI0IQPjVTL9', 'exclude' => true],
        ],
    ],
]);
$campaign = json_decode($response->getBody(), true);
```

**200**

```json
{
  "object": "campaign",
  "id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
  "name": "October newsletter",
  "status": "draft",
  "subject": "Your October update, {{first_name}}",
  "from_email": "news@acme.com",
  "from_name": "Acme",
  "reply_to": "support@acme.com",
  "preview_text": null,
  "content_type": "html",
  "scheduled_at": null,
  "created_at": "2026-10-01 09:30:12.482193+00",
  "updated_at": "2026-10-01 10:02:47.118204+00",
  "recipients": [
    { "audience_id": "aud_3Cz7WJ9GpvD7P0PQez50xOmkZSV", "exclude": false },
    { "audience_id": "aud_3hRmYTSQ4ca6y9tbPI0IQPjVTL9", "exclude": true }
  ]
}
```

**422**

```json
{
  "message": "Validation failed.",
  "errors": {
    "recipients": ["One or more audiences are invalid."]
  }
}
```

**404**

```json
{
  "error": "Campaign not found"
}
```

---
Source: https://emailit.com/fr/docs/api-reference/campaigns/update/

## Lister les campagnes — GET /campaigns

> Listez les campagnes d’un espace de travail, de la plus récente à la plus ancienne, avec pagination par numéro de page, recherche et filtres par statut, nom et dates.

# Lister les campagnes

Renvoie les campagnes de l’espace de travail, de la plus récente à la plus ancienne. Nécessite une clé API avec la portée `full`.

`GET /campaigns`

## Paramètres de requête

- `page` (integer): Numéro de page, à partir de 1.

- `limit` (integer): Campagnes par page, de 1 à 100.

- `search` (string): Correspondance insensible à la casse sur le nom ou l’objet de la campagne.

- `status` (string): Filtre de statut raccourci : `draft`, `scheduled`, `sending` (correspond aussi à `queued`), `sent`, `canceled`, `archived` ou `all`.

- `match`, `order`, `direction`: voir [Filtrage et tri](https://emailit.com/fr/docs/api-reference/filtering/).

### Clés de filtre

Les filtres utilisent des paramètres de requête `key.condition=value`, par exemple `status.exact=sent` ou `created_at.after=2026-09-01`. Pour les conditions propres à chaque type, consultez [Filtrage et tri](/fr/docs/api-reference/filtering/).

| Clé | Type | Remarques |
| --- | --- | --- |
| `name` | chaîne | |
| `subject` | chaîne | |
| `status` | énumération | `draft`, `scheduled`, `queued`, `sending`, `sent`, `archived` |
| `created_at` | date | |
| `sent_at` | date | |

Clés de tri pour `order` : `name`, `subject`, `status`, `created_at`, `sent_at`.

## Réponse

Renvoie une page d’objets campagne sans `reply_to`, `preview_text`, `content_type` ni `recipients`. Pour ces champs, utilisez [Récupérer une campagne](/fr/docs/api-reference/campaigns/get/).

- `data` (object[]): Campagnes de cette page.

- `total_records` (integer): Nombre de campagnes correspondant à la requête.

- `next_page_url` (string | null): Chemin de la page suivante, ou `null` sur la dernière page. Il ne contient que `page` et `limit` : ajoutez de nouveau votre recherche et vos filtres quand vous le suivez.

- `previous_page_url` (string | null): Chemin de la page précédente, ou `null` sur la première page.

**Requête** `GET /campaigns`

**cURL**

```bash
curl -G https://api.emailit.com/v2/campaigns \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -d limit=20 \
  -d status=sent \
  -d order=sent_at \
  -d direction=desc
```

**Node.js**

```javascript
const params = new URLSearchParams({ limit: '20', status: 'sent', order: 'sent_at', direction: 'desc' });
const res = await fetch(`https://api.emailit.com/v2/campaigns?${params}`, {
  headers: { Authorization: `Bearer ${process.env.EMAILIT_API_KEY}` },
});
const { data, total_records } = await res.json();
```

**Python**

```python
import os, requests

r = requests.get(
    "https://api.emailit.com/v2/campaigns",
    headers={"Authorization": f"Bearer {os.environ['EMAILIT_API_KEY']}"},
    params={"limit": 20, "status": "sent", "order": "sent_at", "direction": "desc"},
)
campaigns = r.json()["data"]
```

**PHP**

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.emailit.com/v2/']);

$response = $client->get('campaigns', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('EMAILIT_API_KEY')],
    'query' => ['limit' => 20, 'status' => 'sent', 'order' => 'sent_at', 'direction' => 'desc'],
]);
$campaigns = json_decode($response->getBody(), true)['data'];
```

**200**

```json
{
  "data": [
    {
      "object": "campaign",
      "id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
      "name": "October newsletter",
      "status": "sent",
      "subject": "Your October update, {{first_name}}",
      "from_email": "news@acme.com",
      "from_name": "Acme",
      "sent_at": "2026-10-08 09:00:04+00",
      "scheduled_at": "2026-10-08 09:00:00+00",
      "created_at": "2026-10-01 09:30:12.482193+00",
      "updated_at": "2026-10-08 09:00:31+00"
    }
  ],
  "total_records": 34,
  "next_page_url": "/v2/campaigns?page=2&limit=20",
  "previous_page_url": null
}
```

---
Source: https://emailit.com/fr/docs/api-reference/campaigns/list/

## Envoyer ou programmer une campagne — POST /campaigns/{id}/send

> Envoyez une campagne à ses listes de contacts immédiatement, ou programmez une campagne en brouillon pour une date et une heure ultérieures.

# Envoyer ou programmer une campagne

Envoie la campagne immédiatement, ou la programme si vous transmettez un `scheduled_at` dans le futur. Nécessite une clé API avec la portée `full` et un [espace de travail vérifié](/fr/docs/workspaces/production-access/) : les espaces de travail non vérifiés ne peuvent pas envoyer de campagnes et reçoivent `403`.

Avant l’envoi, vérifiez que la campagne a une adresse `from_email` sur un domaine vérifié, un objet, un corps `html` ou `text` et au moins une liste de contacts incluse (définie avec [Mettre à jour une campagne](/fr/docs/api-reference/campaigns/update/)). Chaque e-mail coûte 2 crédits.

`POST /campaigns/{id}/send`

## Paramètres de chemin

- `id` (string, obligatoire): L’ID de la campagne (`cmp_…`) ou son nom.

## Paramètres du corps

- `scheduled_at` (string): Date d’envoi. Accepte le format ISO 8601 (`2026-10-08T09:00:00Z`), un horodatage Unix en secondes ou du langage naturel comme `tomorrow at 9am` (interprété en UTC). L’heure doit être dans le futur et la campagne doit être au statut `draft`. Omettez-le pour envoyer immédiatement. Pour envoyer une campagne programmée plus tôt que prévu, appelez cet endpoint sans `scheduled_at`.

## Réponse

**Envoi immédiat :** le statut passe à `sending` et Emailit émet `campaign.sending`. Emailit crée ensuite un e-mail par destinataire : chaque contact abonné des listes incluses, dédoublonné par adresse, sans les contacts désinscrits ni les adresses bloquées. Une fois chaque destinataire transmis à la chaîne d’envoi, le statut passe à `sent` et Emailit émet `campaign.sent`. Suivez la livraison dans le tableau de bord ou avec les [événements d’e-mail](/fr/docs/webhooks/event-types/).

**Programmation :** le statut passe à `scheduled` et Emailit émet `campaign.scheduled`. À l’heure prévue, la campagne passe à `queued` (`campaign.queued`), puis est envoyée comme ci-dessus.

La réponse contient `object`, `id`, `name` et le nouveau `status`, ainsi que `scheduled_at` en cas de programmation.

| Statut | Cas |
| --- | --- |
| `403` | L’espace de travail n’est pas vérifié, ou la clé API n’a pas la portée `full`. |
| `404` | Aucune campagne ne correspond à `id`. |
| `422` | `scheduled_at` ne peut pas être analysé ou n’est pas dans le futur, ou vous avez tenté de programmer une campagne qui n’est pas un brouillon. |

**Requête** `POST /campaigns/{id}/send`

**cURL**

```bash
curl -X POST https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN/send \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "scheduled_at": "2026-10-08T09:00:00Z" }'
```

**Node.js**

```javascript
const res = await fetch('https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN/send', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.EMAILIT_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ scheduled_at: '2026-10-08T09:00:00Z' }),
});
const campaign = await res.json();
```

**Python**

```python
import os, requests

r = requests.post(
    "https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN/send",
    headers={"Authorization": f"Bearer {os.environ['EMAILIT_API_KEY']}"},
    json={"scheduled_at": "2026-10-08T09:00:00Z"},
)
campaign = r.json()
```

**PHP**

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.emailit.com/v2/']);

$response = $client->post('campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN/send', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('EMAILIT_API_KEY')],
    'json' => ['scheduled_at' => '2026-10-08T09:00:00Z'],
]);
$campaign = json_decode($response->getBody(), true);
```

**200 scheduled**

```json
{
  "object": "campaign",
  "id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
  "name": "October newsletter",
  "status": "scheduled",
  "scheduled_at": "2026-10-08T09:00:00.000000Z"
}
```

**200 sending**

```json
{
  "object": "campaign",
  "id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
  "name": "October newsletter",
  "status": "sending"
}
```

**403**

```json
{
  "code": "unverified_workspace_recipient",
  "error": "Workspace not verified",
  "message": "Unverified workspaces cannot send campaigns. You can send individual emails only to workspace members' account emails."
}
```

**422**

```json
{
  "error": "Campaign cannot be scheduled",
  "message": "Campaign status is 'sent'. Only draft campaigns can be scheduled."
}
```

---
Source: https://emailit.com/fr/docs/api-reference/campaigns/send/

## Annuler une campagne — POST /campaigns/{id}/cancel

> Annulez une campagne en brouillon ou en cours d’envoi. Les e-mails déjà en file d’attente de livraison ne sont pas rappelés.

# Annuler une campagne

Passe le statut de la campagne à `canceled` et émet l’événement `campaign.canceled`. Nécessite une clé API avec la portée `full`.

Seules les campagnes au statut `draft` ou `sending` peuvent être annulées ; tout autre statut renvoie `422`. L’annulation d’une campagne en cours d’envoi ne rappelle pas les e-mails déjà en file d’attente de livraison.

`POST /campaigns/{id}/cancel`

## Paramètres de chemin

- `id` (string, obligatoire): L’ID de la campagne (`cmp_…`) ou son nom.

## Réponse

Renvoie `object`, `id`, `name` et `status` (`canceled`).

Renvoie `422` si le statut de la campagne n’est ni `draft` ni `sending`, et `404` si la campagne n’existe pas.

**Requête** `POST /campaigns/{id}/cancel`

**cURL**

```bash
curl -X POST https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN/cancel \
  -H "Authorization: Bearer $EMAILIT_API_KEY"
```

**Node.js**

```javascript
const res = await fetch('https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN/cancel', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.EMAILIT_API_KEY}` },
});
const campaign = await res.json();
```

**Python**

```python
import os, requests

r = requests.post(
    "https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN/cancel",
    headers={"Authorization": f"Bearer {os.environ['EMAILIT_API_KEY']}"},
)
campaign = r.json()
```

**PHP**

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.emailit.com/v2/']);

$response = $client->post('campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN/cancel', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('EMAILIT_API_KEY')],
]);
$campaign = json_decode($response->getBody(), true);
```

**200**

```json
{
  "object": "campaign",
  "id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
  "name": "October newsletter",
  "status": "canceled"
}
```

**422**

```json
{
  "error": "Campaign cannot be canceled",
  "message": "Campaign status is 'scheduled'. Only 'draft' or 'sending' campaigns can be canceled."
}
```

**404**

```json
{
  "error": "Campaign not found"
}
```

---
Source: https://emailit.com/fr/docs/api-reference/campaigns/cancel/

## Supprimer une campagne — DELETE /campaigns/{id}

> Supprimez définitivement une campagne par son ID ou son nom. Émet l’événement campaign.deleted ; les e-mails déjà envoyés ne sont pas concernés.

# Supprimer une campagne

Supprime définitivement une campagne. Nécessite une clé API avec la portée `full`. Émet l’événement `campaign.deleted`.

La suppression d’une campagne n’a aucun effet sur les e-mails déjà envoyés ou en file d’attente. Pour arrêter une campagne en cours d’envoi, [annulez-la](/fr/docs/api-reference/campaigns/cancel/) d’abord.

`DELETE /campaigns/{id}`

## Paramètres de chemin

- `id` (string, obligatoire): L’ID de la campagne (`cmp_…`) ou son nom.

## Réponse

Renvoie `object`, `id`, `name` et `deleted: true`. Renvoie `404` si la campagne n’existe pas.

**Requête** `DELETE /campaigns/{id}`

**cURL**

```bash
curl -X DELETE https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN \
  -H "Authorization: Bearer $EMAILIT_API_KEY"
```

**Node.js**

```javascript
const res = await fetch('https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN', {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${process.env.EMAILIT_API_KEY}` },
});
const result = await res.json();
```

**Python**

```python
import os, requests

r = requests.delete(
    "https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
    headers={"Authorization": f"Bearer {os.environ['EMAILIT_API_KEY']}"},
)
result = r.json()
```

**PHP**

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.emailit.com/v2/']);

$response = $client->delete('campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('EMAILIT_API_KEY')],
]);
$result = json_decode($response->getBody(), true);
```

**200**

```json
{
  "object": "campaign",
  "id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
  "name": "October newsletter",
  "deleted": true
}
```

**404**

```json
{
  "error": "Campaign not found"
}
```

---
Source: https://emailit.com/fr/docs/api-reference/campaigns/delete/
