Wysyłanie SMS
Ten przewodnik opisuje endpoint pojedynczej wysyłki, POST /v1/sms/messages. Zbuduj ładunek JSON z odbiorcą, nadawcą, treścią i kategorią. Bird zwraca 202 Accepted z identyfikatorem wiadomości i dostarcza ją asynchronicznie. Każde żądanie wysyła jedną wiadomość do jednego odbiorcy. Aby wysłać wiele wiadomości naraz, użyj wysyłki wsadowej. Aby wysłać szablon zamiast własnego tekstu, podaj obiekt template zamiast text i category. Szablony wbudowane odrzucają from; szablony obszaru roboczego go wymagają.
Przed wysyłką: włącz kraj docelowy
Twój obszar roboczy wysyła SMS tylko do krajów z jego listy dozwolonych krajów docelowych. Krajem macierzystym organizacji jest kraj adresu rejestrowego z jej profilu firmy, a jeśli adres rejestrowy nie ma kraju, kraj adresu rozliczeniowego. Nowy obszar roboczy ma pustą listę dozwolonych krajów. Za każdym razem, gdy kraj macierzysty zostanie ustawiony lub zmieniony, Bird dodaje go do tej listy. Bird odrzuca wysyłkę do kraju spoza listy z błędem 422 SMSDestinationNotEnabled, zanim wybierze nadawcę. Włącz kraje, które obsługujesz, w panelu w sekcji SMS > Destinations.
Na tej samej stronie możesz ustawić dzienny limit wydatków dla każdego kraju w walucie swojego portfela. Ustawienie limitu wymaga portfela organizacji i uprawnień do jego odczytu; usunięcie limitu ich nie wymaga. Limit obowiązuje niezależnie od tego, czy kraj jest włączony. Gdy dzisiejsze wydatki na ten kraj osiągną limit, Bird odrzuca nowe wiadomości do niego z błędem 422 SMSDestinationDailySpendExceeded aż do północy UTC. Odrzucane są również wiadomości weryfikacyjne. Wydatek jest liczony w chwili obciążenia za wiadomość, więc wiadomości już przyjęte mogą przekroczyć limit o swój koszt. Zmiana limitu zaczyna obowiązywać przy wysyłce w ciągu maksymalnie minuty.
Minimalna wysyłka
Najmniejszy poprawny ładunek z własnym tekstem zawiera odbiorcę to, nadawcę from, treść text i kategorię category.
const msg = await bird.sms.send({
from: "+15557654321",
to: "+14155550100",
text: "Your verification code is 123456.",
category: "authentication",
});
console.log(msg.id, msg.status);msg = client.sms.send(
from_="+15557654321",
to="+15551234567",
text="Your verification code is 123456.",
category="authentication",
)
print(msg.id, msg.status)msg, err := client.Sms.Send(context.Background(), bird.SmsSendParams{
From: "+15557654321",
To: "+15551234567",
Text: "Your verification code is 123456.",
Category: bird.SMSCategoryAuthentication,
})
if err != nil {
log.Fatal(err)
}
fmt.Println(msg.Id, *msg.Status)$message = $bird->sms->send(
from: '+15557654321',
to: '+15551234567',
text: 'Your verification code is 123456.',
category: 'authentication',
);
echo $message->getId(), ' ', $message->getStatus();bird sms send --body-file - <<'JSON'
{
"to": "+14155550100",
"from": "+15557654321",
"text": "Your verification code is 123456.",
"category": "authentication",
"options": {
"smart_encoding": true
},
"tags": [
{
"name": "campaign",
"value": "signup"
}
],
"metadata": {
"user_id": "usr_12345"
}
}
JSONcurl -X POST https://eu1.platform.bird.com/v1/sms/messages \
-H "Authorization: Bearer bk_eu1_..." \
-H "Content-Type: application/json" \
-d '{
"to": "+31612345678",
"from": "Bird",
"text": "Your Bird verification code is 481920. It expires in 10 minutes.",
"category": "authentication"
}'Użyj hosta swojego regionu (https://us1.platform.bird.com lub https://eu1.platform.bird.com) z pasującym kluczem bk_{region}_.... Odpowiedź zawiera przyjętą wiadomość:
{
"id": "sms_01ky7qmwgpfkybj9ecrnwjx714",
"direction": "outbound",
"status": "accepted",
"to": "+31612345678",
"from": "Bird",
"text": "Your Bird verification code is 481920. It expires in 10 minutes.",
"category": "authentication",
"segments": { "count": 1, "encoding": "GSM_7BIT", "characters": 64 },
"cost": null,
"carrier": null,
"mcc_mnc": null,
"sent_at": null,
"delivered_at": null,
"created_at": "2026-07-23T14:56:34.326Z"
}status: accepted oznacza, że Bird ma wiadomość i ją przetwarza; cost ma wartość null, ponieważ wycena odbywa się podczas przetwarzania. Dalsze kroki opisuje sekcja model asynchroniczny.
Budowanie ładunku
Odbiorca
to to jeden odbiorca w formacie E.164: początkowy znak +, kod kraju i numer abonenta, na przykład +31612345678. Jedna wiadomość trafia do jednego odbiorcy, bez cc, bcc ani tablicy odbiorców. Aby dotrzeć do wielu osób, wyślij partię.
Nadawca
from to nadawca widoczny dla odbiorcy. Jest wymagany przy wysyłce wolnego tekstu, chyba że messaging_profile_id wskazuje profil wiadomości z nadawcą dla kraju docelowego lub nadawcą domyślnym. Przyjmuje jedną z dwóch postaci, a to, które z nich działają, zależy od kraju docelowego:
- Alfanumeryczny identyfikator nadawcy: od 3 do 11 liter, cyfr, spacji, myślników, podkreśleń lub kropek, z co najmniej jedną literą i bez separatora na początku ani na końcu, na przykład
BirdlubAcme-Co. Musi zawierać literę, więc ciąg cyfr ze znakami interpunkcyjnymi, taki jak555 555, zostanie odrzucony. Niektóre kraje wymagają rejestracji, a inne, w tym USA, nie obsługują nadawców alfanumerycznych. Odbiorcy nie mogą na nie odpowiadać. - Numer należący do Twojego obszaru roboczego, w formacie E.164 lub jako same cyfry. Każda wartość
fromzłożona wyłącznie z cyfr jest traktowana jako numeryczna i wyszukiwana wśród Twoich nadawców, więc dowolny numer, który nie należy do Ciebie, zostanie odrzucony. To, czy działa jako long code, numer bezpłatny czy short code, wynika z samego numeru, a nie z liczby wpisanych cyfr. Sześciocyfrowa wartośćfromnie jest short code dlatego, że ma 6 cyfr; jest nim, jeśli posiadany przez Ciebie numer jest short code.
Nadawca, który nie jest prawidłowy dla miejsca docelowego, zostaje odrzucony z kodem 422 podającym przyczynę (na przykład SMSAlphaNotSupported tam, gdzie nadawcy alfanumeryczni nie są dostępni). Przy wysyłce wbudowanego szablonu pole from nie jest akceptowane: Bird wybiera nadawcę dla miejsca docelowego i kategorii. Szablon obszaru roboczego wymaga własnego nadawcy from lub profilu wiadomości, który go dostarcza.
Rezerwowanie identyfikatora nadawcy, wymagania poszczególnych krajów wobec niego i jego rejestrację w każdym kraju opisano w sekcji Identyfikatory nadawców SMS.
Aby przechowywać nadawców i ustawienia domyślne jednego programu w jednym miejscu, utwórz profil wiadomości i wskaż go w messaging_profile_id. Gdy pominiesz from, Bird wysyła wiadomość od nadawcy profilu dla kraju docelowego lub od jego nadawcy domyślnego. Pominięte pole category przyjmuje domyślną kategorię profilu, a options.smart_encoding, cost_center, validity_period i options.callback_url przyjmują ustawienia profilu. Wartości ustawione w wiadomości mają pierwszeństwo.
Treść i kategoria
text to treść wiadomości, zawierająca co najmniej jeden znak. Jest rozliczana i dostarczana w segmentach; wysyłka jest ograniczona do 12 segmentów (około 1836 znaków GSM-7 lub 804, jeśli treść używa rozszerzonego kodowania UCS-2). Treść przekraczająca limit zostaje odrzucona z kodem 422, a nie obcięta.
category jest wymagane przy wysyłce wolnego tekstu, chyba że profil wiadomości wskazany w messaging_profile_id ustawia kategorię domyślną. Klasyfikuje wiadomość jako transactional, marketing, authentication lub service, co informuje Bird i operatorów, w jakim celu wysyłasz wiadomość. Jednorazowy kod weryfikacyjny używa authentication, a promocja używa marketing. Wybierz kategorię zgodną z celem wiadomości.
Tagi i metadane
Te pola dołączają do wysyłki Twoje własne dane, ale służą do różnych celów:
tagsto ustrukturyzowane pary{name, value}(maks. 20 na wysyłkę; nazwa od 1 do 32 znaków, wartość od 1 do 64, wyłącznie ASCII[A-Za-z0-9_-], z rozróżnianiem wielkości liter, nazwy unikalne w obrębie wysyłki). Są pełnoprawnymi wymiarami filtrowania: filtruj listę wiadomości według tagu. Używaj ich do etykiet o niewielkiej liczbie wartości, takich jakcampaignlubexperiment_variant.metadatato dowolny obiekt JSON (maks. 2 KB po serializacji). Jest przechowywany, zwracany przy odczytach API i dołączany do każdego zdarzenia webhooka, ale nie jest wymiarem filtrowania. Używaj go do kontekstu, który ma do Ciebie wrócić: wewnętrznych identyfikatorów, kluczy obcych i wszystkiego, co chcesz otrzymywać z każdym zdarzeniem.referenceto jeden ciąg od 1 do 255 znaków, po którym chcesz wyszukiwać wiadomość, na przykład numer zamówienia lub zgłoszenia.?reference=na liście wiadomości dopasowuje go dokładnie, z rozróżnianiem wielkości liter, a kilka wiadomości może mieć tę samą wartość. Jest zwracany przy odczytach i dołączany do każdego zdarzenia webhooka. Ustawiaj go tylko wtedy, gdy musisz po nim wyszukiwać, a wszelkie inne dane umieszczaj wmetadata.
{
"tags": [{ "name": "campaign", "value": "spring-2026" }],
"metadata": { "user_id": "usr_12345", "order_id": "ord_98765" },
"reference": "ord_98765"
}Opis pól
| Pole | Typ | Wymagane | Limity / uwagi |
|---|---|---|---|
to | ciąg znaków (E.164) | tak | Jeden odbiorca na wiadomość |
from | string | tak* | Posiadany numer E.164, alfanumeryczny identyfikator nadawcy (3–11 znaków, co najmniej jedna litera) lub krótki kod (5–6 cyfr) |
text | string | tak* | Co najmniej 1 znak; limit 12 segmentów |
category | string | tak* | transactional, marketing, authentication lub service |
template | obiekt | tak* | {slug, parameters?, language?} dla szablonu wbudowanego lub szablonu obszaru roboczego |
tags | {name, value}[] | nie | Maks. 20; nazwa 1–32 znaki, wartość 1–64 znaki; tylko [A-Za-z0-9_-] |
metadata | obiekt | nie | Dowolny JSON, maks. 2 KB po serializacji |
reference | string | nie | 1–255 znaków; dokładne dopasowanie dla ?reference= na liście wiadomości |
messaging_profile_id | string | nie | Profil wiadomości, który dostarcza nadawcę i wartości domyślne; wartości ustawione w wiadomości mają pierwszeństwo |
validity_period | integer | nie | 60–172 800 sekund od przyjęcia; pomiń, aby użyć wartości z profilu wiadomości lub reguł operatora |
options | obiekt | nie | Ustawienia przetwarzania dla pojedynczej wiadomości, takie jak smart_encoding (zobacz segmenty i kodowanie) oraz callback_url (zobacz adresy URL wywołań zwrotnych) |
* Wysyłki z własnym tekstem wymagają pól from, text i category, przy czym from i category może dostarczyć profil wiadomości. Wysyłki z szablonem wymagają template zamiast text i category (i odrzucają oba te pola). Szablony wbudowane odrzucają from, a szablony obszaru roboczego go wymagają.
Wysyłanie z szablonem
Ustaw template, aby wysłać szablon wbudowany lub opublikowany szablon obszaru roboczego. Tworzenie szablonów obszaru roboczego jest dostępne w wersji zapoznawczej API. Katalog, zmienne i reguły nadawców opisuje strona Szablony SMS.
Segmenty i kodowanie
SMS jest rozliczany za segment. Wiadomość mieszcząca się w kodowaniu GSM-7 ma 160 znaków w pojedynczym segmencie, a UCS-2 (włączane przez emoji, znaki CJK lub inne znaki spoza GSM) zmniejsza ten limit do 70. Dłuższe wiadomości są dzielone na segmenty wieloczęściowe o nieco niższych limitach na segment. Każda odpowiedź podaje ustalone segments: rozliczane count, encoding i liczbę znaków. Segmenty są jednostką rozliczenia; zobacz koszt.
Gdy jedynym powodem, dla którego treść wykracza poza GSM-7, są znaki typograficzne, inteligentne kodowanie może zmniejszyć liczbę segmentów. Ustaw options.smart_encoding na true, a Bird przed wysłaniem zastąpi cudzysłowy drukarskie, myślniki, wielokropki i podobne znaki ich odpowiednikami w GSM-7. Ta opcja jest domyślnie wyłączona, ponieważ zmienia treść, którą napisałeś.
Pełny zestaw znaków, znaki z tabeli rozszerzeń zajmujące dwa miejsca, rozmiar emoji, znaki zastępowane przez smart encoding oraz sposób liczenia segmentów opisuje strona Character limits.
Wysyłka wsadowa
POST /v1/sms/batches wysyła do 100 niezależnych wiadomości w jednym żądaniu. To masowy wzorzec SMS: jedno wywołanie API dla wielu odbiorców. Żądania wsadowe podlegają zasadom ograniczania liczby żądań sms_batch, oddzielnym od zasad sms_send dla pojedynczych wysyłek. Treść żądania to obiekt JSON, którego tablica messages zawiera obiekty wiadomości z sekcji Budowanie ładunku:
const result = await bird.sms.sendBatch({
messages: [
{
from: "+15557654321",
to: "+15551111111",
text: "Hi Alice!",
category: "marketing",
},
{
from: "+15557654321",
to: "+15552222222",
text: "Hi Bob!",
category: "marketing",
},
],
});batch = client.sms.send_batch(
messages=[
{
"from_": "+15557654321",
"to": "+15551111111",
"text": "Hi Alice!",
"category": "marketing",
},
{
"from_": "+15557654321",
"to": "+15552222222",
"text": "Hi Bob!",
"category": "marketing",
},
]
)
for msg in batch.data:
print(msg.id, msg.status)batch, err := client.Sms.SendBatch(context.Background(), bird.SmsSendBatchParams{
Messages: []bird.SmsSendParams{
{
From: "+15557654321", To: "+15551111111",
Text: "Hi Alice!", Category: bird.SMSCategoryMarketing,
},
{
From: "+15557654321", To: "+15552222222",
Text: "Hi Bob!", Category: bird.SMSCategoryMarketing,
},
},
})
if err != nil {
log.Fatal(err)
}
for _, msg := range batch.Data {
fmt.Println(msg.Id, *msg.Status)
}$batch = $bird->sms->sendBatch(messages: [
(new SMSMessageSendRequest())
->setFrom('+15557654321')
->setTo('+15551111111')
->setText('Hi Alice!')
->setCategory('marketing'),
(new SMSMessageSendRequest())
->setFrom('+15557654321')
->setTo('+15552222222')
->setText('Hi Bob!')
->setCategory('marketing'),
]);
foreach ($batch->getData() ?? [] as $item) {
echo $item->getId(), ' ', $item->getStatus(), "\n";
}curl -X POST "https://{region}.platform.bird.com/v1/sms/batches" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"messages": [
{
"to": "+15551111111",
"from": "+15557654321",
"text": "Hi Alice!",
"category": "marketing"
},
{
"to": "+15552222222",
"from": "+15557654321",
"text": "Hi Bob!",
"category": "marketing"
}
]
}'Walidacja działa na zasadzie wszystko albo nic: jeśli którakolwiek wiadomość w partii jest nieprawidłowa, całe żądanie zostaje odrzucone z 422 i nic nie zostaje wysłane, więc partia nigdy nie jest stosowana częściowo. Po powodzeniu odpowiedź 202 zawiera każdą przyjętą wiadomość w kolejności przesłania w data oraz summary z accepted_count. Od tego momentu każda wiadomość jest niezależna: błąd u jednego odbiorcy nigdy nie wpływa na pozostałe.
Model asynchroniczny: co oznacza 202
Udana wysyłka zwraca 202 Accepted z identyfikatorem wiadomości i status: accepted. Błędy żądania są zwracane natychmiast: nieprawidłowe pole, treść przekraczająca limit segmentów, kraj docelowy, którego nie włączono, lub nieprawidłowy nadawca zwracają 422. Obszar roboczy bez środków w portfelu otrzymuje 402.
Doręczenie odbywa się asynchronicznie. Wiadomość przechodzi do stanu sent, gdy Bird przekaże ją operatorowi. Następnie potwierdzenie doręczenia ustawia delivered, undelivered, failed lub expired, co widać w zdarzeniach i webhookach oraz w endpointach odczytu. Ma to trzy konsekwencje:
- Koszt jest wyceniany po przyjęciu. Pole
costwiadomości ma w chwili przyjęcia wartośćnulli zostaje wypełnione, gdy Bird wyceni wysyłkę podczas przetwarzania. Aby zobaczyć dotychczas wyceniony koszt, odczytaj wiadomość ponownie lub poczekaj na zdarzenie doręczenia. Składniki kosztu i przypadki, w których któryś pozostaje niewyceniony, opisuje sekcja koszt i rozliczenia. - Wiadomość może zostać odrzucona po 202. Jeśli obciążenie nie powiedzie się podczas przetwarzania, wiadomość kończy w stanie
rejectedz webhookiemsms.rejectedi nie płacisz za nią. Wyczerpany portfel pojawia się jakolast_error.code: insufficient_balance. - Odczyty mogą chwilowo nie nadążać za 202. Wiadomość staje się widoczna w endpointach odczytu krótko po
202, więc404zaraz po wysyłce rozwiązuje się samoczynnie w ciągu kilku chwil.
Pola zarezerwowane
Bird odrzuca następujące pola żądania z 422 SMSUnsupportedFeature:
scheduled_at, media_urls, broadcast_id, campaign_id, audience_id, contact_id, topic_id, personalization, options.max_price_per_segment, options.track_clicks (gdy true)
Nie umieszczaj tych pól w wysyłce.
Bezpieczne ponowne próby
Wysyłaj nagłówek Idempotency-Key z unikalną wartością dla każdej logicznej wysyłki. Jeśli żądanie się powiedzie, ale nie zwróci odpowiedzi, powtórz to samo żądanie z tym samym kluczem. Bird zwraca pierwotny wynik zamiast wysyłać zduplikowaną wiadomość. Format klucza i czas jego przechowywania opisuje strona idempotentność.
Koszty i rozliczenia
Wychodzące SMS są rozliczane za segment. Kwota zależy od kraju docelowego i operatora. Niektóre trasy doliczają opłatę dodatkową podmiotu zewnętrznego, na przykład opłaty operatorów w USA za 10DLC.
Pole cost wiadomości dzieli opłatę na nazwane składniki. transaction_amount to kwota, którą Bird pobrał za przesłanie wiadomości, passthrough_amount to przeniesiona opłata podmiotu zewnętrznego, a amount to suma wycenionych składników wyrażona w currency_code. Składnik, który nie został wyceniony, ma wartość null, a nie "0.00000". Dlatego wiadomość, której opłata dodatkowa nigdy nie została ustalona, podaje w amount wyłącznie opłatę za przesłanie. Każde pole opisuje dokumentacja wiadomości.
Opłata dodatkowa jest ustalana w miarę możliwości. Bird ustala ją podczas zapisywania potwierdzenia doręczenia, w ograniczonym oknie czasowym. Jeśli nie zostanie ustalona w tym oknie, passthrough_amount pozostaje na stałe null: Bird nie ponawia próby, a amount pozostaje równe opłacie za przesłanie.
Przychodzące SMS są rozliczane w dwóch pozycjach: według stawki za segment przychodzący oraz opłaty dodatkowej operatora za wiadomości przychodzące, jeśli ma zastosowanie. Obie pozycje widnieją w polu cost odebranej wiadomości: stawka jako transaction_amount, a opłata dodatkowa jako passthrough_amount. W odróżnieniu od odpowiednika dla wiadomości wychodzących opłata dodatkowa za wiadomości przychodzące jest wyceniana w chwili przyjęcia wiadomości, a nie przy doręczeniu, więc nigdy nie jest uzupełniana później.
Koszty i segmenty poszczególnych wiadomości sprawdzisz w logu SMS.
Dalsze kroki
- Szablony SMS: wyślij wbudowany szablon i pozwól, aby Bird wybrał nadawcę.
- Dziennik SMS: znajdź wiadomość i sprawdź jej cykl życia, segmenty oraz koszt.
- Zdarzenia: odbieraj zdarzenia dostarczenia w swoich systemach.
- Adresy URL wywołań zwrotnych SMS: wysyłaj zdarzenia jednej wiadomości lub jednego profilu do osobnego punktu końcowego HTTPS.
- Metryki SMS: monitoruj wskaźnik dostarczeń, wskaźnik niepowodzeń i liczbę zaakceptowanych wiadomości.
- Idempotentność: bezpiecznie ponawiaj żądania z nagłówkiem
Idempotency-Key. - Wysyłanie pierwszego SMS: film, który pokazuje tę samą konfigurację w panelu
Powiązane zasoby
Przejdź do dokumentacji, przewodników i przykładów dotyczących tego tematu.