Wysyłanie SMS
Ten przewodnik opisuje endpoint pojedynczej wysyłki POST /v1/sms/messages. Zbuduj payload JSON z odbiorcą, nadawcą, treścią i kategorią. Bird zwraca 202 Accepted z identyfikatorem wiadomości i doręcza asynchronicznie. Każde żądanie wysyła jedną wiadomość do jednego odbiorcy. Aby wysłać wiele wiadomości naraz, użyj wysyłki zbiorczej. Aby wysłać szablon zamiast własnego tekstu, przekaż obiekt template w miejsce text, category i from.
Przed wysyłką: włącz kraj docelowy
Twój obszar roboczy ma listę dozwolonych krajów docelowych opartą na domyślnej odmowie, w której początkowo włączony jest tylko kraj macierzysty Twojej organizacji. Bird odrzuca wysyłkę do każdego innego kraju z 422 SMSDestinationNotEnabled, zanim jeszcze rozwiąże nadawcę. Włącz kraje, do których wysyłasz, w sekcji SMS > Destinations w panelu.
Minimalna wysyłka
Najmniejszy poprawny payload z własnym tekstem to odbiorca to, nadawca from, treść text i 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 swojego regionalnego hosta (https://us1.platform.bird.com lub https://eu1.platform.bird.com) z pasującym kluczem bk_{region}_.... Odpowiedź to zaakceptowana wiadomość:
Przykład kodu
{
"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 odebrał wiadomość i ją przetwarza; cost ma wartość null, ponieważ wycena następuje podczas przetwarzania. Co dzieje się dalej, opisuje model asynchroniczny.
Budowanie payloadu
Odbiorca
to to jeden odbiorca w formacie E.164: wiodący +, 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 paczkę.
Nadawca
from jest wymagane przy wysyłce z własnym tekstem i określa nadawcę widocznego dla odbiorcy. 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ślników lub kropek, z co najmniej jedną literą i bez separatora na początku ani na końcu, na przykład Bird lub Acme-Co. Musi zawierać literę, więc ciąg cyfr z interpunkcją, taki jak 555 555, jest odrzucany. Niektóre kraje wymagają rejestracji, a inne, w tym USA, nie obsługują nadawców alfanumerycznych. Odbiorcy nie mogą na nie odpowiedzieć.
- Numer należący do Twojego obszaru roboczego, w formacie E.164 lub jako same cyfry. Każda wartość from zł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, zostaje odrzucony. To, czy działa jako numer długi, numer bezpłatny czy krótki, wynika z samego numeru, a nie z liczby wpisanych cyfr. 6-cyfrowa wartość from nie jest krótkim numerem dlatego, że ma 6 cyfr; jest krótkim numerem, jeśli posiadany przez Ciebie numer nim jest.
Nadawca nieprawidłowy dla danego celu jest odrzucany z 422 wskazującym przyczynę (na przykład SMSAlphaNotSupported, gdy nadawcy alfanumeryczni nie są dostępni). Przy wysyłce szablonowej from nie jest akceptowane: Bird wybiera nadawcę na podstawie celu i kategorii.
Rejestrowanie identyfikatora nadawcy, sprawdzanie wymagań poszczególnych krajów i rejestracja per kraj są opisane w identyfikatory nadawców SMS.
Treść i kategoria
text to treść wiadomości, co najmniej jeden znak. Jest rozliczana i doręczana 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 jest odrzucana z 422, a nie obcinana.
category jest wymagane przy wysyłce z własnym tekstem i klasyfikuje wiadomość jako transactional, marketing, authentication lub service. Informuje Bird i operatorów, dlaczego wysyłasz. Jednorazowy kod weryfikacyjny używa authentication; promocja używa marketing. Wybierz kategorię odpowiadającą celowi wiadomości.
Tagi i metadane
Oba mechanizmy dołączają Twoje własne dane do wysyłki, ale służą różnym celom:
- tags to ustrukturyzowane pary {name, value} (maks. 20 na wysyłkę; nazwa od 1 do 32 znaków, wartość od 1 do 64, tylko ASCII [A-Za-z0-9_-], wielkość liter ma znaczenie, nazwy unikalne w ramach wysyłki). Są pełnoprawnym wymiarem filtrowania: filtruj listę wiadomości po tagu. Używaj ich do etykiet o niskiej kardynalności, takich jak campaign lub experiment_variant.
- metadata to dowolny obiekt JSON (maks. 2 KB po serializacji). Jest przechowywany, zwracany przy odczytach API i powtarzany w każdym zdarzeniu webhooka, ale nie jest wymiarem filtrowania. Używaj go do kontekstu dwukierunkowego: wewnętrznych identyfikatorów, kluczy obcych, wszystkiego, co chcesz otrzymać z powrotem przy każdym zdarzeniu.
Przykład kodu
{
"tags": [{ "name": "campaign", "value": "spring-2026" }],
"metadata": { "user_id": "usr_12345", "order_id": "ord_98765" }
}Opis pól
| Pole | Typ | Wymagane | Limity / uwagi |
|---|---|---|---|
| to | string (E.164) | tak | Jeden odbiorca na wiadomość |
| from | string | tak* | Własny numer E.164, alfanumeryczny identyfikator nadawcy (3–11 znaków, min. jedna litera) lub krótki numer (5–6 cyfr) |
| text | string | tak* | Min. 1 znak; maks. 12 segmentów |
| category | string | tak* | transactional, marketing, authentication lub service |
| tags | {name, value}[] | nie | Maks. 20; nazwa 1–32 znaków, wartość 1–64 znaków; tylko [A-Za-z0-9_-] |
| metadata | object | nie | Dowolny JSON, maks. 2 KB po serializacji |
| options | object | nie | Ustawienia przetwarzania per wiadomość. Jedynym dostępnym jest smart_encoding; zobacz segmenty i kodowanie |
* Wymagane przy wysyłce z własnym tekstem. Wysyłka szablonowa dostarcza treść, kategorię i nadawcę z szablonu i odrzuca te trzy pola.
Wysyłka z szablonem
Zamiast tworzyć text, ustaw obiekt template wysyłki tak, aby odwoływał się do jednego z wbudowanych szablonów Bird. Szablon dostarcza treść, kategorię i nadawcę, więc text, category, from i media_urls nie są akceptowane obok niego. Katalog, zmienne każdego szablonu i pełny kontrakt wysyłki szablonowej znajdziesz w szablony SMS.
Segmenty i kodowanie
SMS jest rozliczane per segment. Wiadomość mieszcząca się w kodowaniu GSM-7 ma 160 znaków na pojedynczy segment; UCS-2 (wywoływane przez emoji, CJK i inne znaki spoza GSM) zmniejsza limit do 70. Dłuższe wiadomości są dzielone na segmenty wieloczęściowe z nieco mniejszymi limitami per segment. Każda odpowiedź zawiera rozwiązane segments: rozliczaną liczbę count, encoding i liczbę znaków. Segmenty to jednostka rozliczeniowa; zobacz koszt.
Gdy znaki typograficzne są jedynym powodem, dla którego treść wykracza poza GSM-7, 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 GSM-7. Domyślnie jest wyłączone, ponieważ zmienia skomponowaną treść.
Pełny zestaw znaków, znaki z tabeli rozszerzonej zajmujące dwa miejsca, rozmiar emoji, co zastępuje inteligentne kodowanie i arytmetykę segmentów znajdziesz w artykule Limity znaków.
Wysyłka zbiorcza
POST /v1/sms/batches wysyła do 100 niezależnych wiadomości w jednym żądaniu. Żądania wsadowe korzystają z zasad ograniczania liczby żądań sms_batch, odrębnych od zasad sms_send dla pojedynczych wysyłek. Ciało żą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 w trybie wszystko albo nic: jeśli jakakolwiek wiadomość w partii jest nieprawidłowa, całe żądanie zostaje odrzucone z 422 i nic nie jest wysyłane, więc partia nigdy nie zostanie zastosowana częściowo. W przypadku powodzenia odpowiedź 202 zawiera każdą zaakceptowaną wiadomość w kolejności wysłania w data oraz summary z accepted_count. Od tego momentu każda wiadomość jest niezależna: niepowodzenie doręczenia do jednego odbiorcy 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 zwracane są natychmiast: nieprawidłowe pole, treść przekraczająca limit segmentów, kraj docelowy, którego nie włączyłeś, lub nieprawidłowy nadawca zwraca 422. Obszar roboczy bez środków na koncie otrzymuje 402.
Doręczenie odbywa się asynchronicznie. Wiadomość przechodzi do sent, gdy Bird przekaże ją operatorowi. Potwierdzenie doręczenia ustawia następnie delivered, undelivered, failed lub expired za pośrednictwem zdarzeń i webhooków oraz endpointów odczytu. Ten model ma trzy konsekwencje:
- Koszt jest wyceniany po zaakceptowaniu. cost wiadomości w momencie akceptacji ma wartość null i jest uzupełniany, gdy Bird wyceni wysyłkę podczas przetwarzania. Odczytaj wiadomość ponownie lub poczekaj na zdarzenie doręczenia, aby zobaczyć dotychczasowy koszt; sekcja koszt i rozliczenia opisuje składniki i sytuacje, gdy któryś pozostaje niewyceniony.
- Wiadomość może zostać odrzucona po 202. Jeśli obciążenie nie powiedzie się podczas przetwarzania, wiadomość kończy się statusem rejected z webhookiem sms.rejected i nie ponosisz opłaty; wyczerpane środki pojawiają się jako last_error.code: insufficient_balance.
- Odczyty mogą chwilowo nie nadążać za 202. Wiadomość staje się widoczna na endpointach odczytu krótko po 202, więc 404 wykonany natychmiast po wysyłce rozwiąże się w ciągu chwili.
Zarezerwowane pola
Bird odrzuca obecnie następujące pola żądania z 422 SMSUnsupportedFeature:
scheduled_at, validity_period, media_urls, messaging_profile_id, broadcast_id, campaign_id, audience_id, contact_id, topic_id, personalization, options.max_price_per_segment, options.track_clicks
Nie dołączaj tych pól do wysyłki.
Bezpieczne ponawianie
Wyślij nagłówek Idempotency-Key z unikalną wartością dla każdej logicznej wysyłki. Jeśli żądanie zakończy się sukcesem, ale nie zwróci odpowiedzi, powtórz to samo żądanie z tym samym kluczem. Bird zwróci pierwotny wynik zamiast wysyłać duplikat wiadomości. Format klucza i czas jego przechowywania opisano w sekcji idempotentność.
Koszt i rozliczenia
Wychodzące SMS jest rozliczane za segment. Kwota zależy od kraju i operatora docelowego; na niektórych trasach doliczana jest dopłata strony trzeciej, na przykład opłaty operatorskie US 10DLC.
cost wiadomości dzieli opłatę na nazwane składniki. transaction_amount to kwota, jaką Bird pobrał za dostarczenie wiadomości, passthrough_amount to ewentualna przekazywana opłata strony trzeciej, a amount to suma wycenionych składników wyrażona w currency_code. Składnik, który nie został wyceniony, ma wartość null zamiast "0.00000", więc wiadomość, której dopłata nigdy nie została rozliczona, raportuje amount jako samą opłatę za dostarczenie. Każde pole dokumentuje referencja wiadomości.
Dopłata rozliczana jest w trybie best effort. Bird rozwiązuje ją podczas rejestrowania potwierdzenia doręczenia, w ograniczonym oknie czasowym. Jeśli nie zostanie rozwiązana w tym oknie, passthrough_amount pozostaje null na stałe: Bird nie ponawia próby, a amount pozostaje opłatą za dostarczenie.
Przychodzące SMS jest rozliczane w dwóch pozycjach: stawka przychodząca za segment oraz przychodząca dopłata operatorska, jeśli dotyczy. Obie pozycje są raportowane w cost odebranej wiadomości: stawka jako transaction_amount, dopłata jako passthrough_amount. W odróżnieniu od odpowiednika wychodzącego, dopłata przychodząca jest wyceniana w momencie przyjęcia wiadomości, a nie przy doręczeniu, więc nigdy nie jest uzupełniana później.
Przeglądaj koszt i segmenty poszczególnych wiadomości w logu SMS.
Następne kroki
- Szablony SMS: wyślij wbudowany szablon i pozwól Bird wybrać nadawcę.
- Log SMS: znajdź wiadomość i sprawdź jej cykl życia, segmenty i koszt.
- Zdarzenia: odbieraj zdarzenia doręczenia w swoich systemach.
- Metryki SMS: monitoruj wskaźnik doręczeń, wskaźnik błędów i zaakceptowany wolumen.
- Idempotentność: bezpiecznie ponawiaj wysyłkę za pomocą nagłówka Idempotency-Key.
- Wysyłanie pierwszego SMS: film pokazujący tę samą konfigurację w panelu
Powiązane zasoby
Kontynuuj z dokumentacją, przewodnikami i przykładami dotyczącymi tego tematu. Zasoby są w języku angielskim.
Obejrzyj przewodnikSMS shipping notificationsZrozum koncepcjęWhat does SMS mean?Poznaj możliwościSMSPodążaj ścieżką naukiBuild your first integration
Wypróbuj ćwiczenie i uzyskaj brief wdrożeniowy