Mengirim pesan WhatsApp
Panduan ini membahas endpoint pengiriman, POST /v1/whatsapp/messages. Anda menyusun satu payload JSON dengan satu penerima dan tepat satu jenis konten: template yang telah disetujui, atau pesan layanan berisi teks, gambar, video, audio, stiker, dokumen, lokasi, kartu kontak, atau sesuatu yang bisa diketuk. Bird mengembalikan 202 Accepted dengan ID pesan dan mengirim secara asinkron. Jenis mana yang bisa Anda kirim bergantung pada jendela layanan pelanggan. Setiap permintaan mengirim satu pesan ke satu penerima, dan tidak ada endpoint batch.
Pengiriman minimal
Payload valid terkecil adalah penerima to dan template dengan slug-nya. Tambahkan language jika Anda menginginkan bahasa tertentu; tidak menyertakannya akan mengirim bahasa default template, dan isi variabel yang dideklarasikan template melalui components.
Pemanggilan curl menyebutkan host US; jika kunci Anda diawali dengan bk_eu1_, panggil https://eu1.platform.bird.com sebagai gantinya. SDK membaca region dari kunci Anda, jadi tidak perlu mengatur host.
const msg = await bird.whatsapp.send({
to: "+15551234567",
template: {
slug: "bird_otp",
components: [{ type: "body", parameters: [{ type: "text", text: "123456" }] }],
},
});
console.log(msg.id, msg.status);msg = client.whatsapp.send(
to="+31612345678",
template="bird_otp",
language="en",
components=[{"type": "body", "parameters": [{"type": "text", "text": "123456"}]}],
)
print(msg.id, msg.status)code := "123456"
msg, err := client.Whatsapp.Send(context.Background(), bird.WhatsappSendParams{
To: "+15551234567",
Template: "bird_otp",
Language: "en",
Components: []bird.WhatsAppMessageTemplateComponent{{
Type: "body",
Parameters: &[]bird.WhatsAppMessageTemplateComponentParameter{{Type: "text", Text: &code}},
}},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(msg.Id, *msg.Status)$message = $bird->whatsapp->send(
to: '+15551234567',
template: 'bird_otp',
language: 'en',
components: [
(new WhatsAppMessageTemplateComponent())
->setType('body')
->setParameters([
(new WhatsAppMessageTemplateComponentParameter())->setType('text')->setText('123456'),
]),
],
);
echo $message->getId(), ' ', $message->getStatus();bird whatsapp send \
--components '[{"parameters":[{"text":"1234","type":"text"}],"type":"body"},{"parameters":[{"text":"1234","type":"text"}],"type":"button"}]' \
--language en \
--template bird_otp \
--to +31612345678curl -X POST "https://{region}.platform.bird.com/v1/whatsapp/messages" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"to": "+31612345678",
"template": {
"slug": "bird_otp",
"language": "en",
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "1234"
}
]
},
{
"type": "button",
"parameters": [
{
"type": "text",
"text": "1234"
}
]
}
]
}
}'Jendela layanan pelanggan
Jenis mana yang bisa Anda kirim bergantung pada satu kondisi: apakah jendela layanan pelanggan sedang terbuka.
Kontak membuka jendela layanan dengan mengirim pesan atau menelepon nomor bisnis Anda, dan jendela layanan tetap terbuka selama 24 jam, direset setiap kali mereka mengirim pesan lagi. Selama terbuka, Anda dapat mengirim pesan layanan, yaitu konten bebas apa pun: teks, gambar, video, audio, stiker, dokumen, lokasi, atau interaktif. Setelah kedaluwarsa, hanya template yang telah disetujui yang dapat menjangkau mereka, dan balasan mereka terhadap template tersebut membuka kembali jendela layanan.
Bird melacak jendela layanan untuk Anda, sehingga pesan layanan yang dikirim ke jendela layanan yang tertutup ditolak sebelum apa pun dibuat atau dikenakan biaya: permintaan mengembalikan 422 E15044 WhatsAppServiceWindowClosed. Pemeriksaan ini dilakukan sebisa mungkin; jika tidak dapat memastikan status jendela layanan, permintaan tetap dapat diterima, jadi 202 bukan bukti bahwa jendela layanan benar-benar terbuka saat pengiriman; pesan gagal secara asinkron jika jendela layanan kedaluwarsa antara penerimaan permintaan dan pengiriman ke WhatsApp, dengan service_window_expired pada last_error pesan.
Lihat jendela layanan pelanggan untuk siklus lengkapnya: apa yang membukanya, apa yang meresetnya, dan bagaimana interaksinya dengan harga.
Menyusun payload
Penerima
to menyebutkan satu tujuan, berupa nomor telepon, business-scoped user ID, atau group ID. Nomor telepon menggunakan format E.164: diawali +, kode negara, dan nomor pelanggan, misalnya +14155550100. Kami memvalidasi nomor tersebut, sehingga nilai yang bukan nomor nyata dan dapat dihubungi (panjang salah, prefiks tidak terdaftar) ditolak dengan 422 WhatsAppInvalidRecipient sebelum ada biaya yang dikenakan. Tidak ada array penerima dan tidak ada pengiriman batch, jadi untuk menjangkau banyak orang yang tidak berada dalam satu grup, Anda perlu satu panggilan per penerima.
ID pengguna cakupan bisnis seperti US.13491208655302741918 digunakan untuk mengirim pesan ke kontak yang nomor teleponnya tidak Anda miliki, yaitu cara Anda membalas kontak yang menghubungi Anda tanpa nomor telepon. Dua hal berubah: nomor pengirim harus termasuk dalam portofolio bisnis yang sama dengan cakupan ID tersebut, dan template kode verifikasi sekali pakai memerlukan nomor telepon. Template kode verifikasi sekali pakai yang dikelola Bird ditolak saat permintaan diterima dengan 422 WhatsAppRecipientNotSupportedForTemplate; template autentikasi yang dibuat workspace Anda diterima lalu gagal, karena Meta memerlukan nomor telepon untuk template tersebut.
to menerima satu bentuk lagi: WhatsApp group ID seperti wag_01krdgeqcxet5s7t44vh8rt9mg, yang mengirim ke setiap peserta group chat tersebut. Pengiriman grup tidak menyertakan from dan melaporkan pengirimannya ke seluruh grup, bukan terhadap satu penerima, sehingga Mengirim ke grup WhatsApp membahasnya di halaman tersendiri.
Template
template menyebutkan template yang telah disetujui untuk dikirim:
- slug (wajib): slug template, misalnya bird_order_confirmation. Harus cocok dengan template di katalog Anda (huruf kecil, digit, dan garis bawah).
- language: tag bahasa template, misalnya en atau pt-BR. Abaikan untuk mengirim bahasa default template; menyebutkan bahasa yang tidak dimiliki template mengembalikan 422 yang mencantumkan bahasa yang tersedia. Pesan yang diterima menampilkan bahasa yang diterapkan.
- components: nilai yang mengisi variabel template (lihat Komponen dan parameter). Abaikan untuk template tanpa variabel.
Telusuri template Anda, bahasanya, dan pratinjau render masing-masing di halaman Templates.
Komponen dan parameter
Template memiliki variabel, baik bernama ({{ref}}, {{amount}}) maupun bernomor ({{1}}, {{2}}). Anda mengisi nilainya melalui components. Setiap komponen menyebutkan type (body atau button) dan array parameters. Setiap parameter menyebutkan type-nya sendiri (text, image, video, gif, document, atau location) dan membawa field yang sesuai: text berupa string biasa, image/video/gif/document berupa https url publik, dan location berupa titik di peta. Template dengan parameter bernama memerlukan name pada setiap parameter, yang harus cocok persis dengan nama yang dideklarasikan template (lihat Referensi field). Template posisional tidak menyertakan name dan mengambil nilainya sesuai urutan {{n}}, sehingga parameter pertama mengisi {{1}}. Bagaimanapun, parameter yang tidak cocok dengan deklarasi template mengembalikan 422 WhatsAppTemplateParameterMismatch. Tipe komponen header juga ada di wire: pada template yang dikelola Bird, tipe ini diabaikan karena tidak ada template yang dikelola Bird yang mendeklarasikan variabel header, tetapi pada template yang dibuat workspace Anda, tipe ini diteruskan, dan begitulah cara template utilitas atau marketing dengan media header mendapatkan gambarnya.
Misalnya, template one-time-passcode yang isinya bertuliskan {{1}} is your verification code dan tombolnya menyalin kode, menerima kode tersebut sebagai parameter body sekaligus parameter button secara posisional (tanpa name):
Contoh kode
{
"components": [
{ "type": "body", "parameters": [{ "type": "text", "text": "481920" }] },
{ "type": "button", "parameters": [{ "type": "text", "text": "481920" }] }
]
}Kategori dan pengirim
Kategori template (authentication, utility, atau marketing) menentukan cara WhatsApp memperlakukan pesan dan, bersama negara tujuan, berapa biayanya.
Siapa pemilik pengirim menentukan apakah Anda perlu menyebutkannya:
- Template yang dikelola Bird (slug-nya diawali bird_) dikirim dari nomor yang disimpan Bird untuk kategori tersebut, jadi abaikan from. Mengisinya mengembalikan 422 WhatsAppSenderNotAllowed.
- Semua yang lain menyebutkan pengirimnya sendiri di from: service message jenis apa pun, dan template apa pun yang dibuat workspace Anda. Nomor tersebut harus dimiliki workspace Anda. Mengabaikannya mengembalikan 422 WhatsAppSenderRequired, dan nomor yang tidak dapat digunakan workspace untuk mengirim mengembalikan 422 WhatsAppSenderNotFound. Template buatan sendiri juga harus berada di WhatsApp Business Account yang sama dengan nomornya, atau pengiriman mengembalikan 422 WhatsAppSenderWABAMismatch.
Pengaturan nomor telepon membahas kedua jenis nomor dan cara menghubungkan nomor milik Anda.
Service message
Alih-alih template, sertakan tepat satu dari text, image, video, audio, sticker, document, location, contact_cards, atau interactive. Kesembilan jenis ini adalah service message, sehingga memerlukan customer service window yang terbuka. Semuanya juga memerlukan from, nomor yang dimiliki workspace Anda; nomor yang dikelola Bird tidak dapat digunakan.
- text: { "body": "..." }, hingga 4096 karakter. Tambahkan "preview_url": true untuk merender pratinjau tautan dari URL pertama di body.
- image, video, audio, sticker, document: masing-masing menerima URL https publik yang diambil WhatsApp saat pengiriman (url), jadi URL bertanda tangan harus tetap berlaku lebih lama dari pengiriman. URL http langsung ditolak. WhatsApp mengambil file itu sendiri, sehingga URL yang tidak dapat dijangkau, yang menyajikan tipe tidak didukung, atau file yang melebihi batas ukuran untuk tipenya akan diterima lalu gagal, dengan media_rejected pada last_error pesan dan alasan dari WhatsApp sendiri di description. image, video, dan document juga menerima caption opsional; document juga menerima filename opsional; audio menerima flag voice opsional untuk rendering voice note.
- location: { "latitude": ..., "longitude": ... } (keduanya wajib, derajat desimal) ditambah name dan address opsional.
- contact_cards: array berisi hingga lima kontak yang dibagikan dalam satu pesan. name setiap kartu memerlukan formatted_name ditambah setidaknya satu bagian lain (first_name, last_name, middle_name, prefix, atau suffix); phone_numbers, emails, urls, dan addresses masing-masing menerima hingga sepuluh entri, dan org serta birthday (sebagai YYYY-MM-DD) bersifat opsional. phone_number dalam format E.164 memberi kartu tersebut tombol yang membuka chat dengannya.
- interactive: teks body ditambah sesuatu untuk diketuk, dalam salah satu dari enam tipe: tombol balasan, menu daftar, tombol tautan, carousel media, atau tombol tunggal yang meminta lokasi atau nomor telepon penerima. Pesan interaktif membahas bentuk wire setiap tipe, balasan yang dihasilkan ketukan, dan batasannya.
Contoh kode
{
"to": "+16505551234",
"from": "+13124495648",
"text": { "body": "Your order shipped: https://example.com/track/A1B2C3", "preview_url": true }
}Permintaan tanpa konten, atau dengan lebih dari satu tipe, ditolak dengan 422.
Mengutip pesan
Atur in_reply_to_message_id ke message ID WhatsApp untuk mengirim pesan Anda sebagai balasan, seperti saat mengetuk balas di aplikasi WhatsApp yang mengutip pesan. Penerima melihat pesan Anda dengan pesan yang dikutip di atasnya, dan field ini dikembalikan setiap kali pesan dibaca.
Ini juga berlaku sebaliknya: pesan masuk yang ditandai WhatsApp sebagai balasan membawa ID pesan yang dikutip di field yang sama, dan begitulah cara Anda mengetahui pesan mana yang dibalas. Pesan masuk yang tidak ditandai WhatsApp tidak membawa ID, dan resolusi juga bisa meleset. Untuk korelasi yang andal, gunakan identifier balasan interaktif eksplisit bersama status percakapan atau tugas yang disimpan aplikasi Anda. metadata keluar tetap di catatan keluar dan tidak otomatis disalin ke balasan.
Kutipan diselesaikan sebelum pengiriman diterima, jadi kutipan yang tidak dapat dirender menggagalkan permintaan itu sendiri dan tidak ada yang dibuat atau dikenakan biaya. ID yang tidak merujuk pesan mana pun di workspace ini, atau yang lebih lama dari 15 hari masa pesan dapat dikutip, mengembalikan 404 E15071 WhatsAppReferencedMessageNotFound. ID yang merujuk pesan yang tidak pernah sampai ke WhatsApp, atau pesan dari percakapan berbeda dari to dan from pengiriman ini, mengembalikan 422 E15072 WhatsAppMessageNotQuotable. Jika Bird tidak dapat menjangkau penyimpanan yang menjawab pertanyaan tersebut, pengiriman mengembalikan 503 E15073 WhatsAppMessageLookupUnavailable, yang layak untuk dicoba lagi. Pengutipan berfungsi pada pengiriman template maupun pengiriman free-form.
Contoh kode
{
"to": "+16505551234",
"from": "+13124495648",
"in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
"text": { "body": "Yes, that slot is still free." }
}Tag dan metadata
Dua field opsional melampirkan konteks Anda sendiri ke pesan; keduanya dikembalikan pada pembacaan API dan disertakan pada setiap event webhook untuk pesan tersebut:
- tags: hingga 20 label { "name": ..., "value": ... } terstruktur untuk dimensi kardinalitas rendah yang Anda gunakan untuk memfilter dan melaporkan (kampanye, varian eksperimen). Nama dan nilai menerima huruf ASCII, digit, garis bawah, dan tanda hubung; nama dibatasi 32 karakter dan unik dalam satu pengiriman, nilai dibatasi 64. Filter daftar pesan berdasarkan tag (?tag=campaign atau ?tag=campaign:launch-week), dan halaman Metrics memecah pengiriman berdasarkan tag.
- metadata: satu objek JSON arbitrer, hingga 2 KB saat diserialisasi, untuk konteks per pengiriman yang tidak Anda perlukan sebagai dimensi filter (ID pesanan internal, referensi sesi).
Contoh kode
{
"tags": [{ "name": "campaign", "value": "order-confirmations" }],
"metadata": { "order_id": "ord_8271" }
}Referensi field
| Field | Tipe | Wajib | Batasan / catatan |
|---|---|---|---|
| to | string | ya | Satu penerima per pesan: nomor telepon E.164, business-scoped user ID yang tidak diterima template one-time-passcode, atau WhatsApp group ID (wag_…) yang mengirim ke setiap peserta grup |
| from | string (E.164) | no** | Abaikan untuk template yang dikelola Bird, yang memilih pengirimnya sendiri, dan untuk pengiriman grup, yang menggunakan nomor grup itu sendiri; wajib untuk service message dan template yang dibuat workspace Anda, dan harus nomor yang dimiliki workspace Anda |
| template.slug | string | no** | Slug template yang dapat dikirim workspace Anda; slug yang dikelola Bird diawali dengan bird_ |
| template.language | string | no* | Tag bahasa template (en, pt-BR); abaikan untuk mengirim bahasa default template |
| template.components | array | no | Mengisi variabel template; type komponen adalah body atau button |
| template.components[].parameters[].name | string | no† | Placeholder yang diisi nilai ini, misalnya ref; wajib dan harus cocok dengan nama yang dideklarasikan template untuk template parameter bernama, diabaikan untuk template posisional |
| interactive | object | no** | Teks body ditambah satu tipe konten yang dapat diketuk; merupakan service message, jadi memerlukan service window yang terbuka. Lihat Pesan interaktif |
| in_reply_to_message_id | string | no | Message ID WhatsApp yang dimiliki workspace ini, dikutip dalam pesan yang Anda kirim; dikembalikan saat dibaca. Lihat Mengutip pesan |
| tags | array | no | Hingga 20 label {name, value}; nama ≤ 32 karakter, nilai ≤ 64, nama unik |
| metadata | object | no | JSON arbitrer, hingga 2 KB saat diserialisasi |
* language bersifat opsional; mengabaikannya mengirim bahasa default template.
† name wajib pada setiap parameter untuk template parameter bernama. Abaikan untuk template posisional. Lihat Komponen dan parameter.
** Sertakan tepat satu dari template atau field konten service message (text, image, video, audio, sticker, document, location, interactive); lihat Service message.
Model async: arti 202
Pengiriman yang berhasil mengembalikan 202 Accepted dengan message ID dan status: accepted. 202 dikembalikan hanya setelah pengiriman diterima secara durable; pengiriman tidak pernah diterima lalu diam-diam dihapus. Kegagalan fatal yang dapat Anda perbaiki langsung gagal dengan 422: penerima tidak valid, slug atau bahasa template tidak dikenal, parameter tidak cocok, atau service message dikirim ke customer service window yang tertutup (WhatsAppServiceWindowClosed). Wallet tanpa dana bukan salah satunya: pengiriman diterima, dan pesan berakhir rejected dengan insufficient_balance begitu Bird mencoba menagihnya. Pengiriman aktual terjadi secara asinkron: pesan berpindah ke sent saat kami menyerahkannya ke WhatsApp, lalu ke status terminal (delivered atau failed) saat tanda terima tiba, dilaporkan melalui event, webhook, dan endpoint baca. Tanda terima baca dimunculkan secara terpisah sebagai timestamp read_at dan event whatsapp.read, bukan sebagai status.
Satu catatan privasi: untuk template kategori authentication, API tidak pernah mengembalikan nilai yang telah diisi. Echo 202 dan setiap pembacaan berikutnya membawa array components kosong untuk pesan-pesan tersebut, sehingga kode verifikasi tidak pernah muncul kembali.
Mencoba lagi dengan aman
Kirim header Idempotency-Key dengan nilai unik per pengiriman logis, dan percobaan ulang menjadi aman. Jika permintaan pertama Anda berhasil tetapi Anda tidak melihat responsnya (timeout, koneksi terputus), mengulangnya dengan kunci yang sama mengembalikan hasil asli alih-alih mengirim, dan menagih, pesan duplikat. Respons yang diulang membawa header Idempotency-Replay. Lihat idempotency untuk format kunci dan retensi.
Menerima balasan
Pesan masuk mendarat di resource yang sama dengan pesan keluar, dan setiap pesan masuk mereset service window. Menerima pesan WhatsApp membahas cara membacanya melalui API, mengambil media yang dikirim kontak, dan webhook whatsapp.received.
Biaya dan penagihan
WhatsApp dikenakan biaya per pesan, berdasarkan kategori template dan negara penerima; lihat Harga WhatsApp. Pesan ditagih dalam dua langkah, pada dua momen berbeda, dan objek cost pada pesan melaporkan keduanya:
| Field | Keterangan | Kapan tersedia |
|---|---|---|
| transaction_amount | Biaya Bird untuk menangani pengiriman | Saat Bird memproses pengiriman yang diterima, sebelum dispatch |
| passthrough_amount | Bagian Meta dari harga pesan, yang diteruskan Bird | Saat tanda terima delivered atau read yang berlaku tiba |
| amount | Jumlah komponen yang sudah dihargai sejauh ini | Bertambah seiring setiap komponen tersedia |
| currency_code | Mata uang wallet organisasi Anda, dipakai oleh kedua komponen | Bersama komponen pertama |
Kedua jumlah berupa string desimal, sebelum pajak.
Note: a service message carries no Meta share until September 30th 2026, and neither does a utility template delivered inside an open customer service window. From October 1st 2026 Meta charges for both, except inside a 72-hour free entry point window, and with 1,000 free service messages per business phone number per month: October 2026 pricing changes.
Kedua komponen dihargai berdasarkan input berbeda. Biaya Bird menggunakan kategori template yang Anda kirim dan negara penerima, yang berasal dari kode negara nomor telepon atau, pada pengiriman ke business-scoped user ID, dari prefiks dua huruf pada ID tersebut. Bagian Meta menggunakan kategori yang dilaporkan Meta sendiri pada tanda terima yang berlaku, yang bisa berbeda dari kategori template: Meta dapat melaporkan authentication-international ketika aturan tujuan, lokasi bisnis, dan kelayakannya berlaku. Lihat Tarif authentication-international WhatsApp.
Apa yang dibaca cost bergantung pada seberapa jauh pesan telah berjalan:
- Pada 202, cost bernilai null. Belum ada yang dihargai.
- Setelah pemrosesan, transaction_amount terisi dan amount sama dengannya. passthrough_amount tetap null.
- Setelah tanda terima delivered atau read yang berlaku, biaya Meta yang berhasil dicatat mengisi passthrough_amount, dan amount mencerminkan komponen yang tercatat.
Komponen null berarti tidak ada jumlah yang tercatat dalam proyeksi tersebut; ini bukan bukti bahwa pesan itu gratis. Komponen yang secara eksplisit dihargai nol terbaca "0.00000".
Kedua tagihan juga gagal secara berbeda. Biaya Bird gagal secara tertutup: ketika tidak dapat diproses setelah 202 karena wallet tidak mencukupi untuk pengiriman atau rute tidak memiliki harga yang dikonfigurasi, pesan berakhir rejected dengan kode error insufficient_balance atau price_not_found, dan tidak ada yang ditagih. Pesan rejected tidak pernah sampai ke WhatsApp, dan inilah yang membedakannya dari failed. Bagian Meta gagal secara terbuka: jika wallet kurang atau tarif tidak tersedia saat tanda terima tiba, tagihan dilewati tanpa membalikkan status pesan yang teramati. Pengiriman Anda tidak pernah ditahan oleh tagihan kedua.
Pesan yang ditagih oleh Bird mempertahankan tagihan keluar tersebut jika pengiriman kemudian gagal. Biaya Meta diproses dari callback delivered atau read yang berlaku ketika Meta melaporkan harga reguler dengan kategori dan tujuan yang dapat diselesaikan. Kedua jalur callback menggunakan identitas biaya yang sama dan mengandalkan deduplikasi layanan penagihan. Rekonsiliasi tanda terima yang diulang terhadap catatan penagihan, jangan perlakukan proyeksi pesan sebagai bukti debit permanen. Harga service atau free-entry dapat membuat komponen Meta menjadi nol; komponen yang belum diselesaikan bukan bukti bahwa pesan itu gratis.
Gunakan buku besar penagihan untuk rekonsiliasi keuangan. Field cost pada pesan adalah proyeksi tagihan dan bisa tertinggal atau tetap tidak lengkap. Lihat Metrik WhatsApp untuk perbedaan antara observasi pesan dan catatan penagihan.
Event WhatsApp tidak membawa biaya. Untuk membaca salah satu komponen, baca kembali pesan dengan GET /v1/whatsapp/messages/{id}.
Langkah berikutnya
- Service message: sembilan jenis konten free-form dan apa yang diterima masing-masing
- Menerima pesan WhatsApp: pesan masuk, media, dan webhook whatsapp.received
- Business-scoped user ID: menjangkau kontak yang menghubungi Anda tanpa nomor telepon
- Templates: telusuri katalog dan baca variabel template
- Mengirim ke grup WhatsApp: menjangkau grup dan membaca tanda terima per peserta
- Idempotency: percobaan ulang yang aman dengan header Idempotency-Key
Sumber daya terkait
Lanjutkan dengan dokumentasi, panduan, dan contoh untuk topik ini. Sumber daya tersedia dalam bahasa Inggris.
Tonton panduannyaConnecting WhatsApp to Bird: from buying a number to a live channelPahami konsepnyaWhat is the 24-hour customer service window on WhatsApp?Gunakan alatnyaWhatsApp message builderJelajahi kemampuannyaWhatsApp
Coba praktiknya dan dapatkan ringkasan implementasi