Sign inGet Started

Wysyłanie zaplanowane

Ustaw scheduled_at, aby wstrzymać wiadomość do określonego czasu. Gdy ten czas nadejdzie, wiadomość wchodzi w normalny cykl dostarczania i generuje te same zdarzenia co wysyłka natychmiastowa. Twoja aplikacja nie musi uruchamiać własnego harmonogramu.

Planowanie wysyłki

Dodaj znacznik czasu scheduled_at do zwykłej wysyłki POST /v1/email/messages. Nic innego w payloadzie się nie zmienia.

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><p><a href="{{ bird.unsubscribe_url }}">Unsubscribe</a></p>',
  category: "marketing",
  scheduled_at: "2027-01-15T09:00:00Z",
});
console.log(msg.id, msg.status); // "em_…", "accepted"

Wywołanie natychmiast zwraca 202 Accepted z ID wiadomości z prefiksem em_ oraz status: accepted. Jest to ten sam obiekt wiadomości, który zwraca wysyłka natychmiastowa, plus scheduled_at zwrócony w UTC, dzięki czemu możesz potwierdzić czas wysyłki bez dodatkowego odczytu. Przyjęcie jest synchroniczne, dostarczenie jest odroczone. Pomiń scheduled_at w żądaniu, a wiadomość zostanie wysłana od razu; odpowiedź nie będzie zawierać klucza scheduled_at.

Wyniki odczytu są aktualizowane asynchronicznie. Dopiero zaplanowana wiadomość może początkowo zwracać 404 w operacji Pobierz wiadomość i nie być widoczna na liście wiadomości ani w panelu. Obszerna treść lub załączniki mogą wydłużyć oczekiwanie, gdy je zapisujemy. Zachowaj ID i scheduled_at z odpowiedzi 202, a następnie ponawiaj odczyty z tym ID, robiąc przerwy między próbami. Za pomocą tego ID możesz też anulować wysyłkę, zanim wiadomość się pojawi.

Gdy wiadomość pojawi się, nadal oczekując na wysłanie, odczyty pokażą status: scheduled oraz jej scheduled_at:

Przykład kodu
{
  "id": "em_01ky7q24hafjgvzfg02v3m177p",
  "status": "scheduled",
  "scheduled_at": "2027-01-15T09:00:00Z",
  "category": "marketing"
}

Gdy czas nadchodzi, wiadomość zostaje zwolniona, a jej status przechodzi przez zwykłe stany (accepted, potem processed, potem delivered itd.). scheduled_at pozostaje ustawiony po wysłaniu, więc zawsze możesz sprawdzić, na kiedy wiadomość była zaplanowana.

Wysyłanie wiadomości może rozpocząć się przed aktualizacją wyników odczytu, więc najpierw możesz zobaczyć późniejszy status. Nie ma stałego czasu oczekiwania, po którym odczyt na pewno pokaże wiadomość.

Zaplanowanie wysyłki zużywa jedną jednostkę limitu zaplanowanych e-maili Twojej organizacji w danym okresie rozliczeniowym. Przekroczenie tego limitu jest odrzucane z błędem 422 (E10003).

Zaplanuj wysyłkę treści podanej bezpośrednio lub szablonu

Użyj scheduled_at z treścią podaną bezpośrednio lub zapisanym szablonem, zbudowanym tak samo jak natychmiastowa wysyłka z szablonem. Ustalamy opublikowaną wersję, wybrany język oraz wartości parametrów w chwili przyjęcia żądania i wysyłamy tę wersję o zaplanowanej godzinie. Opublikowanie nowszej wersji nie zmienia wyboru. Usunięcie szablonu przed zaplanowaną godziną powoduje odrzucenie wiadomości bez jej wysłania.

Wiadomość z kategorii marketing otrzymuje link rezygnacji z subskrypcji w postaci małej stopki na końcu treści. Aby samodzielnie umieścić link, wstaw {{ bird.unsubscribe_url }} w każdej dostarczonej części wiadomości, a przy wysyłce z szablonem w treści szablonu.

Element batch przyjmuje scheduled_at na tych samych zasadach, więc jeden batch może łączyć wiadomości zaplanowane i natychmiastowe. Każdy zaplanowany element zużywa własną jednostkę limitu, a cały batch jest odrzucany, jeśli czas dowolnego elementu jest poza zakresem. Każdy zaplanowany element zwraca własny scheduled_at w odpowiedzi batcha, a element wysyłany natychmiast nie ma klucza scheduled_at; dokumentacja batch pokazuje oba przypadki w jednej odpowiedzi.

Payload wysyłki natychmiastowej może być zbyt duży do zaplanowania. Jeśli jego treść, lista odbiorców lub metadane przekraczają limit planowania, API zwraca 422. Zmniejsz te pola lub wyślij wiadomość natychmiast.

Wybór czasu wysyłki

scheduled_at to absolutny znacznik czasu RFC 3339. Obowiązują dwie reguły:

  • Musi przypadać między 30 sekund a 30 dni w przyszłości. Bliżej niż 30 sekund lub dalej niż 30 dni oznacza odrzucenie z błędem 422. Dolna granica zapobiega wyścigowi z wysyłką natychmiastową. Trzydzieści dni to najdalszy horyzont, przez który przechowujemy wiadomość.
  • Podaj dokładny moment. Dołącz sufiks UTC Z (2027-01-15T09:00:00Z) lub jawne przesunięcie (2026-07-30T09:00:00-04:00, ten sam moment co 13:00:00Z). Porównujemy podany moment z bieżącym czasem i nigdy nie interpretujemy samego czasu lokalnego ani nie stosujemy strefy czasowej odbiorcy. Aby wysłać o 9:00 w czasie lokalnym każdego odbiorcy, oblicz te momenty samodzielnie i zaplanuj osobną wysyłkę dla każdej strefy.

Wyrażenia względne, takie jak "in 2 hours", nie są akceptowane. Wyślij rozwiązany znacznik czasu.

Wyświetlanie zaplanowanych wiadomości

Filtruj listę wiadomości według statusu, aby zobaczyć wiadomości już widoczne i nadal oczekujące na wysłanie. Nowo przyjęta zaplanowana wysyłka może nie być widoczna podczas przesyłania treści lub aktualizacji wyników odczytu:

for await (const message of bird.email.list({ status: "scheduled" })) {
  console.log(message.id, message.scheduled_at);
}

status=canceled wyświetla te, które anulowałeś przed wysłaniem. Gdy zaplanowana wiadomość zostanie wysłana, przechodzi do pipeline i pojawia się ze statusami dostarczenia, tak samo jak każda inna wysyłka. Log e-maili w dashboardzie oferuje te same filtry Scheduled i Canceled.

Anulowanie zaplanowanej wysyłki

Anuluj wiadomość w dowolnym momencie przed rozpoczęciem wysyłki za pomocą POST /v1/email/messages/{message_id}/cancel:

await bird.email.cancel("em_abc123");

Pomyślne anulowanie zwraca 204 No Content. Status wiadomości zmienia się na canceled, wiadomość nigdy nie zostaje wysłana i uruchamiany jest webhook email.canceled. Cztery rzeczy, o których warto wiedzieć:

  • Anulować można tylko wiadomość wciąż zaplanowaną. Wiadomość, której wysyłka już się rozpoczęła, która została już wysłana lub już anulowana, zwraca 409:

    Przykład kodu
    {
      "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."
      }
    }

    W momencie nadejścia czasu wysyłki anulowanie może też przegrać wyścig z samą wysyłką i zwrócić 409 z tego samego powodu.

  • Możesz anulować wysyłkę, gdy treść jest jeszcze przesyłana. Zaplanowana wysyłka z załącznikami lub dużą treścią wiadomości może nadal zapisywać zawartość po odpowiedzi 202. Po udanym anulowaniu wysyłka pozostaje anulowana, nawet jeśli przesyłanie zakończy się później.

  • Anulowanie nie zwraca jednostki limitu zaplanowanych e-maili. Jednostka zużyta w momencie planowania pozostaje zużyta, co uniemożliwia obchodzenie limitu przez pętlę planuj-anuluj. Twój zwykły limit wysyłek pozostaje nienaruszony, ponieważ jest naliczany dopiero wtedy, gdy wiadomość faktycznie zostaje wysłana.

  • Anulowanie można bezpiecznie ponawiać z użyciem Idempotency-Key, tak jak każdą inną operację zapisu.

Aby przenieść zaplanowaną wysyłkę na inny czas, anuluj ją i wyślij nowe żądanie z nowym scheduled_at. Otrzymasz nowy identyfikator em_.

Co dzieje się w momencie wysyłki

Planowanie zmienia tylko moment zwolnienia wiadomości. Jej budowa i reguły pozostają takie same. Załączniki, kategoria, tagi i metadane działają dokładnie tak samo jak przy wysyłce natychmiastowej i są zwracane w zdarzeniach webhooka w ten sam sposób. Pięć kontroli rozłożone na dwa momenty:

  • Walidacja payloadu i domeny odbywa się od razu. Nieprawidłowa zaplanowana wysyłka kończy się błędem na wywołaniu API z odpowiedzią 422, więc dowiadujesz się teraz, a nie o 9:00.
  • Domena nadawcy jest ponownie sprawdzana w momencie wysyłki. Jeśli Twoja domena from nie jest już zweryfikowana w zaplanowanym momencie, wiadomość nie zostaje wysłana. Odbiorcy są zwracani jako rejected z podaniem przyczyny, zamiast otrzymać wiadomość z niezweryfikowanej domeny. Utrzymuj domenę zweryfikowaną przez cały okres oczekiwania.
  • Twój limit wysyłek jest naliczany w momencie wysyłki. Zwykły limit wysyłek jest zużywany w chwili wysłania wiadomości. Zaplanowanie nie zmienia limitu. Jeśli limit jest wyczerpany w momencie wysyłki, odbiorcy są odrzucani.
  • Supresja jest oceniana w momencie wysyłki, względem Twojej listy supresji w jej aktualnym stanie, więc osoba, która wypisze się między zaplanowaniem a wysyłką, jest uwzględniana.
  • Zapisany szablon musi nadal istnieć w momencie wysyłki. Jeśli usuniesz szablon po zaplanowaniu, wiadomość nie zostanie wysłana. Odbiorcy są zwracani jako rejected z generation_failure.

Błędy

StatusKodKiedy
422E10003Limit zaplanowanych e-maili Twojej organizacji na dany okres rozliczeniowy został wyczerpany
422scheduled_at jest bliżej niż 30 sekund lub dalej niż 30 dni
422Payload jest zbyt duży do zaplanowania; zmniejsz treść, odbiorców lub metadane albo wyślij teraz
409E10005Wiadomości nie można już anulować: wysyłka już się rozpoczęła, została wysłana lub anulowana
404Odczyt wiadomości nie odzwierciedla jeszcze jej przyjęcia albo w tym obszarze roboczym nie istnieje wiadomość o tym ID

Webhooki

Dwa zdarzenia są specyficzne dla planowania, oprócz zwykłych zdarzeń dostarczenia:

  • email.scheduled informuje o wiadomości oczekującej na przyszły termin scheduled_at. W przypadku wysyłki z szablonu wybrana wersja jest ponownie ładowana, a jej treść przygotowywana w momencie wysyłki. To zdarzenie może dotrzeć, zanim te czynności się zakończą.
  • email.canceled jest wysyłany, gdy zaplanowana wiadomość zostaje anulowana przed wysłaniem.

Gdy wiadomość zostanie wysłana, normalny łańcuch email.accepted następuje bez zmian.

Zdarzenia dotyczące planowania są publikowane asynchronicznie. Status wiadomości może zmienić się z zaplanowanego przed opublikowaniem email.scheduled. Otrzymanie webhooka nie oznacza, że endpointy odczytu pokazują już ten stan.

Następne kroki

Przejdź do dokumentacji, przewodników i przykładów dotyczących tego tematu.