# Menerima pesan WhatsApp

Pesan masuk tersimpan di resource yang sama dengan pesan keluar, tanpa endpoint inbox terpisah untuk di-poll. Baca pesan melalui [daftar pesan](/docs/guides/whatsapp/message-log) di dashboard, atau melalui API dengan `GET /v1/whatsapp/messages/{id}` setelah memfilter daftar ke pesan masuk.

Setiap pesan masuk memperpanjang [jendela layanan pelanggan](/docs/knowledge-base/whatsapp/customer-service-window) hingga 24 jam setelah timestamp pesan itu sendiri, yang membuat balasan bebas dari Anda dapat terkirim. Pesan yang tiba di Bird terlambat tetap membawa jendela yang sebenarnya diberikan kontaknya, dan tenggat waktu yang sudah tercatat lebih lama tidak pernah diperpendek.

## Isi pesan masuk

Setiap pesan masuk memiliki satu envelope: `id`, `direction: "inbound"`, kontak di `from`, nomor Anda di `to`, `status` berupa `received`, dan `created_at`. Tepat satu field konten menyertainya, menyatakan apa yang dikirim kontak:

```json
{
  "id": "wam_01kya19eknftrs2s6p82asmvnh",
  "direction": "inbound",
  "from": { "phone_number": "+14155550100" },
  "to": { "phone_number": "+13124495569" },
  "status": "received",
  "text": { "body": "Is my order out for delivery yet?" },
  "created_at": "2026-08-25T09:04:11Z"
}
```

`from` menamai kontak berdasarkan identitas apa pun yang dilaporkan WhatsApp: `phone_number` E.164, `bsuid`, atau keduanya, ditambah `username` dan `display_name` yang mereka publikasikan. Kontak yang telah menggunakan username WhatsApp dapat menghubungi Anda tanpa nomor telepon sama sekali; lihat [business-scoped user ID](/docs/guides/whatsapp/business-scoped-user-ids) untuk mengetahui apa yang perlu disimpan dan cara meminta nomor.

Salah satu field konten ini, sebuah **arm**, membawa apa yang dikirim kontak, dan tepat satu arm yang diisi pada setiap pesan. Masing-masing memiliki halaman tersendiri, dengan bentuk baca, payload `whatsapp.received`, dan hal yang perlu diperhatikan:

| Field                                                                               | Isi pesan masuk                                                            |
| ----------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| [`text`](/docs/guides/whatsapp/receiving-whatsapp/plain-text)                       | `body`, pesan yang diketik kontak                                          |
| [`image`](/docs/guides/whatsapp/receiving-whatsapp/images)                          | `id`, `url`, `mime_type`, dan `caption` jika ada                           |
| [`video`](/docs/guides/whatsapp/receiving-whatsapp/video)                           | Field media yang sama, ditambah `caption` jika ada                         |
| [`audio`](/docs/guides/whatsapp/receiving-whatsapp/audio)                           | Field media yang sama, ditambah `voice` pada voice note; tidak ada caption |
| [`sticker`](/docs/guides/whatsapp/receiving-whatsapp/stickers)                      | Field media yang sama, ditambah `animated`                                 |
| [`document`](/docs/guides/whatsapp/receiving-whatsapp/documents)                    | Field media yang sama, ditambah `filename` dan `caption` jika ada          |
| [`location`](/docs/guides/whatsapp/receiving-whatsapp/location)                     | `latitude` dan `longitude`, dan terkadang `name`, `address`, atau `url`    |
| [`contact_cards`](/docs/guides/whatsapp/receiving-whatsapp/contact-cards)           | Satu atau lebih kartu kontak yang dibagikan kontak                         |
| [`interactive_reply`](/docs/guides/whatsapp/receiving-whatsapp/interactive-replies) | `slug` dan `text` dari tombol atau baris yang diketuk kontak               |
| [`unsupported`](/docs/guides/whatsapp/receiving-whatsapp/unsupported)               | Tipe konten WhatsApp yang tidak dimodelkan API, seperti order              |

Dua ketukan tiba pada arm yang mungkin tidak Anda duga. [Location request](/docs/guides/whatsapp/message-types/interactive/location-requests) dijawab sebagai `location` masuk biasa, dan [contact info request](/docs/guides/whatsapp/message-types/interactive/contact-info-requests) dijawab sebagai `contact_cards`, sehingga integrasi yang hanya memantau `interactive_reply` untuk ketukan akan melewatkan keduanya.

## Mengambil media masuk

`image`, `video`, `audio`, `sticker`, atau `document` masuk tiba sebagai referensi ke file yang disimpan Bird, bukan sebagai file itu sendiri:

```json
{
  "image": {
    "id": "waf_01kyb2m4xq7whs0d8n3prv6tez",
    "url": "https://platform.bird.com/v1/whatsapp/messages/wam_01kya19eknftrs2s6p82asmvnh/media/waf_01kyb2m4xq7whs0d8n3prv6tez",
    "mime_type": "image/jpeg",
    "caption": "Is this the right part?"
  }
}
```

Ambil byte-nya dengan method media channel, dengan meneruskan message id dan `id` media:

**TypeScript**

```typescript
const media = await bird.whatsapp.messages.media(
  "wam_01kya19eknftrs2s6p82asmvnh",
  "waf_01kyb2m4xq7whs0d8n3prv6tez",
);
console.log(media.contentType, media.contentLength);
```

Examples: [TypeScript](/id-id/dokumentasi/guides/whatsapp/receiving-whatsapp.ts.md) · [Python](/id-id/dokumentasi/guides/whatsapp/receiving-whatsapp.py.md) · [Go](/id-id/dokumentasi/guides/whatsapp/receiving-whatsapp.go.md) · [PHP](/id-id/dokumentasi/guides/whatsapp/receiving-whatsapp.php.md) · [CLI](/id-id/dokumentasi/guides/whatsapp/receiving-whatsapp.cli.md) · [MCP](/id-id/dokumentasi/guides/whatsapp/receiving-whatsapp.mcp.md) · [cURL](/id-id/dokumentasi/guides/whatsapp/receiving-whatsapp.curl.md)

Anda mendapatkan byte-nya kembali dengan `mime_type` storage yang dideklarasikan untuk file tersebut. ID yang tidak dikenali Bird mengembalikan `404`, dan pesan keluar tidak memiliki media tersimpan untuk disajikan.

**Pesan dapat dibaca kembali selama 30 hari setelah tiba, dan medianya tidak pernah bertahan lebih lama dari pesannya.** Endpoint ini membaca pesan sebelum menyajikan file, jadi setelah jendela itu berlalu keduanya menjawab `404`. Simpan file yang Anda butuhkan lebih lama selagi pesan masih dapat dibaca. Satu kasus yang berakhir lebih awal adalah jika byte yang tersimpan hilang sebelum jendela habis: fetch menjawab `410` [`E15021`](/docs/api/errors/E15021), dan pesan masih dapat dibaca kembali dengan `mime_type` dan `caption` media-nya.

Di balik layar, endpoint ini menjawab `302` dengan presigned URL yang berlaku selama 15 menit. SDK dan CLI menangani redirect itu untuk Anda. Jika Anda memanggilnya langsung, presigned URL membawa kredensialnya sendiri, sehingga request yang di-redirect tidak boleh mengirimkan header `Authorization` Anda juga. Mengirim keduanya akan gagal. `curl -L` menghapus header pada cross-host redirect secara otomatis; klien yang meneruskan header apa adanya perlu mengambil `Location` sebagai request terpisah tanpa autentikasi.

## Balasan kutipan

`in_reply_to_message_id` menamai pesan yang dijawab oleh pesan masuk, saat WhatsApp menandainya sebagai balasan:

```json
{
  "id": "wam_01kyb2m4xq7whs0d8n3prv6tez",
  "direction": "inbound",
  "in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
  "text": { "body": "Yes, that one" }
}
```

WhatsApp tidak menandai setiap balasan, dan balasan yang tidak ditandai tidak membawa ID sama sekali. Field ini juga dihilangkan jika pesan yang dikutip tidak dapat dicocokkan dengan pesan yang disimpan Bird: pesan yang dikirim sebelum workspace ini mulai merekamnya, atau pesan yang sudah melewati 15 hari penyimpanan message id WhatsApp oleh Bird. Ketidakcocokan menghilangkan field tersebut alih-alih melaporkannya, yang terbaca sama seperti balasan yang tidak menjawab apa pun.

Perlakukan field ini sebagai petunjuk, bukan sebagai kunci. `metadata` pada pesan kirim Anda sendiri tidak membantu di sini, karena ia tetap pada pesan Anda dan tidak pernah berpindah ke balasan kontak, sehingga integrasi yang harus mengetahui pertanyaan mana yang dijawab perlu melacak sendiri pertanyaan terakhir yang dikirimkan ke kontak tersebut. Lihat [Mengutip pesan](/docs/guides/whatsapp/sending-whatsapp#quoting-a-message) untuk sisi pengiriman.

## Webhook

Subscribe ke `whatsapp.received` untuk menindaklanjuti pesan masuk saat tiba, alih-alih mem-poll daftar. Payload membawa konten di atas event envelope, sehingga endpoint tidak perlu membaca ulang:

```json
{
  "type": "whatsapp.received",
  "timestamp": "2026-08-25T09:04:11.118Z",
  "data": {
    "whatsapp_id": "wam_01kyb2m4xq7whs0d8n3prv6tez",
    "workspace_id": "ws_01ky7m235keycbnwyajabe1a6b",
    "direction": "inbound",
    "from": { "phone_number": "+14155550100", "display_name": "Alex Rivera" },
    "to": { "phone_number": "+13124495569" },
    "in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
    "interactive_reply": {
      "type": "button",
      "button": { "slug": "cancel-booking", "text": "Cancel" }
    },
    "tags": null,
    "metadata": null
  }
}
```

Lihat [event WhatsApp](/docs/guides/whatsapp/events#webhooks) untuk envelope lengkap dan daftar event selengkapnya.

## Langkah selanjutnya

- [Service message](/docs/guides/whatsapp/message-types): sisi pengiriman dari content arm yang sama
- [Mengirim pesan WhatsApp](/docs/guides/whatsapp/sending-whatsapp): membalas di dalam jendela layanan, dan mengutip pesan
- [Event WhatsApp](/docs/guides/whatsapp/events): daftar event lengkap, melalui API atau webhook
- [Log WhatsApp](/docs/guides/whatsapp/message-log): menelusuri percakapan di dashboard

## Related resources

- [Connecting WhatsApp to Bird: from buying a number to a live channel](/learn/whatsapp/connecting-whatsapp-to-bird) (video)
- [What is the 24-hour customer service window on WhatsApp?](/explained/whatsapp/what-is-the-24-hour-customer-service-window) (answer)
- [WhatsApp message builder](/tools/whatsapp-message-builder) (tool)
- [WhatsApp](/products/whatsapp) (product)

[Get an implementation brief](/learn/workspace?topic=whatsapp)
