# Migrasi SMS dari Twilio

Halaman ini memetakan Programmable Messaging API, Messaging Services, dan status callback Twilio ke Bird. Ikuti [panduan migrasi utama](/docs/guides/sms/migrate) secara berurutan dan gunakan pemetaan ini untuk langkah 3, 4, dan 5.

Dua perbedaan membentuk keseluruhan porting. `POST /2010-04-01/Accounts/{AccountSid}/Messages.json` Twilio menerima parameter `PascalCase` form-encoded yang diautentikasi dengan Account SID dan Auth Token Anda; [`POST /v1/sms/messages`](/docs/api/reference/create-sms-message) menerima JSON yang diautentikasi dengan kunci bearer API terhadap host regional Anda. Dan sebuah Twilio Messaging Service dapat menggabungkan pemilihan pengirim, penanganan opt-out, dan konfigurasi callback. Petakan setiap perilaku secara terpisah ke pemilik Bird; mengganti SID-nya menjadi nilai sender tidak mempertahankan keseluruhan layanan.

## Serahkan ini ke agen Anda

Gunakan ringkasan ini di coding agent Anda. Proses dimulai dengan penemuan dan menghasilkan rencana migrasi yang dapat ditinjau sebelum perubahan apa pun di produksi.

```text
Help me migrate my SMS integration from Twilio to Bird.
1. Inspect this repository's sends, senders, callbacks, schedules, templates, opt-outs and tests. List the traffic and behavior that must survive the migration.
2. Read https://bird.com/docs/guides/sms/migrate/twilio.md and https://bird.com/docs/guides/sms/migrate.md. Use an existing authenticated Bird MCP or CLI connection. If neither is available, follow https://bird.com/docs/ai/set-up-your-agent.md. Discover the actual operations; do not invent commands or ask me to paste credentials into chat.
3. Prepare the code changes, sender/destination requirements, consent migration, webhook verification and rollout/rollback plan. Preserve the scope of each customer's preferences, including requests outside SMS replies. Separate API batches from audience broadcasts and preserve any behavior that has no direct endpoint equivalent.
4. Show me the exact affected resources, destinations, test volume and known costs before an action that sends messages, spends money, registers or changes a sender, or moves production traffic. Require explicit human authorization for each paid submission or production change. Name one-off 10DLC registration and resubmission fees before requesting approval. An existing explicit approval for that exact action is sufficient; broad migration approval is not. Simulated SMS destinations are billable and still require authorization.
5. If I am keeping Twilio numbers, prepare the human support port request and obtain authorization to send it. Read bird support-tickets create --help, then use the available CLI or MCP support operation with the reviewed number list and requirements. Return the ticket ID and follow the reply; support arranges the port on its own schedule, separately from the code cutover.
6. Run local and intercepted tests first. When authorized, perform the agreed bounded integration tests, inspect accepted and final outcomes separately, and report failures or uncertainty. Do not claim a delivery receipt proves reading or that request idempotency guarantees exactly-once delivery.
7. Keep production cutover and retiring the old provider as explicit steps in the approved rollout. Finish with the diff, evidence, unresolved requirements and the next action.
```

## Petakan panggilan kirim

| Fungsi                    | Twilio                                       | Bird                                                                                |
| ------------------------- | -------------------------------------------- | ----------------------------------------------------------------------------------- |
| Penerima                  | `To`                                         | `to` (satu per permintaan)                                                          |
| Pengirim                  | `From` atau `MessagingServiceSid`            | `from`                                                                              |
| Isi                       | `Body`                                       | `text`                                                                              |
| Template konten           | `ContentSid` + `ContentVariables`            | tinjau konten secara terpisah; template sistem Bird bukan impor dari Twilio Content |
| Intent                    | (tidak ada)                                  | `category`, wajib pada teks bebas                                                   |
| Label yang dapat difilter | (tidak ada)                                  | pasangan `tags`: `{name, value}`                                                    |
| Konteks bolak-balik       | penyimpanan sendiri, dikunci berdasarkan SID | `metadata`: JSON arbitrer, dikembalikan di setiap event                             |
| Laporan pengiriman        | `StatusCallback`                             | webhook workspace yang berlangganan event pengiriman di bawah                       |
| Transliterasi             | `SmartEncoded`                               | `options.smart_encoding` (default `false`)                                          |
| Coba lagi yang aman       | (tidak ada di Messages)                      | header `Idempotency-Key`                                                            |
| Penjadwalan               | `ScheduleType` + `SendAt`                    | tidak ada padanan: `scheduled_at` ditolak                                           |
| Media                     | `MediaUrl`                                   | tidak ada padanan: `media_urls` ditolak                                             |
| Validitas                 | `ValidityPeriod`                             | tidak ada padanan: `validity_period` ditolak                                        |
| Pemendekan tautan         | `ShortenUrls`                                | tidak ada padanan                                                                   |

Tiga field yang ditolak berstatus [reserved](/docs/guides/sms/sending-sms#reserved-fields) dan menjawab `422 SMSUnsupportedFeature`. Pertahankan penanganan penjadwalan dan media di tempatnya untuk saat ini.

Catatan porting:

- **Selesaikan perilaku Messaging Service secara terpisah.** Twilio menentukan sender pool, sticky sender, dan geomatch di balik SID. Bird menerima pengirim itu sendiri di `from`, jadi pilih pengirim per pengiriman, atau gunakan [template send](/docs/guides/sms/templates), yang memilih pengirim valid untuk tujuan dan menolak `from`.
- **Batas karakter menjadi [batas segmen](/docs/guides/sms/sending-sms#segments-and-encoding).** Panjangnya hampir sama untuk teks GSM-7, tetapi kegagalannya berbeda: Bird tidak pernah memotong, jadi isi yang melebihi panjang ditolak dengan `422` alih-alih dipangkas.
- **Tidak ada yang di Messages API berpadanan dengan `category`.** Tentukan per jenis pesan apakah itu `transactional`, `marketing`, `authentication`, atau `service`. Trafik autentikasi khususnya harus diberi label demikian, bukan dibiarkan dalam default marketing.
- **Kredensial uji Twilio dipetakan ke tujuan simulasi.** Nomor ajaib yang sudah Anda gunakan untuk pengujian, termasuk `+15005550006` dan `+15005550001`, menghasilkan hasil sintetis di sini juga, dengan dua perbedaan: tidak ada kredensial uji terpisah, dan pengiriman dikenakan biaya. Hasilnya tercantum di [panduan utama](/docs/guides/sms/migrate#6-test-against-simulated-destinations).

## Pindahkan opt-out

Twilio dapat membatasi cakupan opt-out ke nomor atau Messaging Service. Permintaan seluruh layanan dapat mencakup beberapa pengirim. Pertahankan cakupan tersebut saat mengimpor ke supresi pengirim-dan-pelanggan Bird, atau gunakan preferensi workspace yang sesuai untuk permintaan yang benar-benar berskala workspace.

[Dokumentasi Advanced Opt-Out](https://www.twilio.com/docs/messaging/tutorials/advanced-opt-out) Twilio menyatakan bahwa pelaporan nomor yang diblokir tidak tersedia melalui Console atau REST API-nya. Minta ekspor melalui proses dukungan yang tersedia dan cocokkan dengan catatan preferensi Anda sendiri, log masuk, dan permintaan dukungan. Log kata kunci saja mungkin tidak lengkap.

Impor hasil yang telah ditinjau melalui [alur kerja supresi](/docs/guides/sms/migrate#4-carry-over-your-opt-out-list). Supresi manual memblokir semua kategori untuk pasangan tersebut, jadi periksa cakupan yang dimaksud alih-alih mempersempit atau memperluasnya secara diam-diam.

`21610` Twilio menandakan penerima yang telah opt-out. Di Bird, pasangan yang disupresi ditolak saat admisi dengan `E12077 SMSRecipientSuppressed`, sebelum pesan dibuat. Error pengiriman `recipient_opted_out` melaporkan opt-out hilir. Periksa [cakupan kata kunci Bird](/docs/guides/sms/opt-outs-and-keywords) sebelum menonaktifkan handler yang ada, dan pertahankan mekanisme opt-out di luar katalog bawaan.

## Terjemahkan status pengiriman

Gunakan tabel ini untuk membandingkan konsep siklus hidup, bukan untuk mengganti nama event secara mekanis. Bird memilih event kegagalan dari status dan alasan yang dilaporkan. Permintaan API yang ditolak tidak membuat pesan; penolakan setelah penerimaan dapat menghasilkan `sms.rejected`, termasuk penolakan operator. Bukti pengiriman yang tidak ada tetap berstatus unknown. Simpan status dan kode mentah dari provider di samping hasil yang sudah dinormalisasi.

| Hasil                                    | Twilio `MessageStatus`  | Bird                                   |
| ---------------------------------------- | ----------------------- | -------------------------------------- |
| API menerima pesan                       | `queued`, `accepted`    | `sms.accepted`                         |
| Diserahkan ke operator                   | `sending`, `sent`       | `sms.sent`                             |
| Operator mengonfirmasi pengiriman        | `delivered`             | `sms.delivered`                        |
| Operator melaporkan kegagalan pengiriman | `undelivered`           | `sms.undelivered`                      |
| Kegagalan permanen                       | `failed`                | `sms.failed`                           |
| Permintaan ditolak saat admisi           | error permintaan        | error HTTP; tidak ada pesan atau event |
| Jendela validitas habis                  | (tidak ada)             | `sms.expired`                          |
| Dijadwalkan atau dibatalkan              | `scheduled`, `canceled` | belum ada padanan                      |

Tiga mekanisme berubah seiring perubahan nama:

- **Endpoint menggantikan URL callback.** Twilio mengirim ke `StatusCallback` pada pesan atau Messaging Service. Bird mengirimkan ke endpoint yang didaftarkan workspace Anda, masing-masing berlangganan tipe event yang diinginkan, sehingga konsumen baru adalah langganan baru, bukan deploy ulang.
- **JSON bertanda tangan menggantikan post form-encoded.** Twilio mengirim `application/x-www-form-urlencoded` dengan header `X-Twilio-Signature`; Bird mengirim JSON yang ditandatangani sesuai [Standard Webhooks](https://www.standardwebhooks.com). Ganti verifikasi tersebut dengan resep di [Webhooks & events](/docs/guides/webhooks#verify-signatures).
- **Pesan masuk tiba sebagai event.** Webhook "A message comes in" per-nomor Twilio mengharapkan respons TwiML yang dapat digunakan aplikasi Anda untuk membalas otomatis. Bird memancarkan `sms.received` ke endpoint berlangganan yang sama dengan semua event lain, dan tidak ada isi respons yang mengirimkan balasan: jawab dengan memanggil endpoint kirim, atau biarkan [aturan kata kunci](/docs/guides/sms/opt-outs-and-keywords) menjawab untuk Anda.

Daftarkan endpoint sekali, sebutkan tipe event yang diinginkan handler Anda: event `sms.*` dalam tabel di atas adalah daftar yang harus Anda langgani, dan tidak ada wildcard yang menggantikannya. [Buat endpoint](/docs/guides/webhooks#create-an-endpoint) berisi perintahnya, mengapa katalog harus dienumerasi, dan satu hal yang harus benar pada panggilan pertama, yaitu menyimpan signing secret yang ditampilkan respons tepat satu kali.

Kode error numerik Twilio tidak memiliki pemetaan satu-ke-satu. Bird melaporkan kegagalan dengan kode `error` terstandar seperti `invalid_destination`, `content_rejected`, `provider_unavailable`, atau `recipient_opted_out`; daftar lengkapnya ada di [halaman events](/docs/guides/sms/events#failure-events). Petakan alerting Anda ke kode-kode tersebut, bukan ke kode rentang 30000.

## Cutover

[Tujuan](/docs/guides/sms/migrate#1-enable-your-destination-countries), [pengirim](/docs/guides/sms/migrate#2-set-up-a-sender), dan [ramp trafik](/docs/guides/sms/migrate#6-test-against-simulated-destinations) bersifat independen terhadap provider dan dibahas di panduan utama. Dua item khusus Twilio perlu masuk ke rencana cutover: brand dan campaign 10DLC Anda terdaftar di The Campaign Registry melalui Twilio dan tidak otomatis menjadi registrasi Bird. Konfirmasi prosedur migrasi atau registrasi yang berlaku sebelum mengirimkan pekerjaan berbayar. Nomor yang Anda miliki di Twilio memerlukan porting yang diatur oleh tim dukungan, sesuai jadwal mereka, bukan Anda.

Untuk persyaratan sisi Bird, mulailah dari [Register for 10DLC](/docs/guides/sms/10dlc): halaman tersebut mencakup arti setiap field, tipe entitas yang dikenali registry, dan panggilan persyaratan yang memberi tahu apa yang perlu Anda siapkan sebelum membuat brand, yaitu langkah yang dikenakan biaya.

## Langkah berikutnya

- [Bandingkan Bird dan Twilio untuk SMS](/products/sms/compare/bird-vs-twilio): evaluasi produk dan pertimbangan migrasi

- [Mengirim SMS](/docs/guides/sms/sending-sms): payload yang menjadi tujuan porting Anda, secara lengkap
- [Opt-out dan kata kunci](/docs/guides/sms/opt-outs-and-keywords): cakupan kata kunci per negara dan manajemen supresi
- [Event SMS](/docs/guides/sms/events): kosakata event yang menjadi tujuan status handler Anda
- [Webhooks & events](/docs/guides/webhooks): pengaturan endpoint dan verifikasi Standard Webhooks

## Related resources

- [Choose a sender for your markets](/explained/sms/which-sms-sender-type-should-i-use) (answer)
- [Check your message segments](/tools/sms-segment-calculator) (tool)
- [Compare SMS providers](/products/sms/compare) (product)
