Membedah lapisan protokol A2A: lima metode inti JSON-RPC mulai dari message/send, tasks/get, tasks/cancel, tasks/pushNotificationConfig, hingga messages/list, lengkap dengan praktik binding HTTP POST dan endpoint SSE untuk streaming.

Di episode 4 kita memahami Task dan Message sebagai model data. Sekarang saatnya melihat bagaimana model itu dipanggil: metode JSON-RPC yang tersedia dan cara metode tersebut melekat pada HTTP.
Episode 5 adalah episode paling "protocol-heavy" sejauh ini. Kalian akan menghafal lima metode inti, lalu mempraktikkannya langsung dengan curl ke server A2A. Setelah episode ini, kalian bisa menelusuri traffic A2A seperti membaca buku.
A2A memakai JSON-RPC 2.0 sebagai bahasa pemanggilan. Setiap request berbentuk object dengan tiga field wajib:
{
"jsonrpc": "2.0",
"id": "call-001",
"method": "message/send",
"params": {
"message": {
"role": "user",
"parts": [{ "text": "Halo" }]
}
}
}jsonrpc — selalu bernilai 2.0.id — penanda unik request; respons mengembalikan id yang sama sehingga client bisa mencocokkan.method — nama metode yang dipanggil.params — argumen metode; bentuknya spesifik per metode.Berbeda dengan REST yang punya banyak endpoint per resource, JSON-RPC cukup memakai satu endpoint dengan method yang berbeda di dalam body. Kesederhanaan inilah yang membuat binding lintas transport (HTTP, gRPC, SSE) menjadi mungkin.
Metode paling penting — dipakai untuk mengirim pesan pertama sekaligus membuat task baru. Jika params.taskId tidak ada, remote agent membuat task baru dan mengembalikan id-nya.
curl -s -X POST https://analisis.example.com \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":"1","method":"message/send","params":{"message":{"role":"user","parts":[{"text":"Analisis laporan ini"}]}}}'Responsnya membawa object task lengkap dengan id dan status awal:
{
"jsonrpc": "2.0",
"id": "1",
"result": {
"id": "task-7f3a",
"status": { "state": "submitted" }
}
}Dari respons inilah client mendapatkan taskId yang akan dipakai di semua metode berikutnya.
Untuk mengambil kondisi terkini sebuah task — termasuk riwayat message — client memanggil tasks/get dengan taskId. Metode ini esensial untuk pola polling saat streaming tidak tersedia.
{
"jsonrpc": "2.0",
"id": "2",
"method": "tasks/get",
"params": {
"taskId": "task-7f3a",
"historyLength": 10
}
}Parameter historyLength membatasi jumlah message yang dikembalikan. Untuk task dengan percakapan panjang, ini mencegah payload membengkak.
Ketika task sudah tidak relevan — misalnya kebutuhan berubah di tengah jalan — client membatalkannya dengan tasks/cancel:
{
"jsonrpc": "2.0",
"id": "3",
"method": "tasks/cancel",
"params": {
"taskId": "task-7f3a"
}
}Pembatalan mengubah status task menjadi canceled. Remote agent yang baik akan menghentikan pekerjaan yang sedang berjalan dan mengembalikan sumber dayanya.
Metode ini mengubah mode komunikasi dari client menarik (polling) menjadi agent mendorong (push). Client mendaftarkan URL webhook yang akan dipanggil remote agent saat ada pembaruan task:
{
"jsonrpc": "2.0",
"id": "4",
"method": "tasks/pushNotificationConfig",
"params": {
"taskId": "task-7f3a",
"pushNotificationConfig": {
"url": "https://client.example.com/hooks/a2a"
}
}
}Setelah terdaftar, remote agent mengirim notifikasi ke URL tersebut setiap kali status task berubah — tanpa menunggu client bertanya. Detail lengkap streaming dan push, termasuk retry dan fallback polling, akan kita dalami di episode 7.
Riwayat lengkap percakapan sebuah task bisa diambil dengan messages/list. Berbeda dengan tasks/get yang membawa snapshot status, metode ini fokus pada seluruh message:
{
"jsonrpc": "2.0",
"id": "5",
"method": "messages/list",
"params": {
"taskId": "task-7f3a"
}
}Responsnya berupa array message berurutan — dari pesan pertama user sampai pesan terakhir agent. Metode ini berguna untuk membangun ulang konteks percakapan dari nol, misalnya saat client baru bergabung ke task yang sudah berjalan lama.
Seluruh metode di atas diangkut lewat POST ke satu endpoint — biasanya URL yang tercantum di Agent Card. Ringkasannya:
POST https://analisis.example.com -> semua metode JSON-RPC
GET https://analisis.example.com/.well-known/agent-card, /sseAturan mainnya konsisten dengan spesifikasi HTTP: header Content-Type: application/json, body berupa request JSON-RPC, dan respons dikembalikan dengan status 200 selama request valid — bahkan saat task gagal, karena kegagalan dibawa di dalam body JSON-RPC, bukan kode HTTP.
Warning
Jangan biasakan mengandalkan kode status HTTP untuk menilai hasil task. Kode 200 hanya berarti "request diterima dan diproses", bukan "task selesai sukses". Untuk itu, baca result.status.state di dalam body respons.
Jika Agent Card mendeklarasikan streaming: true, client bisa membuka kanal SSE untuk menerima pembaruan task secara real-time:
curl -s -N https://analisis.example.com/sse?taskId=task-7f3aevent: task_update
data: {"state":"working","message":{"role":"agent","parts":[{"text":"Menganalisis..."}]}}
event: task_update
data: {"state":"completed","message":{"role":"agent","parts":[{"text":"Selesai!"}]}}Setiap event membawa delta message atau perubahan status. Coba langsung di terminal dengan curl -s -N https://analisis.example.com/sse?taskId=task-7f3a. Client menutup kanal setelah menerima status terminal (completed, failed, atau canceled). Kombinasi POST untuk request dan SSE untuk notifikasi inilah yang disebut binding HTTP+SSE.
Inilah inti yang harus dibawa pulang:
jsonrpc, id, method, dan params.message/send membuat task dan mengirim pesan pertama.tasks/get dan tasks/cancel mengelola task: membaca kondisi dan membatalkan.tasks/pushNotificationConfig mendaftarkan webhook agar agent mendorong pembaruan.messages/list mengambil riwayat lengkap percakapan.Di episode 6 kita turun dari teori ke praktik nyata: SDK Python & TypeScript — memasang a2a-sdk Python dan @a2a-js/sdk TypeScript, menulis handler task dengan dekorator, dan menjalankan agent A2A pertama kalian. Sampai jumpa!