Sign inGet Started

Wysyłanie e-maili

POST /v1/email/messages wysyła jeden e-mail. Podaj nadawcę, odbiorców i treść w payloadzie JSON. API zwraca 202 Accepted z identyfikatorem wiadomości, a następnie dostarcza e-mail asynchronicznie. Pełne schematy znajdziesz w dokumentacji API.

Minimalne wysłanie

Najmniejszy prawidłowy payload to from, co najmniej jeden odbiorca to, subject i treść (html, text lub oba). Adres from musi znajdować się w domenie zweryfikowanej w tym obszarze roboczym lub w domenie onboardingowej.
const msg = await bird.email.send({
  from: { email: "onboarding@messagebird.dev", name: "Bird" },
  to: ["delivered@messagebird.dev"],
  subject: "Hello from Bird",
  html: "<p>My first Bird email.</p>",
});
console.log(msg.id, msg.status); // "em_…", "accepted"
Użyj swojego regionalnego hosta (https://us1.platform.bird.com lub https://eu1.platform.bird.com) z pasującym kluczem bk_{region}_....
Przykład wysyłania używa delivered@messagebird.dev, adresu sandboxowego, który zawsze przyjmuje pocztę. API odrzuca domeny zastępcze z błędem 422: example.com, example.net, example.org, example.edu, test.com oraz wszystko w zarezerwowanych TLD .test, .example, .invalid i .localhost. Wysyłka na te domeny może jedynie zostać odrzucona (bounce), co kosztuje Cię reputację nadawcy.

Wysyłanie przed zweryfikowaniem domeny

Podczas onboardingu możesz wysyłać z naszej współdzielonej domeny onboardingowej onboarding@messagebird.dev. Te wysyłki pomijają sprawdzanie domeny, ale docierają tylko do zweryfikowanych członków Twojego obszaru roboczego i adresów sandboxowych, z dziennym limitem odbiorców. Quickstart zawiera dokładne zasady i limity.

Budowanie payloadu

Odbiorcy

to, cc i bcc przyjmują do 50 adresów, a to wymaga co najmniej jednego. Każdy wpis to zwykły ciąg e-mail, ciąg skrzynki pocztowej RFC 5322 (Jane <jane@acme.com>) lub obiekt z opcjonalną nazwą wyświetlaną.
Odbiorcy znajdujący się na liście suppressions obszaru roboczego nie powodują błędu żądania. Nadal zwracany jest 202, a każdy wstrzymany odbiorca pojawia się w endpointach odczytu jako status: rejected z powodem recipient_suppressed, również wtedy, gdy dotyczy to wszystkich odbiorców wysyłki.

Treść

subject jest wymagany dla wysyłek inline, do 998 znaków. Podaj html, text lub oba, każdy do 524 288 znaków. Wysyłaj oba, gdy to możliwe: klient, który nie potrafi renderować HTML, korzysta z części tekstowej.
Aby spersonalizować treść inline, umieść tokeny {{ variable }} w temacie lub treści i przekaż ich wartości w parameters, do 16 KB po serializacji. Jeden zestaw wartości obejmuje wszystkich odbiorców wysyłki, a token bez pasującego klucza renderuje się jako pusty. Dla treści wielokrotnego użytku wyślij szablon.
Dodaj parameters, nawet jako pusty obiekt ({}), aby przetworzyć temat i treść jako Liquid. Pomiń go, aby wysłać tokeny takie jak {{ animal }} dokładnie tak, jak zostały zapisane. Każda nazwa parametru to pojedyncze słowo, np. first_name; nazwy z kropkami i zarezerwowana nazwa bird są odrzucane. Nieprawidłowa składnia Liquid oraz nieobsługiwane tagi lub filtry zwracają 422.
Wartości wstawiane do HTML są escapowane, aby nie mogły zmienić otaczającego znacznika. Dla pełnego linku lub URL-a obrazu użyj {{ link }} bez url_encode. Dla wartości wewnątrz zapytania URL zakoduj tę wartość jawnie, na przykład https://example.com/search?q={{ query | url_encode }}.

Reply-to i niestandardowe nagłówki

reply_to przyjmuje od 1 do 25 adresów w tych samych formatach co odbiorcy. Każda odpowiedź odbiorcy trafia do wszystkich z nich, więc typowo podaje się jeden lub dwa.
headers to obiekt string-to-string dla Twoich własnych nagłówków, na przykład {"X-Campaign": "spring-2026"}, z limitem 25 nagłówków o wartościach do 998 znaków. Trzy rodzaje nagłówków zwracają 422:
  • Nagłówki adresowe i platformowe. Ustaw adresowanie wiadomości przez dedykowane pola (from, to, cc, bcc, reply_to, subject). Tych nazw ani nagłówków, które generujemy za Ciebie (Content-Type, Content-Transfer-Encoding, DKIM-Signature, Received, Return-Path), nie można ustawiać tutaj.
  • List-Unsubscribe i List-Unsubscribe-Post w wysyłce marketing. Ustawiamy na nich zgodny nagłówek rezygnacji jednym kliknięciem samodzielnie. W wysyłce transactional zostawiamy Twoje dokładnie tak, jak je ustawisz.
  • Dowolna wartość zawierająca znak powrotu karetki lub nowej linii.

Śledzenie

track_opens i track_clicks domyślnie mają wartość true. Ustaw dowolne na false, aby pominąć wstrzykiwanie piksela otwarcia lub przepisywanie linków w tej wysyłce. Śledzenie i metryki opisuje, co każde z nich zmienia w wiadomości.

Kategoria i pula IP

category klasyfikuje treść i ustawia politykę suppressions: marketing blokuje dostarczanie przy każdym powodzie suppression i każdej rezygnacji, a transactional dostarcza mimo suppression ze skargi lub rezygnacji tylko z marketingu (rezygnacja zarejestrowana dla wszystkich wiadomości również blokuje). Domyślnie przyjmuje kategorię szablonu w wysyłce z szablonem, a w pozostałych przypadkach marketing, więc ustaw transactional jawnie dla potwierdzeń, resetów haseł i innej poczty operacyjnej. Kategorie opisują wybór. Poczta przesłana przez SMTP pobiera kategorię z konfiguracji SMTP klucza.
ip_pool_id wybiera pulę wysyłkową: identyfikator puli (ipp_...) lub ipp_shared, aby jawnie kierować przez pulę współdzieloną. Pomiń go, aby użyć domyślnej puli organizacji. Nieznana pula lub pula bez dostępnych dedykowanych adresów IP jest odrzucana z błędem 422.

Opis pól

PoleTypWymaganeLimity i uwagi
fromaddresstakMusi być w zweryfikowanej domenie lub w domenie onboardingowej
toaddress[]takOd 1 do 50
cc, bccaddress[]nieDo 50 każde
subjectstringwysyłki inlineDo 998 znaków; pomiń w wysyłkach z szablonem
html, textstringco najmniej jednoDo 524 288 znaków każde; pomiń w wysyłkach z szablonem
reply_toaddress[]nieOd 1 do 25; odpowiedzi trafiają do każdego wymienionego adresu
headersobject (string → string)nieDo 25; zarezerwowane nazwy odrzucane (zobacz niestandardowe nagłówki)
parametersobjectnieWartości dla {{ tokens }} w treści inline; do 16 KB po serializacji; wspólne dla wszystkich odbiorców
tags{name, value}[]nieDo 20; nazwa ≤ 32 znaki, wartość ≤ 64 znaki; tylko [A-Za-z0-9_-]; nazwy unikalne w wysyłce
metadataobjectnieDowolny JSON, do 2 KB po serializacji
track_opensbooleannieDomyślnie true
track_clicksbooleannieDomyślnie true
categorystringniemarketing lub transactional; domyślnie kategoria szablonu w wysyłce z szablonem, w przeciwnym razie marketing
ip_pool_idstringnieipp_... lub ipp_shared; pomiń, aby użyć domyślnej puli organizacji
templateobjectnieWyślij opublikowany szablon po id lub slug, z parameters dla jego zmiennych i opcjonalnym language
attachmentsobject[]nieDo 20; zobacz załączniki
scheduled_atRFC 3339 timestampnieZaplanuj wysyłkę treści inline lub template; zobacz planowanie wysyłki

Wysyłanie z szablonem

Zamiast treści inline wyślij opublikowany szablon: ustaw template na obiekt wskazujący go po id (emt_...) lub po slug, dokładnie jedno z dwóch, z wartościami zmiennych w template.parameters. Pomiń subject, html i text, ponieważ szablon już je zawiera.
const msg = await bird.email.send({
  from: { email: "onboarding@messagebird.dev", name: "Bird" },
  to: ["delivered@messagebird.dev"],
  category: "transactional",
  template: {
    slug: "welcome-email",
    parameters: { first_name: "Jane" },
  },
});
console.log(msg.id, msg.status);
Treść szablonu to Liquid, więc oprócz zwykłego podstawiania {{ variable }} może korzystać z filtrów, instrukcji warunkowych {% if %} i pętli {% for %}. Personalizacja za pomocą zmiennych wymienia kilka konstrukcji, które publikacja odrzuca. template.parameters to miejsce, w którym podajesz wartości własnych parametrów szablonu, według nazwy. Pomiń jeden, a wysyłka zostanie odrzucona z błędem 422 wskazującym jego nazwę. Wszystko inne w wysyłce działa tak samo jak inline, w tym odbiorcy, tags, metadata, śledzenie i załączniki. Co jest specyficzne dla wysyłki z szablonem:
  • Inline albo szablon, nigdy oba. Wysłanie template razem z subject, html lub text jest odrzucane z błędem 422. API odrzuca również wartości zmiennych w polu parameters najwyższego poziomu; w wysyłce z szablonem należy je umieścić w template.parameters.
  • bird to jedyna zarezerwowana nazwa. Ścieżka placeholdera zaczynająca się od bird. wskazuje nasze własne dane, takie jak link rezygnacji czy rekord kontaktu odbiorcy, więc klucz template.parameters nie może nosić nazwy bird. Każdy inny klucz możesz zdefiniować sam, a każdy jest prostym pojedynczym słowem: {"order_number": "A-1043"} wypełnia {{ order_number }}.
  • Szablon można wysłać teraz lub później. Dodaj scheduled_at, aby zaplanować wysyłkę. Utrwalamy opublikowaną wersję, wybrany język i wartości parametrów w momencie przyjęcia. Jeśli usuniesz szablon przed zaplanowanym czasem wysyłki, wiadomość zostanie odrzucona z błędem generation_failure.
  • Wysyłka korzysta z opublikowanej wersji szablonu. Wersje robocze nigdy nie są wysyłane. Nieznany szablon jest odrzucany z błędem 404, a szablon bez opublikowanej wersji z błędem 422.
  • language wybiera jeden z języków szablonu. Pomiń go, aby wysłać domyślny język szablonu. Jeśli poprosisz o język, którego szablon nie posiada, jego własne ustawienie on_missing_language decyduje, czy zamiast tego zostanie wysłane najbliższe dopasowanie, czy wysyłka zostanie odrzucona. Szablon z ustawieniem language_source_required odrzuca wysyłkę, która nie wskazuje żadnego języka.
  • Kategoria szablonu jest wartością domyślną, a Twoja ją nadpisuje. Pomiń category, a wysyłka odziedziczy kategorię szablonu, więc szablon transakcyjny nie wymaga powtarzania jej przy każdym wywołaniu.
Szablony e-mail opisują tworzenie, publikowanie i konstrukcje, jakie szablon może zawierać.

Tagi a metadane

Oba dołączają Twoje własne dane do wysyłki i różnią się sposobem późniejszego odpytywania:
  • tags to strukturalne pary {name, value}: do 20 na wysyłkę, nazwa do 32 znaków, wartość do 64, tylko litery ASCII, cyfry, podkreślnik i myślnik, nazwy unikalne w ramach wysyłki. Tagi są wymiarami filtrowania, więc możesz filtrować listę wiadomości po tagu oraz dzielić analitykę i podsumowania dashboardu po tagu. Używaj ich dla etykiet o niskiej kardynalności, takich jak campaign, experiment_variant czy source.
  • metadata to dowolny obiekt JSON, do 2 KB po serializacji. Przechowujemy go, zwracamy przy odczytach API i odsyłamy w każdym zdarzeniu webhooka, więc nadaje się do kontekstu, który chcesz odzyskać: wewnętrzne ID, klucze obce, strukturalne payloady.
Każde zdarzenie webhooka zawiera oba razem z identyfikatorami korelacji (email_id, recipient_id), więc możesz uzgodnić dane ze swoimi rekordami bez dodatkowego odczytu. Nazwy tagów i klucze metadanych najwyższego poziomu zaczynające się od __bird są odrzucane. Nie musisz kodować urządzenia, geografii, dostawcy skrzynki, typu odrzucenia ani domeny odbiorcy w żadnym z tych pól, ponieważ każdy z nich rejestrujemy jako wymiar analityki.
Przykład kodu
{
  "tags": [{ "name": "campaign", "value": "onboarding" }],
  "metadata": { "user_id": "usr_12345", "order_id": "ord_98765" }
}

Załączniki

attachments przyjmuje do 20 plików na wiadomość jako bajty zakodowane w base64. Odrzucamy wysyłkę, której szacowany rozmiar wygenerowanej wiadomości przekracza 20 MB (mierzony po kodowaniu base64), więc utrzymuj surową zawartość załączników na poziomie 15 MB lub mniej, jako zapas. Załączniki zawierają kontrakt pól, obrazy inline, zablokowane typy plików i sposób pobierania załącznika.

Co oznacza 202

Udana wysyłka zwraca 202 Accepted z identyfikatorem wiadomości z prefiksem em_ i status: accepted:
Przykład kodu
{
  "id": "em_01ky7ma8y2es1s2akzk53tmjn0",
  "status": "accepted",
  "category": "marketing",
  "from": { "email": "hello@yourdomain.com" },
  "to": [{ "email": "delivered@messagebird.dev" }],
  "subject": "Hello from Bird",
  "accepted_count": 1,
  "processed_count": 0,
  "delivered_count": 0,
  "deferred_count": 0,
  "bounced_count": 0,
  "complained_count": 0,
  "rejected_count": 0,
  "open_count": 0,
  "click_count": 0,
  "track_opens": true,
  "track_clicks": true,
  "created_at": "2026-07-23T13:58:20.866Z"
}
202 oznacza, że trwale przyjęliśmy wysyłkę. Błędy, które możesz naprawić, wracają w samym żądaniu jako 422: niezweryfikowana domena nadawcy lub pole, które nie przechodzi walidacji. Wyniki per odbiorca (dostarczono, odrzucono, odroczono, zgłoszono skargę) docierają potem przez webhooki i endpointy odczytu wiadomości.
Wynikają z tego dwie rzeczy:
  • Odczyty zwracają stan bez treści. GET /v1/email/messages/{message_id} zwraca stan wiadomości i odbiorcy, nigdy treść html ani text. Gdy przechowywanie treści jest włączone dla obszaru roboczego, zapisane treści pozostają dostępne przez 30 dni z GET /v1/email/messages/{message_id}/content.
  • Odczyt może chwilowo nie nadążać za wysyłką. 404 na endpointach odczytu tuż po 202 oznacza, że wiadomość nie jest jeszcze widoczna, więc spróbuj ponownie za chwilę.

Bezpieczne ponawianie

Wyślij nagłówek Idempotency-Key z unikalną wartością dla każdej logicznej wysyłki. Jeśli żądanie się powiodło, ale nie otrzymałeś odpowiedzi, wyślij je ponownie z tym samym kluczem. API zwraca oryginalny wynik zamiast wysyłać drugi e-mail i dołącza nagłówek Idempotency-Replay. Idempotentność opisuje format klucza i czas przechowywania.

Wysyłanie wsadowe

Aby zmniejszyć liczbę żądań API, POST /v1/email/batches przyjmuje do 100 niezależnych wiadomości i waliduje je jako jedną całość. Wywoływanie endpointu pojedynczej wysyłki w pętli również jest obsługiwane. Element wsadu używa payloadu opisanego na tej stronie, włącznie z scheduled_at, więc jeden wsad może łączyć wiadomości natychmiastowe i zaplanowane.

Rozliczenia

Wysyłki e-mail są mierzone per odbiorca względem miesięcznego limitu Twojego planu, więc wiadomość do trzech odbiorców zużywa trzy wysyłki. Rozliczenia i zużycie opisują model mierzenia i odczyt bieżącego zużycia.

Następne kroki

Powiązane zasoby

Kontynuuj z dokumentacją, przewodnikami i przykładami dotyczącymi tego tematu. Zasoby są w języku angielskim.

Wypróbuj ćwiczenie i uzyskaj brief wdrożeniowy