Sign inGet started

Envoi programmé

Définissez scheduled_at pour retenir un message jusqu'à une heure précise. Lorsque cette heure arrive, le message entre dans le cycle de livraison normal et produit les mêmes événements qu'un envoi immédiat. Votre application n'a pas besoin de gérer son propre planificateur.

Programmer un envoi

Ajoutez un horodatage scheduled_at à un envoi POST /v1/email/messages normal. Rien d'autre ne change dans le payload.
const msg = await bird.email.send({
  from: "news@yourdomain.com",
  to: ["delivered@messagebird.dev"],
  subject: "Your weekly digest",
  html: "<p>Here is what happened this week...</p>",
  category: "marketing",
  scheduled_at: "2027-01-15T09:00:00Z",
});
console.log(msg.id, msg.status); // "em_…", "accepted"
L'appel renvoie immédiatement 202 Accepted avec l'ID de message préfixé par em_ et status: accepted. C'est le même objet message qu'un envoi immédiat renvoie, plus scheduled_at renvoyé en UTC, ce qui vous permet de confirmer l'heure d'envoi sans lecture supplémentaire. L'acceptation est synchrone ; la livraison est différée. Omettez scheduled_at de la requête et le message part tout de suite ; sa réponse ne contient alors pas de clé scheduled_at.
Sur les endpoints de lecture, le message affiche status: scheduled avec son scheduled_at jusqu'à l'arrivée de l'heure d'envoi :
Exemple de code
{
  "id": "em_01ky7q24hafjgvzfg02v3m177p",
  "status": "scheduled",
  "scheduled_at": "2027-01-15T09:00:00Z",
  "category": "marketing"
}
Lorsque l'heure arrive, nous libérons le message et son statut progresse à travers les états habituels (accepted, puis processed, puis delivered, etc.). scheduled_at reste défini après coup, ce qui vous permet de toujours voir pour quand un message était programmé.
La programmation consomme une unité de l'enveloppe d'e-mails programmés de votre organisation pour la période de facturation. Dépasser cette enveloppe est rejeté avec un 422 (E10003).

Un envoi programmé utilise du contenu inline

scheduled_at et template sont mutuellement exclusifs, et un envoi qui définit les deux est rejeté avec un 422. C'est le contrat : un envoi programmé possède son propre subject et son corps, tandis qu'un envoi par template part immédiatement. Pour programmer du contenu de template, effectuez d'abord le rendu de son sujet et de son corps. Le tableau de bord et bird CLI prévisualisent le sujet, le HTML et le texte exacts qu'un envoi par template livrerait. Programmez ces valeurs rendues comme contenu inline.
Un élément de batch accepte scheduled_at aux mêmes conditions, ce qui permet à un batch de mélanger messages programmés et immédiats. Chaque élément programmé consomme sa propre unité de l'enveloppe, et le batch entier est rejeté si l'heure d'un élément est hors de la plage autorisée. Chaque élément programmé porte son propre scheduled_at dans la réponse du batch, et un élément envoyé immédiatement n'a pas de clé scheduled_at ; la référence batch montre les deux dans une même réponse.
Un payload d'envoi immédiat peut tout de même être trop volumineux pour être programmé. Si son corps, sa liste de destinataires ou ses métadonnées dépassent la limite de programmation, API renvoie 422. Réduisez ces champs ou envoyez le message immédiatement.

Choisir l'heure d'envoi

scheduled_at est un horodatage absolu RFC 3339. Deux règles le gouvernent :
  • L'heure doit se situer entre 30 secondes et 30 jours dans le futur. Moins de 30 secondes ou plus de 30 jours est rejeté avec un 422. Le seuil minimal empêche un envoi programmé d'entrer en concurrence avec un envoi immédiat. Trente jours est l'horizon le plus lointain pour lequel nous retenons un message.
  • Fournissez un instant exact. Incluez un suffixe UTC Z (2027-01-15T09:00:00Z) ou un décalage explicite (2026-07-30T09:00:00-04:00, le même instant que 13:00:00Z). Nous comparons l'instant à l'heure courante et n'interprétons jamais une heure locale brute ni n'appliquons le fuseau horaire du destinataire. Pour envoyer à 9 h dans l'heure locale de chaque destinataire, calculez vous-même ces instants et programmez un envoi par fuseau horaire.
Les expressions relatives comme "in 2 hours" ne sont pas acceptées. Envoyez un horodatage résolu.

Lister les messages programmés

Filtrez la liste des messages par statut pour voir ceux qui n'ont pas encore été envoyés :
for await (const message of bird.email.list({ status: "scheduled" })) {
  console.log(message.id, message.scheduled_at);
}
status=canceled liste ceux que vous avez annulés avant leur envoi. Une fois qu'un message programmé est déclenché, il entre dans le pipeline et apparaît avec les statuts de livraison, comme tout autre envoi. Le journal des e-mails du tableau de bord propose les mêmes filtres Scheduled et Canceled.

Annuler un envoi programmé

Annulez un message à tout moment avant qu'il ne commence à partir avec POST /v1/email/messages/{message_id}/cancel :
await bird.email.cancel("em_abc123");
Une annulation réussie renvoie 204 No Content. Le statut du message devient canceled, il n'est jamais envoyé, et un webhook email.canceled se déclenche. Quatre points à retenir :
  • Seul un message encore programmé peut être annulé. Un message dont l'envoi a déjà commencé, qui a déjà été envoyé ou déjà annulé renvoie 409 :
    Exemple de code
    {
      "error": {
        "type": "conflict_error",
        "code": "E10005",
        "name": "EmailNotCancelable",
        "message": "This message cannot be canceled.",
        "remediation": "Only a scheduled message that has not started sending can be canceled. Once sending begins there is no way to pull it back."
      }
    }
    À l'approche de l'heure d'envoi, une annulation peut aussi perdre la course face à l'envoi lui-même et renvoyer 409 pour la même raison.
  • Un envoi volumineux peut prendre quelques secondes avant de devenir annulable. Un envoi programmé avec des pièces jointes ou un corps volumineux est encore en cours de stockage après le 202, donc :
    1. Une annulation pendant cette fenêtre renvoie 409 et le message reste programmé.
    2. Relisez le message.
    3. S'il affiche toujours status: scheduled, réessayez l'annulation.
  • L'annulation ne restitue pas l'enveloppe d'e-mails programmés. L'unité consommée au moment de la programmation reste consommée, ce qui empêche une boucle programmer-puis-annuler de contourner l'enveloppe. Votre enveloppe d'envoi normale n'est pas affectée, car elle n'est débitée que lorsqu'un message part effectivement.
  • L'annulation peut être réessayée en toute sécurité avec un Idempotency-Key, comme toute autre écriture.
Pour déplacer un envoi programmé à une autre heure, annulez-le et soumettez un nouvel envoi avec le nouveau scheduled_at. Vous obtenez un nouvel ID em_.

Ce qui se passe à l'heure d'envoi

La programmation ne change que le moment où un message est libéré. Sa construction et sa gouvernance restent identiques. Les pièces jointes, la catégorie, les tags et métadonnées se comportent exactement comme lors d'un envoi immédiat et sont renvoyés de la même façon sur les événements webhook. Quatre vérifications se répartissent entre les deux moments :
  • La validation du payload et du domaine s'effectue en amont. Un envoi programmé malformé échoue lors de l'appel API avec un 422, ce qui vous informe tout de suite plutôt qu'à 9 h.
  • Le domaine de l'expéditeur est revérifié à l'heure d'envoi. Si votre domaine from n'est plus vérifié lorsque l'heure programmée arrive, le message n'est pas envoyé. Ses destinataires sont renvoyés en tant que rejected avec une raison, au lieu de recevoir un e-mail d'un domaine non vérifié. Maintenez le domaine vérifié pendant toute la fenêtre.
  • Votre enveloppe d'envoi est débitée à l'heure d'envoi. Le quota d'envoi normal est consommé lorsque le message part. La programmation laisse le quota inchangé. Si l'enveloppe est épuisée à l'heure d'envoi, les destinataires sont rejetés.
  • La suppression est évaluée à l'heure d'envoi, par rapport à votre liste de suppression telle qu'elle est à ce moment-là. Ainsi, une personne qui se désinscrit entre la programmation et l'envoi est bien prise en compte.

Erreurs

StatutCodeQuand
422E10003L'enveloppe d'e-mails programmés de votre organisation pour la période de facturation est épuisée
422scheduled_at est à moins de 30 secondes ou à plus de 30 jours
422scheduled_at a été combiné avec template
422Le payload est trop volumineux pour être mis en attente ; réduisez le corps, les destinataires ou les métadonnées, ou envoyez maintenant
409E10005Le message ne peut plus être annulé : son envoi a déjà commencé, il a été envoyé ou a été annulé
404Aucun message avec cet ID dans cet espace de travail

Webhooks

Deux événements sont propres à la programmation, en plus des événements de livraison habituels :
  • email.scheduled se déclenche lorsqu'un message est accepté avec un scheduled_at futur, et indique cette heure.
  • email.canceled se déclenche lorsqu'un message programmé est annulé avant son envoi.
Lorsque le message part, la chaîne email.accepted normale suit sans changement.

Étapes suivantes

Ressources associées

Poursuivez avec la documentation, les guides et les exemples sur ce sujet. Les ressources sont en anglais.

Obtenir un guide d'implémentation