Dokumentasi Developer

Hubungkan software Anda sendiri ke inbox SyBox

Kirim pesan WhatsApp dari nomor Anda sendiri, tampilkan data pelanggan Anda di samping setiap chat, ajukan kasus, terima setiap peristiwa di server Anda sendiri, dan pasang live chat di situs web Anda. Rute pengiriman menggunakan format WhatsApp Cloud API, jadi kode yang ditulis untuk Meta hanya perlu base URL baru dan kunci SyBox.

Base URLhttps://api.sybox.io

Memulai

Panduan Cepat

Cukup tiga hal dan pesan pertama Anda langsung terkirim: base URL, device key, dan endpoint pesan.

POST/v26.0/{phone-number-id}/messagesAuthorization: Bearer <DEVICE_KEY>

Segmen versi diterima dalam format v<n> apa pun (v26.0, v1.0, ...) — gunakan saja apa yang sudah dipakai kode Anda saat ini. {phone-number-id} adalah ID nomor WhatsApp Anda, sama persis seperti di Meta.

{phone-number-id} ditampilkan setelah id pada kartu nomor di Pengaturan › Pesan › Saluran. Kunci pengiriman terikat pada satu nomor dan hanya mengirim dari nomor tersebut.

cURL
curl -X POST https://api.sybox.io/v26.0/PHONE_NUMBER_ID/messages \
  -H "Authorization: Bearer YOUR_DEVICE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messaging_product": "whatsapp",
    "to": "15551234567",
    "type": "text",
    "text": { "body": "Hello from SyBox" }
  }'

Kartu setiap kunci di Pengaturan › Integrasi › Kunci API menampilkan kapan terakhir kali kunci itu dipakai — cara tercepat untuk melihat apakah panggilan Anda sampai.

Memulai

Autentikasi dan kunci

Setiap panggilan membawa kunci di header Authorization sebagai Bearer token. Setiap kunci punya satu tugas: kunci yang dibuat untuk mengirim tidak dapat mengajukan kasus, dan kunci yang dibuat untuk mengajukan kasus tidak dapat mengirim. Simpan setiap kunci di server Anda — satu-satunya pengecualian adalah kunci publik Live Chat, yang memang dibuat untuk dipasang di halaman Anda.

HTTP
Authorization: Bearer YOUR_KEY
Content-Type: application/json
KunciKegunaannya
Kirim melalui WhatsAppPOST /v{n}/{phone-number-id}/messages
Buat kasusPOST /v1/case
Mulai otomatisasiPOST /v1/automation
Baca dan perbarui kontakPOST /v1/contacts/…
Terima dari programPOST /v1/inbound
Kunci publik · lcpk_<script … data-key="lcpk_…">
Kunci penandatanganan untuk pengguna yang telah masuk · lcid_Pengguna yang telah masuk: kunci penandatanganan
Kunci server (untuk layar chat Anda sendiri) · lcsk_/v1/livechat/*
Kunci tanda tangan balasan · lcwh_x-sybox-signature
Signing secretX-Hub-Signature-256

Memulai

Mendapatkan device key

Device key dibuat di dalam ruang kerja Anda dan sudah memuat rute tujuannya sendiri — tidak memerlukan subdomain atau ID akun di dalam request.

  1. Buka ruang kerja Anda → Pengaturan → API keys lalu buat device key baru.
  2. Setiap key terikat pada satu nomor dan dapat dicabut kapan saja.
  3. Token WhatsApp asli Anda tidak pernah keluar dari server kami — device key berfungsi sebagai penggantinya.
  4. Gateway dinonaktifkan secara default; mengaktifkan akses API pada ruang kerja akan menyalakannya.

WhatsApp API

Kirim pesan pertama Anda

Pesan teks biasa. Bagian body menggunakan payload standar Cloud API — kami meneruskannya langsung ke Meta tanpa perubahan apa pun.

POST/v26.0/{phone-number-id}/messagesAuthorization: Bearer <DEVICE_KEY>
curl -X POST https://api.sybox.io/v26.0/PHONE_NUMBER_ID/messages \
  -H "Authorization: Bearer YOUR_DEVICE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messaging_product": "whatsapp",
    "to": "15551234567",
    "type": "text",
    "text": { "body": "Hello from SyBox" }
  }'

Respons

Anda menerima respons persis seperti yang dikembalikan Meta, lengkap dengan kode status HTTP yang sama — sehingga library client Cloud API yang ada dapat memprosesnya tanpa perubahan.

200 OK · application/json
{
  "messaging_product": "whatsapp",
  "contacts": [{ "input": "15551234567", "wa_id": "15551234567" }],
  "messages": [{ "id": "wamid.HBgLMTU1NTEyMzQ1NjcVAgARGBI…" }]
}

WhatsApp API

Semua jenis pesan didukung

Karena bagian body diteruskan tanpa perubahan, semua jenis pesan Cloud API didukung penuh — template, gambar, dokumen, hingga pesan interaktif. Berikut adalah contoh pengiriman template.

{
  "messaging_product": "whatsapp",
  "to": "15551234567",
  "type": "template",
  "template": {
    "name": "order_shipped",
    "language": { "code": "en_US" },
    "components": [{
      "type": "body",
      "parameters": [{ "type": "text", "text": "#10432" }]
    }]
  }
}

Teks bebas hanya sampai ke pelanggan dalam 24 jam sejak pesan terakhir mereka. Di luar jendela itu, kirim template yang sudah disetujui: SyBox menolak teks bebas di sana dengan kode 131047 sebelum sampai ke Meta.

WhatsApp API

Aturan dan batas kunci

Setiap kunci pengiriman memiliki aturannya sendiri, yang ditetapkan saat Anda membuatnya: teks bebas, template, atau keduanya; media atau tidak; template mana; negara penerima mana; jam pengiriman yang diizinkan; dan batas harian. Pengiriman yang melanggar salah satunya ditolak oleh SyBox sebelum sampai ke Meta.

StatusKapan
404Jawaban kosong: Gateway API dinonaktifkan, atau kunci tidak terhubung ke workspace mana pun. Periksa sakelar di bagian atas Pengaturan › Integrasi › Kunci API.
401Kunci tidak ada atau tidak dikenal.
403Kunci ini bukan kunci pengiriman, atau mengirim dari nomor yang tidak terhubung dengannya.
403Pesan melanggar salah satu aturan kunci: teks bebas, template, media, nama template, negara, atau jam.
403Meta telah menjeda template ini, atau membatasinya karena peringkat kualitasnya.
400Jendela 24 jam sudah tertutup (kode 131047): kirim template sebagai gantinya.
400Body bukan JSON yang valid, atau nomor WhatsApp milik kunci ini sudah tidak terhubung.
409Meta untuk sementara menghentikan pengiriman dari nomor ini.
429Batas harian kunci, atau batas pengiriman pesan WhatsApp nomor ini, sudah tercapai.
502Meta tidak dapat dihubungi. Coba lagi.

Hitungan harian dimulai lagi pada tengah malam UTC, dan pengiriman yang gagal tidak dihitung.

WhatsApp API

Error

Error berasal dari dua tempat, dan keduanya memakai bentuk error Meta, sehingga klien Cloud API yang sudah ada dapat membacanya tanpa perubahan. Error dari Meta dikembalikan persis seperti yang dikirim Meta, dengan kode status Meta. Error dari salah satu aturan SyBox sendiri memiliki type SyBoxGatewayError, dan message-nya menyebutkan aturan mana yang menolak panggilan tersebut.

{
  "error": {
    "message": "(#131030) Recipient phone number not in allowed list",
    "type": "OAuthException",
    "code": 131030
  }
}

Sistem Anda di SyBox

Tampilkan data Anda di samping chat

Saat agen membuka percakapan, SyBox memanggil endpoint ANDA dan menampilkan data yang Anda kirim tepat di samping chat — pesanan pelanggan, saldo, tiket. Kami mengirim nomor ponsel pelanggan, atau email pelanggan untuk percakapan email.

Tambahkan endpoint Anda di Pengaturan › Integrasi › API ERP. Setiap panggilan adalah POST dengan kunci Anda di Authorization dan permintaan dalam satu kolom, data, berisi string JSON — sehingga kedua pihak dapat menambahkan kolom nanti tanpa merusak pihak lain. Jawab dalam 15 detik.

POST YOUR_ERP_URL
Authorization: Bearer YOUR_ERP_KEY
X-Sybox-Action: lookup
X-Sybox-Lang: en
X-Sybox-Theme: light
X-Sybox-Agent: 6f1c…
X-Sybox-Number: 104857600000000
Content-Type: application/json

{ "data": "{\"phone\":\"15551234567\",\"email\":\"customer@example.com\",\"ref\":\"\"}" }

Setiap panggilan juga menyebutkan siapa yang bertanya: X-Sybox-Lang (bahasa pengguna — jawab dalam bahasa tersebut), X-Sybox-Theme (light atau dark, untuk balasan html), X-Sybox-Agent (id pengguna), dan X-Sybox-Number (nomor tempat percakapan berlangsung).

Kami mengirim nomor ponsel dan email — salah satunya bisa saja kosong. Cocokkan dengan data pengenal pelanggan di sistem Anda, lalu balas dengan { renderAs, content }.

renderAs

Atur renderAs untuk memberi tahu SyBox cara menampilkan konten Anda — salah satu dari:

renderAsDeskripsi
tableBaris dan kolom. content adalah array berisi objek datar (atau { rows: [ … ] }); kunci-kuncinya menjadi judul kolom.
cards · kpiUbin kecil, seperti saldo atau jumlah pesanan. content adalah array berisi { label, value } (atau { cards: [ … ] }).
feed · list · threadLinimasa berisi kartu. content adalah array berisi { title, text, date, tags, media: [{ type, url, name }] }.
messageSatu catatan yang ditata sebagai satu kartu bergaya pesan.
htmlHTML Anda sendiri, sebagai string di content. Hanya untuk markup yang Anda buat sendiri.
sectionsBeberapa blok dalam satu balasan: content adalah { sections: [ { title, renderAs, content } ] }.
jsonBawaan jika renderAs tidak diisi: SyBox menampilkan content Anda sebagai JSON yang diformat.

Tambahkan sybox_ref ke baris tabel atau kartu mana pun agar bisa diklik — SyBox akan memanggil endpoint Anda kembali dengan ref tersebut agar Anda dapat menampilkan detail data tersebut.

Pencarian produk (X-Sybox-Action: products)

Endpoint yang sama juga dapat merespons pencarian produk. Pengguna mengetik apa yang dicari pelanggan, SyBox mengirimkannya sebagai "q", dan balasan Anda ditampilkan sebagai kartu produk di samping obrolan — dengan sekali ketuk Kirim yang memasukkan tautan produk ke editor pesan.

POST YOUR_ERP_URL
Authorization: Bearer YOUR_ERP_KEY
X-Sybox-Action: products

# the decoded "data":
{ "q": "wireless keyboard", "phone": "15551234567", "email": "customer@example.com", "ref": "" }
KolomDeskripsi
namewajibSatu-satunya kolom wajib. Produk yang hanya memiliki nama tetap akan tampil rapi sebagai kartu.
price · oldPrice · currencyGunakan angka, bukan string terformat. Kirim oldPrice hanya jika memang ada harga sebelumnya — persentase diskon akan dihitung otomatis dari kedua harga tersebut.
available · stockavailable bernilai true/false; stock adalah jumlah opsional yang ditampilkan di sampingnya. Abaikan kedua kolom ini jika Anda tidak melacak stok — kolom yang tidak ada tidak akan menampilkan apa pun dan tidak pernah dianggap habis stok.
imageURL gambar langsung dengan protokol https. Gambar apa pun yang gagal dimuat akan digantikan dengan placeholder netral.
linkURL halaman produk. Tanpa URL ini kartu hanya dapat dilihat (read-only) — tombol Kirim ke chat hanya muncul jika ada link untuk dikirim.
noteSatu baris teks singkat di bawah harga — waktu pengiriman, varian, atau kondisi barang.

Cukup gunakan endpoint yang sudah Anda buat: URL yang sama, key yang sama, struktur { "data": "…" } yang sama. Periksa X-Sybox-Action untuk membedakan antara pencarian produk dan pencarian pelanggan. Berikan respons berupa content sebagai array biasa (atau { items: [ … ] }).

Sistem Anda di SyBox

Buat tiket kasus dari sistem Anda sendiri

Ini adalah rute yang digunakan sistem ERP atau akuntansi. Program Anda tidak mengirimkan pesan keluhan terformat — melainkan meminta SyBox untuk membuka kasus. Satu catatan, satu tempat, satu nomor referensi yang dapat diberikan staf Anda kepada pelanggan.

POST/v1/caseAuthorization: Bearer <CASE_KEY>
curl -X POST https://api.sybox.io/v1/case \
  -H "Authorization: Bearer $SYBOX_CASE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_unique_id": "CUST-10432",
    "header": "Screen replacement not delivered",
    "description": "Paid on 12 Aug, promised in 3 days, still nothing.",
    "department_id": 5,
    "ext_ref": "TICKET-99817"
  }'

Kolom data

KolomDeskripsi
customer_unique_idId Anda sendiri untuk pelanggan — kunci yang sama dengan yang dipakai sinkronisasi pelanggan. Kirim phone sebagai gantinya jika Anda tidak punya id.
phoneNomor telepon pelanggan, jika Anda tidak punya id.
header · descriptionSetidaknya satu diperlukan. Header adalah baris yang dilihat pengguna dalam daftar.
department_idwajibintegerWajib. Departemen tempat kasus diajukan: nomor yang ditampilkan di sampingnya dalam Pengaturan › Departemen (misalnya #5).
ext_refNomor tiket Anda. Sertakan nomor ini. Permintaan ulang dengan ext_ref yang sama akan mengembalikan kasus yang sudah ada daripada membuat tiket ganda — sehingga panggilan API aman diulang setelah batas waktu (timeout).
sectioninteger1 sampai 4: tab kasus tempat kasus ini masuk. Bawaan 1.
deadlinestringTanggal jatuh tempo, YYYY-MM-DD.
notifybooleanBawaan true: catatan berisi nomor kasus muncul di percakapan pelanggan di SyBox. Tidak ada yang dikirim ke pelanggan. false menghilangkannya.
sourcestringNama program yang ditampilkan pada catatan tersebut. Bawaan ERP.

Jawabannya memuat nomor kasus, yaitu nomor yang disebutkan staf Anda kepada pelanggan. Percobaan ulang dengan ext_ref yang sama menjawab "duplicate": true beserta kasus yang sudah ada, tanpa customer_id.

Pelanggan harus sudah ada di SyBox. Jika id tidak ditemukan, SyBox menjalankan satu kali sinkronisasi pelanggan dengan sistem Anda lalu mencarinya lagi; jika masih tidak ditemukan, jawabannya 404 — kasus tidak pernah dibuat untuk pelanggan rekaan.

Gunakan key dengan jenis 'case'. Relay key (yang digunakan untuk mengirim pesan) akan ditolak di sini dengan kode status 403 demi keamanan: key yang dapat mengirim pesan ke pelanggan tidak boleh memiliki akses untuk membuka data di CRM Anda.

Sistem Anda di SyBox

Kirim pesan masuk dari program lain

Untuk pesan di luar WhatsApp: catatan dari kasir/POS, peringatan dari perangkat, atau pesan dari sistem lama. Pesan ini masuk ke percakapan yang tepat berdasarkan nomor ponsel, dan ditandai dengan nama program pengirimnya.

POST/v1/inboundAuthorization: Bearer <INBOUND_KEY>

Kunci jenis ini tidak dibuat lagi: kunci Terima dari program yang sudah ada tetap berfungsi. Untuk integrasi baru, ajukan kasus — SyBox menuliskan catatannya ke dalam percakapan untuk Anda.

cURL
curl -X POST https://api.sybox.io/v1/inbound \
  -H "Authorization: Bearer $SYBOX_INBOUND_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "15551234567",
    "text": "Order 4821 has left the warehouse.",
    "source": "Warehouse"
  }'
KolomDeskripsi
phonewajibstringNomor telepon pelanggan, dengan kode negara.
textwajibstringPesannya.
sourcestringNama program, yang ditampilkan pada pesan.

Jawabannya adalah {"ok": 1, "id": …}, yaitu id catatan di dalam percakapan.

Dirancang khusus hanya untuk pesan masuk. Rute ini mencatat pesan ke dalam percakapan dan tidak mengirim apa pun ke pelanggan. Gunakan rute pengiriman pesan di atas untuk mengirim pesan ke pelanggan.

Sistem Anda di SyBox

Kontak: baca dan perbarui

Dengan kunci bertipe Baca dan perbarui kontak, program dapat mencari kontak, membacanya, serta mengubah nama, email, kolom kontak, dan labelnya. Setiap panggilan adalah POST dengan isi JSON.

Kunci ini bertindak sebagai orang yang membuatnya: kunci hanya menemukan kontak yang boleh dilihat orang tersebut, dan hanya jika orang tersebut boleh membuka daftar kontak serta melihat nomor. Untuk mengubah apa pun, orang tersebut harus diizinkan mengedit kontak. Kunci yang pembuatnya dinonaktifkan akan berhenti berfungsi.

POST/v1/contacts/searchAuthorization: Bearer <CONTACTS_KEY>

Mencari kontak yang nama, telepon, atau emailnya mengandung q. limit secara default adalah 20, paling banyak 50.

POST/v1/contacts/get

Satu kontak, berdasarkan phone atau key (contact.key yang sama yang dikirim webhook).

POST/v1/contacts/update

Mengubah hanya apa yang Anda kirim: name, email, dan fields (kolom kontak berdasarkan id atau nama, beserta nilainya; nilai kosong akan menghapus isinya).

POST/v1/contacts/labels

Menambahkan dan menghapus label berdasarkan id atau nama: add dan remove adalah daftar.

curl -X POST https://api.sybox.io/v1/contacts/update \
  -H "Authorization: Bearer $SYBOX_CONTACTS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "201112223344",
    "name": "Sara Ali",
    "fields": { "city": "Alexandria" }
  }'

# Find:   POST /v1/contacts/search  {"q": "sara", "limit": 20}
# Read:   POST /v1/contacts/get     {"phone": "201112223344"}
# Labels: POST /v1/contacts/labels  {"phone": "201112223344", "add": ["VIP"], "remove": [7]}

Setiap panggilan menjawab dengan kontak (search: daftar kontak): key, name, phone, email, channel, labels, dan fields.

Peristiwa

Webhook: peristiwa di server Anda

Tambahkan endpoint Anda di Pengaturan › Integrasi › Webhook, pilih peristiwa dan nomornya, lalu SyBox mengirim POST setiap peristiwa ke sana saat terjadi. Peristiwa WhatsApp tiba dalam format webhook Meta sendiri, sehingga handler yang ditulis untuk Meta bekerja tanpa perubahan.

PeristiwaDeskripsi
messagePesan masukPesan dari pelanggan.
statusStatus pesanTerkirim, diterima, dibaca, atau gagal — untuk pesan yang Anda kirim.
reactionReaksiPelanggan memberi reaksi pada sebuah pesan.
donePercakapan ditandai selesaiPercakapan ditandai selesai: oleh seseorang, oleh otomatisasi, atau dengan sendirinya setelah pelanggan tidak membalas.
labelLabel ditambahkan atau dihapusLabel ditambahkan ke percakapan, atau dihapus darinya.
contactKontak dibuat atau diperbaruiKontak dibuat, atau nama, email, atau kolom kontaknya berubah.
dealKesepakatan ditutupKesepakatan yang ditutup dicatat dalam percakapan.
caseKasus CRM dibuka atau ditutupKasus CRM dibuka, atau ditutup (terselesaikan, tidak terselesaikan, atau dibatalkan).
Permintaan · SyBox → Anda
POST YOUR_WEBHOOK_URL
Content-Type: application/json
X-Hub-Signature-256: sha256=5d1f0c…
x-sybox-signature: sha256=5d1f0c…
x-sybox-event: message
x-sybox-timestamp: 1761400000

{
  "object": "whatsapp_business_account",
  "entry": [{
    "id": "WABA_ID",
    "changes": [{
      "field": "messages",
      "value": {
        "messaging_product": "whatsapp",
        "metadata": { "display_phone_number": "15550001111", "phone_number_id": "PHONE_NUMBER_ID" },
        "contacts": [{ "profile": { "name": "Sara" }, "wa_id": "15551234567" }],
        "messages": [{
          "from": "15551234567",
          "id": "wamid.HBgLMTU1NTEyMzQ1NjcVAgASGBQ…",
          "timestamp": "1761400000",
          "type": "text",
          "text": { "body": "Is my order shipped?" }
        }]
      }
    }]
  }]
}

Media. Tautan milik Meta memerlukan token Meta untuk dibuka, jadi SyBox menggantinya dengan tautan bertanda tangan ke salinan file milik SyBox sendiri, yang berlaku selama 24 jam. Pesan suara juga dapat membawa kata-katanya di sybox.transcription, jika webhook memintanya.

Saluran lain — Messenger, Instagram, Telegram, dan Live Chat — tiba dalam format SyBox sendiri, hanya untuk peristiwa pesan:

JSON
{
  "object": "sybox",
  "event": "message",
  "channel": "telegram",
  "line": "8123456789",
  "workspace": "yourworkspace",
  "contact": { "key": "tg:6423115118", "name": "Sara" },
  "message": {
    "id": "812345",
    "timestamp": 1761400000,
    "type": "image",
    "text": "",
    "caption": "The broken part",
    "media": { "url": "https://api.sybox.io/…", "mime": "image/jpeg" }
  }
}

Peristiwa percakapan tiba dalam format SyBox sendiri, untuk setiap saluran. event menyebutkan secara tepat apa yang terjadi:

Peristiwa<code>event</code>
Percakapan ditandai selesaiconversation.done
Label ditambahkan atau dihapuslabel.added · label.removed
Kontak dibuat atau diperbaruicontact.created · contact.updated
Kesepakatan ditutupdeal.closed
Kasus CRM dibuka atau ditutupcase.opened · case.closed
Peristiwa ujitest
{
  "object": "sybox",
  "event": "conversation.done",
  "channel": "whatsapp",
  "line": "201001234567",
  "workspace": "yourworkspace",
  "timestamp": 1761400000,
  "contact": {
    "key": "201112223344",
    "name": "Sara",
    "phone": "201112223344",
    "email": "",
    "channel": "whatsapp",
    "labels": [{ "id": 3, "name": "VIP" }],
    "fields": [{ "id": 2, "key": "city", "name": "City", "value": "Cairo" }]
  },
  "data": { "by": "Omar", "note": "Refund sent" }
}

Signing secret

HeaderDeskripsi
X-Hub-Signature-256sha256= diikuti HMAC-SHA256 heksadesimal dari body mentah, dengan kunci rahasia penandatanganan webhook — header dan metode yang sama dengan milik Meta.
x-sybox-signatureNilai yang sama, agar endpoint yang juga menerima panggilan dari Meta sendiri dapat membedakan panggilan kami.
x-sybox-eventApa yang terjadi: message, status, reaction, salah satu peristiwa percakapan di bawah ini (conversation.done, label.added…), atau test.
x-sybox-timestampWaktu pengirimannya, dalam detik Unix.
x-sybox-signature-rsaTanda tangan kedua: rsa-sha256= diikuti RSA-SHA256 (PKCS#1 v1.5) dalam base64 dari x-sybox-timestamp, sebuah titik, dan body mentah.
x-sybox-key-idKunci kami yang mana yang membuatnya. Kunci publiknya ada di https://api.sybox.io/.well-known/sybox-webhook-key.

Periksa tanda tangan pada byte mentah, sebelum Anda mem-parse-nya, dan bandingkan dalam waktu konstan:

const crypto = require('crypto');

// express.raw: the signature is over the bytes as sent, so read them before any JSON parser.
app.post('/sybox/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const sent = Buffer.from(req.get('X-Hub-Signature-256') || '');
  const want = Buffer.from('sha256=' + crypto
    .createHmac('sha256', process.env.SYBOX_WEBHOOK_SECRET)
    .update(req.body)
    .digest('hex'));
  if (sent.length !== want.length || !crypto.timingSafeEqual(sent, want)) return res.sendStatus(401);

  res.sendStatus(200);                       // answer first, then do the work
  const event = JSON.parse(req.body);
  const kind = req.get('x-sybox-event');     // message | status | reaction
});

Tidak ingin menyimpan kunci rahasia bersama di server Anda? Periksa x-sybox-signature-rsa dengan kunci publik kami sebagai gantinya. Dengan cara mana pun, tolak timestamp yang lebih dari lima menit.

Jawab dengan 2xx apa pun dalam 15 detik. Selain itu — error, waktu habis, atau pengalihan — akan dicoba lagi setelah 1, 2, 4, 8, 16, dan 32 menit, lalu dibuang. Satu peristiwa bisa tiba lebih dari sekali: gunakan id pesan untuk mengabaikan pengulangan. Alamatnya harus publik dan https.

Webhook yang gagal 20 kali berturut-turut selama lebih dari satu jam akan dinonaktifkan secara otomatis dan admin ruang kerja akan diberi tahu. Peristiwa yang menunggu disimpan selama 24 jam: aktifkan kembali untuk mengirimkannya.

Untuk menguji, tekan Kirim peristiwa uji pada kartu webhook. Pengiriman, pada kartu yang sama, menampilkan 50 pengiriman terakhir beserta jawaban server Anda, dan dapat mengirimkannya lagi.

Live Chat

Live Chat

Pasang chat di situs web Anda: pengunjung menulis di sana, tim Anda menjawab di SyBox. Tambahkan situs web di Pengaturan › Pesan › Saluran, pada kartu Live Chat; jendela yang terbuka, Kode untuk situs Anda, memberi Anda kode dan kunci di bawah ini. Ketiga kunci rahasia hanya ditampilkan satu kali.

KunciDiawali denganKegunaannya
Kunci publiklcpk_Dipasang di halaman Anda. Aman untuk dipublikasikan: kunci ini hanya menyebutkan situs web, dan chat hanya muncul di Alamat situs web Anda.
Kunci penandatanganan untuk pengguna yang telah masuklcid_Hanya di server Anda. Menandatangani setiap pengguna yang telah masuk, sehingga tidak ada yang bisa menulis atas nama orang lain.
Kunci server (untuk layar chat Anda sendiri)lcsk_Hanya di server Anda. Hanya untuk situs yang membuat layar chat sendiri, bukan memakai chat siap pakai.
Kunci tanda tangan balasanlcwh_Hanya di server Anda. Membuktikan bahwa balasan yang dikirim ke server Anda berasal dari SyBox.

Chat siap pakai hanya memerlukan kode. Kunci penandatanganan untuk situs yang memiliki akun pengguna; kunci server dan kunci tanda tangan balasan hanya untuk situs dengan layar chat sendiri.

Menonaktifkan situs web langsung menyembunyikan chat. Panggilan dari server Anda tetap diterima dan disimpan.

Tambahkan chat ke situs Anda

Tempel kode sekali di setiap halaman, tepat sebelum tag penutup body. Chat hanya muncul di alamat yang ada di Alamat situs web, dan warna, posisi, judul, serta sambutannya diatur di SyBox, bukan di kode.

HTML
<script async src="https://api.sybox.io/lc/w.js" data-key="lcpk_YOUR_PUBLIC_KEY"></script>

WordPress: unduh plugin kami dari jendela yang sama. Shopify: di aplikasi Shopify SyBox, aktifkan Live Chat di toko ini, lalu SyBox Live Chat di bawah Penyematan aplikasi — pelanggan yang telah masuk langsung dikenali tanpa langkah tambahan.

Pengguna yang telah masuk: kunci penandatanganan

Saat pengguna telah masuk ke situs Anda, server Anda memberi tahu chat siapa mereka dengan token singkat — JWT, HS256 — yang ditandatangani dengan kunci penandatanganan. Pengguna tersebut lalu memiliki satu percakapan atas namanya, di setiap perangkat, dan tidak ada yang bisa membukanya dengan mengetik id orang lain.

  1. Setelah pengguna masuk, server Anda membuat token dari klaim di bawah ini.
  2. Halaman meneruskannya ke chat sebagai identity, sebelum kode chat.
  3. Setelah pengguna masuk tanpa memuat ulang halaman, panggil SyBoxChat('identify', token) sebagai gantinya.
KolomDeskripsi
subwajibstringId pengguna Anda, hingga 120 karakter. Tidak boleh diawali dengan v_.
expwajibnumberWaktu kedaluwarsa, dalam detik Unix — tidak lebih dari satu hari ke depan. Sepuluh menit sudah tepat: token hanya dibaca saat chat dibuka.
namestringNama yang ditampilkan percakapan.
emailstringAlamat email pengguna.
phonestringNomor telepon pengguna.
picturestringAlamat https foto pengguna, hingga 500 karakter. SyBox menyimpan salinannya sendiri, dan mengambilnya lagi saat pengguna masuk berikutnya jika alamatnya berubah.
function b64url(string $s): string { return rtrim(strtr(base64_encode($s), '+/', '-_'), '='); }

$header  = b64url(json_encode(['alg' => 'HS256', 'typ' => 'JWT']));
$payload = b64url(json_encode([
    'sub'   => (string) $user->id,
    'name'  => $user->name,
    'email' => $user->email,
    'exp'   => time() + 600,          // ten minutes
]));
$signature = b64url(hash_hmac('sha256', "$header.$payload", getenv('SYBOX_LC_SIGNING_KEY'), true));
$token = "$header.$payload.$signature";
HTML
<script>
  window.SyBoxChatConfig = { identity: "TOKEN_FROM_YOUR_SERVER", locale: "en" };
</script>
<script async src="https://api.sybox.io/lc/w.js" data-key="lcpk_YOUR_PUBLIC_KEY"></script>

Buat token hanya di server Anda. Kunci penandatanganan di halaman web memungkinkan siapa pun menulis atas nama pengguna Anda mana pun. Dan jangan pernah menaruh id pengguna begitu saja di halaman sebagai pengganti token: itu memungkinkan siapa pun memilih percakapan siapa yang ingin dibaca.

Jika Hanya pengguna yang telah masuk di situs saya diaktifkan, pengunjung tanpa token tidak akan melihat chat.

Pengunjung yang sudah chat sebelum masuk akan ditanya sekali, di browser yang sama, apakah ingin melanjutkan percakapan itu dengan akunnya. Anda tidak perlu melakukan apa pun untuk ini.

Kendalikan chat dari halaman Anda

Kode chat menambahkan satu fungsi ke halaman Anda, SyBoxChat:

JavaScript
SyBoxChat('open');                       // open the chat
SyBoxChat('close');                      // close it
SyBoxChat('identify', token);            // after a sign-in without a page reload
SyBoxChat('locale', 'fr');               // the chat's language
SyBoxChat('on', 'message', function (m) {
  // a reply arrived
});
SyBoxChat('on', 'open', function () { /* the chat opened */ });
SyBoxChat('on', 'close', function () { /* the chat closed */ });

// Before the chat's code, every setting is optional:
window.SyBoxChatConfig = {
  identity: 'TOKEN_FROM_YOUR_SERVER',    // a signed-in user (see above)
  name: 'Sara', email: 'sara@example.com', // a visitor without an account: fills the form for them
  locale: 'ar',
  serviceWorker: 'auto'                   // 'auto' | '/your-sw.js' | 'site' | 'off'
};

Notifikasi setelah situs Anda ditutup

Selama halaman situs Anda terbuka, balasan muncul sebagai notifikasi dengan sendirinya. Untuk menjangkau pengunjung setelah situs Anda ditutup, browser memerlukan service worker di domain Anda sendiri: sajikan satu baris ini sebagai /sybox-lc-sw.js di root situs Anda, sebagai application/javascript.

/sybox-lc-sw.js
try { importScripts('https://api.sybox.io/lc/sw.js'); } catch (e) {}

Pilih mode di SyBox (Notifikasi saat situs web ditutup) atau di halaman dengan serviceWorker: "auto" (file di atas, bawaan), path milik Anda sendiri, "site" (letakkan baris yang sama di bagian atas service worker Anda sendiri), atau "off".

Chat tidak pernah menggantikan service worker yang sudah dimiliki situs Anda, dan file ini tidak memiliki fetch handler, sehingga tidak pernah melihat permintaan situs Anda. Plugin WordPress menyajikan file ini untuk Anda. Safari di iPhone tidak menampilkan notifikasi untuk situs web biasa.

Layar chat Anda sendiri: kunci server

Situs atau aplikasi dengan layar chat sendiri berkomunikasi dengan SyBox dari servernya, bukan memakai chat siap pakai. Setiap panggilan membawa Authorization: Bearer lcsk_…. Server Anda menyebut pengguna dengan id Anda sendiri, dan dipercaya untuk itu, karena server Anda memegang kuncinya.

PanggilanDeskripsi
POST /v1/livechat/messagesPengguna Anda menulis. client_id membuat percobaan ulang aman: id yang sama hanya disimpan sekali ("duplicate": 1).
POST /v1/livechat/uploadSebuah file, sebagai multipart form data: file, user_id, client_id. Hingga 16 MB: gambar, suara, video, PDF, teks, dan dokumen Office.
GET /v1/livechat/messages?user_id=&since=&before=&limit=Percakapan: pesan setelah since, dan agents_read_id, pesan terbaru dari pengguna Anda yang sudah dibaca agen.
POST /v1/livechat/readPengguna Anda telah membaca balasan hingga up_to.
POST /v1/livechat/editPengguna Anda mengedit pesannya sendiri, dalam 15 menit.
POST /v1/livechat/deletePengguna Anda menghapus pesannya sendiri untuk semua orang, dalam 24 jam.
POST /v1/livechat/reactReaksi pada pesan apa pun; emoji kosong akan menghapusnya.
POST /v1/livechat/typingPengguna Anda sedang mengetik: kirim on: 1 setiap beberapa detik dan on: 0 saat berhenti.
curl -X POST https://api.sybox.io/v1/livechat/messages \
  -H "Authorization: Bearer $SYBOX_LC_SERVER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "user":    { "id": "u42", "name": "Sara Ali", "email": "sara@example.com", "locale": "ar" },
    "message": { "client_id": "a1b2c3", "text": "Hi, is my order on its way?", "reply_to": "" }
  }'

Sebuah pesan, di riwayat dan di balasan:

JSON
{
  "id": 990,
  "guid": "b81d…",
  "dir": "out",                       // "in" = your user wrote it, "out" = your team
  "type": "image",                    // text | image | audio | video | file
  "text": "Here is the tracking page",
  "media": { "url": "https://api.sybox.io/…", "mime": "image/png", "name": "tracking.png", "w": 1080, "h": 720 },
                                       // a voice note or a video also has "secs"
  "status": 3,                         // on your user's messages: 1 received, 3 read by an agent
  "reply_to": "7c9e…",
  "client": "a1b2c3",                  // on your user's messages: the client_id you sent
  "react_us": "",                      // your team's reaction on it
  "react_me": "👍",                    // your user's reaction on it
  "at": "2026-10-25T09:41:07Z",
  "edited": 0
}

Riwayat pengguna yang belum pernah menulis menjawab 404 unknown_user: tampilkan percakapan kosong.

Tautan media bertanda tangan dan berlaku selama satu jam; minta lagi untuk mendapatkan yang baru. SyBox tidak pernah mengambil file dari alamat yang Anda kirim: unggah file tersebut. Hingga 120 panggilan per menit untuk setiap situs web.

Balasan di server Anda: kunci tanda tangan balasan

Isi Alamat server Anda untuk balasan pada situs web. Saat tim Anda membalas, mengedit, menghapus, atau membaca, SyBox mengirim POST peristiwa tersebut ke sana, ditandatangani dengan kunci tanda tangan balasan.

HeaderDeskripsi
x-sybox-signaturet=TIMESTAMP,v1=SIGNATURE — TIMESTAMP dalam detik Unix, SIGNATURE adalah HMAC-SHA256 dalam hex dari TIMESTAMP.BODY (body mentah), dengan kunci tanda tangan balasan sebagai kuncinya.
x-sybox-eventmessage.created, message.updated, message.deleted, atau messages.read.
x-sybox-deliverySama di setiap percobaan ulang untuk satu peristiwa: gunakan untuk mengabaikan pengulangan.

Body berisi event, line_id, user_id, dan message — atau message_id untuk penghapusan, dan read_id untuk messages.read: pesan pengguna Anda sudah dibaca hingga id tersebut.

const crypto = require('crypto');

app.post('/sybox/livechat', express.raw({ type: 'application/json' }), (req, res) => {
  const parts = Object.fromEntries((req.get('x-sybox-signature') || '').split(',').map(p => p.split('=')));
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > 300) return res.sendStatus(401);   // older than five minutes

  const want = Buffer.from(crypto.createHmac('sha256', process.env.SYBOX_LC_REPLY_KEY)
    .update(t + '.').update(req.body).digest('hex'));
  const sent = Buffer.from(parts.v1 || '');
  if (sent.length !== want.length || !crypto.timingSafeEqual(sent, want)) return res.sendStatus(401);

  res.sendStatus(200);
  const delivery = req.get('x-sybox-delivery');   // seen it already? ignore
  const evt = JSON.parse(req.body);               // { event, line_id, user_id, message | message_id | read_id }
});

Periksa tanda tangan pada body mentah, tolak t yang lebih dari lima menit, dan segera jawab dengan 2xx. Selain itu akan dicoba lagi setelah 10 dtk, 30 dtk, 2 mnt, 10 mnt, dan 30 mnt, lalu dibuang. SyBox hanya memanggil alamat publik dan tidak pernah mengikuti pengalihan.

Kode alasan

Setiap jawaban Live Chat berupa JSON — {"ok": 1, …}, atau {"ok": 0, "error": "CODE"} dengan kode, bukan kalimat:

KodeStatusDeskripsi
unauthorized401Kunci server salah atau sudah diganti.
invalid_json invalid_payload invalid_user_id400Permintaan tidak dalam bentuk yang diharapkan.
empty_message no_file empty_file400Tidak ada teks dan tidak ada file.
too_long400Teks yang diedit lebih dari 4.096 karakter.
not_an_emoji400emoji bukan emoji.
not_found404Pesan tidak ada, atau bukan milik pengguna ini.
too_late409Waktu untuk mengedit atau menghapus sudah lewat.
file_type_not_allowed400Jenis file ini tidak diterima.
file_too_large413File lebih dari 16 MB.
blocked403Tim Anda telah memblokir pengguna ini.
unknown_user404Belum ada percakapan untuk id pengguna ini.
rate_limited429Terlalu banyak panggilan: perlambat dan coba lagi.
maintenance503SyBox sedang diperbarui: coba lagi setelah Retry-After detik.
server_error500Terjadi kegagalan di pihak kami.

Mengganti kunci

Kehilangan kunci, atau mengira kunci bocor? Di kartu situs web, klik Kunci penandatanganan baru, Kunci server baru, atau Kunci tanda tangan balasan baru. Kunci server baru membuat kunci lama tetap berfungsi selama satu hari, sehingga Anda dapat beralih tanpa jeda; kunci lainnya langsung berhenti.