# Envoyer un e-mail

> Envoyer des e-mails avec POST /emails – règles d’expéditeur, destinataires, contenu, modèles, suivi, réponse, événements webhook et tous les codes d’erreur.

Ce guide détaille chaque partie d’une requête `POST /emails` et ce qu’Emailit en fait, de l’adresse d’expéditeur jusqu’aux erreurs que vous pouvez recevoir. Pour la référence complète des paramètres, consultez [Envoyer un e-mail](/fr/docs/api-reference/emails/send/) dans la référence de l’API.

## Avant de commencer

- Un domaine d’envoi vérifié dans votre espace de travail. Consultez [Ajouter un domaine](/fr/docs/domains/add-a-domain/).
- Une clé API de portée **Full Access** ou **Sending Only**. Consultez [Clés API](/fr/docs/developers/api-keys/).
- L’accès production si vous envoyez à d’autres personnes que les membres de votre espace de travail. Consultez [Accès production](/fr/docs/workspaces/production-access/).
- Assez de crédits pour chaque destinataire (1 crédit chacun).

## Envoyer un e-mail simple

**cURL**

```bash
curl https://api.emailit.com/v2/emails \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "Acme Billing <billing@acme.com>",
    "to": ["ada@example.com", "Grace Hopper <grace@example.com>"],
    "cc": "accounts@example.com",
    "reply_to": "support@acme.com",
    "subject": "Your invoice for October",
    "html": "<p>Your invoice is ready.</p>",
    "text": "Your invoice is ready."
  }'
```

**Node.js**

```javascript
import { Emailit } from '@emailit/node';

const emailit = new Emailit(process.env.EMAILIT_API_KEY);

const email = await emailit.emails.send({
  from: 'Acme Billing <billing@acme.com>',
  to: ['ada@example.com', 'Grace Hopper <grace@example.com>'],
  cc: 'accounts@example.com',
  reply_to: 'support@acme.com',
  subject: 'Your invoice for October',
  html: '<p>Your invoice is ready.</p>',
  text: 'Your invoice is ready.',
});
```

**Python**

```python
import os
from emailit import EmailitClient

client = EmailitClient(os.environ["EMAILIT_API_KEY"])

email = client.emails.send({
    "from": "Acme Billing <billing@acme.com>",
    "to": ["ada@example.com", "Grace Hopper <grace@example.com>"],
    "cc": "accounts@example.com",
    "reply_to": "support@acme.com",
    "subject": "Your invoice for October",
    "html": "<p>Your invoice is ready.</p>",
    "text": "Your invoice is ready.",
})
```

**PHP**

```php
$emailit = Emailit::client(getenv('EMAILIT_API_KEY'));

$email = $emailit->emails()->send([
    'from' => 'Acme Billing <billing@acme.com>',
    'to' => ['ada@example.com', 'Grace Hopper <grace@example.com>'],
    'cc' => 'accounts@example.com',
    'reply_to' => 'support@acme.com',
    'subject' => 'Your invoice for October',
    'html' => '<p>Your invoice is ready.</p>',
    'text' => 'Your invoice is ready.',
]);
```

## Définir l’adresse d’expéditeur

`from` est obligatoire et accepte une adresse sous l’une de ces formes :

- `billing@acme.com`
- `Acme Billing <billing@acme.com>`, ou avec des guillemets, `"Acme, Inc." <billing@acme.com>`

Le domaine après le `@` doit être un domaine d’envoi vérifié du même espace de travail :

- **La correspondance est exacte.** La comparaison ignore la casse, mais `mail.acme.com` et `acme.com` sont des domaines différents. Ajoutez et vérifiez chaque sous-domaine depuis lequel vous envoyez.
- **N’importe quelle partie locale convient.** Vous n’avez pas besoin d’une boîte aux lettres pour `billing@` ou `no-reply@`.
- **Les domaines en attente ne peuvent pas envoyer.** Un domaine encore en attente d’examen (**Pending verification**) est traité comme non vérifié.
- **Les clés restreintes restent sur leur domaine.** Une clé **Sending Only** restreinte à un domaine ne peut envoyer que depuis ce domaine.
- **Les domaines en pause sont bloqués.** Si la [santé d’envoi](/fr/docs/deliverability/sending-health/) a mis le domaine en pause, les envois depuis ce domaine sont rejetés jusqu’à la levée de la pause.

## Ajouter des destinataires

`to` est obligatoire. `cc` et `bcc` sont facultatifs. Chaque champ accepte une chaîne ou un tableau de chaînes, avec ou sans nom d’affichage, et contient 50 adresses au maximum. Une chaîne peut contenir plusieurs adresses séparées par des virgules ; utilisez un tableau quand un nom d’affichage contient lui-même une virgule.

Emailit supprime les doublons entre `to`, `cc` et `bcc` (sans tenir compte de la casse), puis crée **un e-mail par destinataire unique**, chacun avec son propre ID `em_`. Chaque copie porte les mêmes en-têtes `To` et `Cc`, si bien que les destinataires voient la conversation comme d’habitude, et les destinataires `Bcc` n’apparaissent jamais dans les en-têtes d’une copie.

Quand une requête a plus d’un destinataire, la réponse inclut un objet `ids` qui associe chaque destinataire à l’ID de son e-mail. `id` est l’e-mail du premier destinataire.

```json
{
  "object": "email",
  "id": "em_33VtK8mRq1xZp7LwN4cY2bHsDfa",
  "ids": {
    "ada@example.com": "em_33VtK8mRq1xZp7LwN4cY2bHsDfa",
    "grace@example.com": "em_33VtK8nB5rTq0YxW3mJk9PdLsUe",
    "accounts@example.com": "em_33VtK8nQ2wErT6yU8iOp4AsDf7g"
  }
}
```

Chaque destinataire coûte 1 crédit et compte dans vos [limites de débit](/fr/docs/api-reference/rate-limits/). Un destinataire faisant l’objet d’un [blocage](/fr/docs/suppressions/) de type `recipient` est accepté, puis marqué `suppressed` au lieu d’être livré.

## Rédiger le contenu

| Champ | Règles |
| --- | --- |
| `subject` | Obligatoire, sauf si un modèle le fournit. Les caractères non ASCII sont encodés pour vous. |
| `html` | Le corps HTML. Il vous faut `html`, `text` ou les deux, sauf si un modèle les fournit. |
| `text` | Le corps en texte brut. Envoyez-le avec `html` : certains clients de messagerie et filtres anti-spam préfèrent les messages qui contiennent les deux. |
| `reply_to` | Une chaîne ou un tableau d’adresses auxquelles les réponses doivent être envoyées. |

Si `reply_to` indique la même adresse que `from`, Emailit supprime l’en-tête `Reply-To`, car il n’apporte rien et certains filtres anti-spam le pénalisent.

## Envoyer avec un modèle

Renseignez dans `template` l’alias d’un modèle ou un ID `tem_`, et transmettez `variables` pour les variables [Temple](/fr/docs/templates/temple/) qu’il contient.

- **Un alias** envoie la version actuellement publiée pour cet alias. Si aucune version n’est publiée, la requête échoue avec `404`.
- **Un ID `tem_`** envoie cette version précise, publiée ou non. Utilisez-le pour tester une version brouillon avant de la publier.

Les champs de la requête ont priorité sur le modèle : un `subject`, un `html` ou un `text` que vous envoyez remplace la valeur du modèle. Si vous n’envoyez pas `reply_to`, l’adresse de réponse (Reply-To) du modèle est utilisée. `from` est toujours obligatoire dans la requête. Pour comprendre le fonctionnement de la publication, consultez [Versions de modèle](/fr/docs/templates/versions/).

**cURL**

```bash
curl https://api.emailit.com/v2/emails \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "Acme <hello@acme.com>",
    "to": "ada@example.com",
    "template": "welcome-email",
    "variables": {
      "first_name": "Ada",
      "plan": "Pro",
      "activation_url": "https://acme.com/activate?token=8f3k2"
    }
  }'
```

**Node.js**

```javascript
const email = await emailit.emails.send({
  from: 'Acme <hello@acme.com>',
  to: 'ada@example.com',
  template: 'welcome-email',
  variables: {
    first_name: 'Ada',
    plan: 'Pro',
    activation_url: 'https://acme.com/activate?token=8f3k2',
  },
});
```

**Python**

```python
email = client.emails.send({
    "from": "Acme <hello@acme.com>",
    "to": "ada@example.com",
    "template": "welcome-email",
    "variables": {
        "first_name": "Ada",
        "plan": "Pro",
        "activation_url": "https://acme.com/activate?token=8f3k2",
    },
})
```

**PHP**

```php
$email = $emailit->emails()->send([
    'from' => 'Acme <hello@acme.com>',
    'to' => 'ada@example.com',
    'template' => 'welcome-email',
    'variables' => [
        'first_name' => 'Ada',
        'plan' => 'Pro',
        'activation_url' => 'https://acme.com/activate?token=8f3k2',
    ],
]);
```

`variables` fonctionne aussi sans modèle : Emailit effectue le rendu des variables Temple dans le `subject`, le `html` et le `text` que vous envoyez directement.

## Gérer le suivi

Par défaut, chaque e-mail suit les paramètres **Track loads** et **Track clicks** de son domaine d’envoi. Remplacez-les pour un e-mail donné avec `tracking` :

- `"tracking": true` ou `false` active ou désactive à la fois le suivi des chargements (ouvertures) et celui des clics.
- `"tracking": { "loads": true, "clicks": false }` règle chacun séparément.

Le suivi ne fonctionne que si le CNAME de suivi du domaine est vérifié. Sans lui, l’e-mail est envoyé sans suivi et la requête réussit quand même. L’objet `tracking` de la réponse indique les paramètres réellement appliqués. Consultez [Suivi des ouvertures et des clics](/fr/docs/tracking/).

## Ajouter des en-têtes et des métadonnées

Utilisez `headers` pour les en-têtes d’e-mail personnalisés, comme `List-Unsubscribe`, et `meta` pour vos propres paires clé-valeur de type chaîne. Emailit enregistre `meta` avec l’e-mail et l’inclut dans les événements webhook. Consultez [En-têtes et métadonnées](/fr/docs/email-api/headers-and-metadata/).

Pour joindre des fichiers, programmer l’envoi ou sécuriser les relances, consultez [Pièces jointes](/fr/docs/email-api/attachments/), [Programmation](/fr/docs/email-api/scheduling/) et [Idempotence](/fr/docs/email-api/idempotency/).

## Lire la réponse

Une requête réussie renvoie `200` :

| Champ | Description |
| --- | --- |
| `object` | Toujours `email`. |
| `id` | L’ID `em_` de l’e-mail du premier destinataire. |
| `ids` | Objet associant chaque adresse de destinataire à l’ID de l’e-mail. Présent uniquement s’il y a plus d’un destinataire. |
| `token` | Jeton interne du premier e-mail, utilisé aussi dans son Message-ID. |
| `message_id` | L’en-tête `Message-ID` du premier e-mail, sous la forme `<token@your-domain>`. |
| `from` | L’adresse d’expéditeur telle que vous l’avez envoyée. |
| `to` | Les adresses `to`, sans les noms d’affichage. |
| `cc`, `bcc` | Les adresses `cc` et `bcc`. Présent uniquement si vous les avez envoyées. |
| `subject` | L’objet final, après le rendu du modèle. |
| `status` | `accepted`, ou `scheduled` quand l’e-mail a une heure d’envoi future. |
| `scheduled_at` | L’heure d’envoi au format ISO 8601, ou `null`. |
| `created_at` | Date de création de l’e-mail. |
| `tracking` | Les paramètres `loads` et `clicks` appliqués. |

Conservez l’`id` (ou l’objet `ids`) pour faire correspondre les futurs événements webhook et retrouver l’e-mail avec [Récupérer un e-mail](/fr/docs/api-reference/emails/get/).

## Événements

L’e-mail de chaque destinataire émet ses propres événements :

1. [`email.accepted`](/fr/docs/webhooks/events/email/accepted/) juste après la requête, ou [`email.scheduled`](/fr/docs/webhooks/events/email/scheduled/) s’il a une heure d’envoi future.
2. Des événements de livraison à mesure que l’e-mail progresse dans la chaîne de traitement : [`email.delivered`](/fr/docs/webhooks/events/email/delivered/), [`email.attempted`](/fr/docs/webhooks/events/email/attempted/) (échec temporaire, Emailit réessaiera), [`email.bounced`](/fr/docs/webhooks/events/email/bounced/), [`email.failed`](/fr/docs/webhooks/events/email/failed/), [`email.rejected`](/fr/docs/webhooks/events/email/rejected/) ou [`email.suppressed`](/fr/docs/webhooks/events/email/suppressed/). Un e-mail retenu pour examen émet `email.held`.
3. Des événements d’engagement, si le suivi est activé : [`email.loaded`](/fr/docs/webhooks/events/email/loaded/) et [`email.clicked`](/fr/docs/webhooks/events/email/clicked/). Les signalements comme spam émettent [`email.complained`](/fr/docs/webhooks/events/email/complained/).

Pour la signification de chaque statut, consultez [Statuts des e-mails](/fr/docs/logs/email-statuses/).

## Erreurs

Les erreurs de validation renvoient la liste de tous les problèmes détectés :

```json
{
  "error": "Validation failed",
  "validation_errors": [
    "Missing required field: subject",
    "Invalid to email address at index 1: grace@"
  ]
}
```

| Statut | `error` | Cause | Solution |
| --- | --- | --- | --- |
| `400` | `Validation failed` | Un champ obligatoire manque, une adresse est mal formée, un champ contient plus de 50 destinataires ou une pièce jointe est invalide. | Corrigez chaque élément de `validation_errors`. |
| `400` | `Invalid Idempotency-Key` | L’en-tête `Idempotency-Key` est mal formé. | Utilisez de 1 à 256 lettres, chiffres, `-` ou `_`. Voir [Idempotence](/fr/docs/email-api/idempotency/). |
| `401` | `Unauthorized` | La clé API est absente ou invalide. | Envoyez `Authorization: Bearer` avec une clé valide. |
| `402` | `Insufficient credits` | L’espace de travail ne peut pas payer pour tous les destinataires. | [Achetez des crédits](/fr/docs/billing/credits/) ou activez la [recharge automatique](/fr/docs/billing/auto-refill/). |
| `403` | `Workspace not verified` | L’espace de travail est en mode bac à sable et un destinataire n’est pas membre de l’espace de travail. `code` vaut `unverified_workspace_recipient` et `blocked_recipients` liste les adresses. | [Demandez l’accès production](/fr/docs/workspaces/production-access/), ou testez avec les adresses des membres. |
| `403` | `Domain not authorized` | La clé API est restreinte à un autre domaine d’envoi. | Envoyez depuis le domaine de la clé, ou utilisez une clé sans restriction de domaine. |
| `403` | `Domain paused` | La santé d’envoi a mis le domaine d’expéditeur en pause. | Voir [Santé d’envoi](/fr/docs/deliverability/sending-health/). |
| `404` | `Template not found` | L’alias n’a aucune version publiée, ou l’ID `tem_` n’existe pas dans cet espace de travail. | Publiez une version ou vérifiez l’ID. |
| `409` | `Idempotency key in progress` | Une autre requête avec la même clé est encore en cours. | Patientez, puis relancez avec la même clé. |
| `413` | `Message too large` | Le message encodé dépasse 40 Mo. | Envoyez moins de pièces jointes ou des pièces jointes plus petites, ou mettez un lien vers les fichiers volumineux. |
| `422` | `Domain not verified` | Le domaine d’expéditeur n’est pas un domaine d’envoi vérifié de cet espace de travail. | Vérifiez le domaine, ou cherchez un sous-domaine ou une faute de frappe. |
| `422` | `Attachment error` | L’URL d’une pièce jointe n’a pas pu être téléchargée ou dépasse 25 Mo. | Voir [Pièces jointes](/fr/docs/email-api/attachments/). |
| `429` | `Rate limit exceeded` ou `Daily limit exceeded` | Vous dépassez la limite d’envoi par seconde ou quotidienne. | Attendez `retry-after` secondes, ou demandez une limite plus élevée. |
| `503` | `Idempotency unavailable` | Le stockage d’idempotence est injoignable. | Relancez avec la même clé. |

Un espace de travail suspendu reçoit `403` avec `Workspace is suspended` à chaque envoi. Pour le format général des erreurs, consultez [Erreurs](/fr/docs/api-reference/errors/).

## Voir aussi

- [Envoyer un e-mail](/fr/docs/api-reference/emails/send/) dans la référence de l’API
- [Modèles](/fr/docs/templates/)
- [Statuts des e-mails](/fr/docs/logs/email-statuses/)
- [Types d’événements webhook](/fr/docs/webhooks/event-types/)
- [Pourquoi mon e-mail n’est-il pas arrivé ?](/fr/docs/kb/email-not-delivered-checklist/)

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