Dokumentasi API — Geura
Referensi lengkap buat integrasi ke sistem lain (Laravel, Odoo, n8n, atau bahasa/framework apapun yang bisa HTTP request). Semua contoh di bawah pakai curl, tinggal disesuaikan ke library HTTP client bahasa kamu.
Autentikasi
Semua endpoint di bawah /api/* butuh autentikasi. Ada dua cara, pilih salah satu:
1. API Key — buat integrasi server-ke-server
Kirim sebagai header x-api-key, atau query string ?api_key=... (khusus endpoint yang didesain dibuka langsung di browser, misal gambar QR).
curl https://geura.wibicon.com/api/numbers \
-H "x-api-key: API_TOKEN_KAMU"
API token kamu bisa dilihat di dashboard: tab Saldo & Kuota (klien) atau tab Klien (admin, buat lihat token tiap klien).
2. JWT Bearer Token — dipakai dashboard web
curl -X POST https://geura.wibicon.com/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"USERNAME","password":"PASSWORD"}'
Respons berisi token — pakai sebagai header Authorization: Bearer <token> di request selanjutnya. Token berlaku 7 hari.
Quick Start: Kirim Pesan
Alur paling umum buat integrasi: pastikan minimal satu Device sudah connected (scan QR sekali lewat dashboard, tab Device), lalu kirim pesan pakai number_id device itu.
/api/messages/sendcurl -X POST https://geura.wibicon.com/api/messages/send \
-H "x-api-key: API_TOKEN_KAMU" \
-H "Content-Type: application/json" \
-d '{
"number_id": "ID_DEVICE",
"to": "6281234567890",
"message": "Halo dari Geura!"
}'
Respons 202: {"id": "...", "status": "queued"} — pesan masuk antrian (BullMQ), dikirim dengan jeda otomatis anti-banned, bukan langsung sinkron. Cek status akhirnya lewat GET /api/messages/:id.
message jadi poll:
"poll": {"name": "Pilih menu", "options": ["Nasi Goreng", "Mie Goreng"], "multiple": false}Device
Satu Device = satu nomor WhatsApp = satu session Baileys (protokol WhatsApp Web, unofficial). Butuh scan QR sekali di awal.
| Method | Endpoint | Keterangan |
|---|---|---|
| GET | /api/numbers | List semua device tenant kamu + status connected |
| POST | /api/numbers | Tambah device baru ({"label": "Nomor CS"}), mulai proses pairing |
| GET | /api/numbers/:id | Detail satu device |
| GET | /api/numbers/:id/qr | QR sebagai JSON (data URL base64 PNG) |
| GET | /api/numbers/:id/qr.png | QR sebagai gambar langsung, bisa dibuka browser pakai ?api_key= |
Riwayat & Inbox
| Method | Endpoint | Keterangan |
|---|---|---|
| GET | /api/messages?limit=&offset= | Riwayat pesan keluar (terbaru dulu) |
| GET | /api/messages/:id | Detail + status satu pesan (queued/sent/failed) |
| GET | /api/inbox | Pesan WA masuk |
Webhook (pesan masuk)
Daripada polling /api/inbox terus-terusan, atur webhook_url kamu sendiri di dashboard (menu Webhook) — tiap ada pesan WA masuk, gateway POST ke URL itu:
{
"event": "message.received",
"numberId": "...",
"from": "6281234567890@s.whatsapp.net",
"body": "isi pesannya"
}
| Method | Endpoint | Keterangan |
|---|---|---|
| GET | /api/settings/webhook | Lihat webhook_url yang diatur |
| PATCH | /api/settings/webhook | {"webhook_url": "https://..."} |
| GET | /api/settings/webhook/log | Riwayat 100 percobaan kirim webhook terakhir (sukses/gagal) |
/api/inbox sebagai cadangan.Phonebook
Terbagi 3 submenu: Contact (buku kontak), Group (pengelompokan kontak), dan WA Group (grup WhatsApp asli yang device-nya udah jadi member).
Contact
Bulk add pakai format nomor|var1|var2|... per baris (satu baris = satu kontak) — var1 otomatis jadi Nama, sisanya disimpan sebagai variables[] buat personalisasi ke depannya.
| Method | Endpoint | Keterangan |
|---|---|---|
| GET | /api/contacts?group_id= | List kontak, opsional filter grup |
| POST | /api/contacts | {"name","phone","group_id","variables":[]} — tambah satu kontak |
| POST | /api/contacts/bulk | {"lines":["081...|Andi|Jakarta"],"group_id","country_code":"62"} — dipakai Add Number & Import |
| PATCH | /api/contacts/:id | Update kontak |
0 otomatis dinormalisasi pakai country_code (mis. 081... + 62 jadi 6281...). Nomor yang udah lengkap (diawali + atau kode negaranya sendiri) dibiarkan apa adanya.Group
| Method | Endpoint | Keterangan |
|---|---|---|
| GET | /api/groups | List grup + jumlah kontak tiap grup |
| POST | /api/groups | {"name"} |
| PATCH | /api/groups/:id | Rename grup (otomatis sinkron ke semua kontak yang kepaut) |
WA Group
Beda dari Group di atas (yang cuma pengelompokan kontak internal) — ini grup WhatsApp asli, dibaca live dari Baileys, jadi Device-nya wajib connected dulu.
| Method | Endpoint | Keterangan |
|---|---|---|
| GET | /api/numbers/:id/groups | List grup WhatsApp yang device ini udah jadi member |
| POST | /api/numbers/:id/groups/send | {"group_id","message"} — group_id di sini adalah JID grup (diakhiri @g.us) |
Template
Pesan tersimpan, dipilih dari dropdown pas Kirim Pesan/Campaign/Recurring biar gak ngetik ulang.
| Method | Endpoint | Keterangan |
|---|---|---|
| GET | /api/templates | List template |
| POST | /api/templates | {"name","content"} |
| PATCH | /api/templates/:id | Update name/content |
Campaign (blast)
Kirim satu pesan ke banyak penerima sekaligus, lewat satu atau beberapa Device (kalau lebih dari satu, beban blast-nya kebagi).
/api/campaigns{
"name": "Promo Akhir Bulan",
"number_ids": ["ID_DEVICE_1", "ID_DEVICE_2"],
"recipients": ["6281111111111", "6282222222222"],
"message": "Halo, ada promo nih!",
"delay_min_ms": 2000,
"delay_max_ms": 5000
}
Cuma nomor dari number_ids yang beneran connected yang dipakai kirim. delay_min_ms/delay_max_ms opsional (default dari setting server) — jeda acak antar pesan buat anti-banned.
Recurring
Kirim ulang isi sebuah Template ke daftar penerima tetap, otomatis sesuai jadwal — dieksekusi scheduler tiap menit.
/api/recurring{
"name": "Reminder Mingguan",
"number_id": "ID_DEVICE",
"template_id": "ID_TEMPLATE",
"recipients": ["6281111111111"],
"interval_type": "weekly",
"start_at": "2026-09-15T09:00:00.000Z"
}
interval_type: daily, weekly, monthly, atau annually.
Autoreply
Balasan otomatis berdasar keyword pesan WA masuk.
/api/autoreply{
"keyword": "harga",
"match_type": "contains",
"reply_text": "Info harga bisa dicek di katalog kami ya!",
"is_active": true
}
match_type: contains, exact, begin, atau end.
Submission
Form tanya-jawab bertahap lewat chat WA — orang chat trigger_keyword, bot kirim opening_message (opsional) lalu pertanyaan satu-satu, jawabannya tersimpan otomatis.
/api/submissions/flows{
"name": "Form Pendaftaran",
"trigger_keyword": "daftar",
"opening_message": "Yuk isi form pendaftaran singkat ini!",
"questions": ["Siapa nama kamu?", "Nomor WA aktif?"],
"thank_you_message": "Terima kasih, pendaftaran kamu udah kami terima!"
}
/api/submissions/responsesLihat semua hasil isian yang udah masuk.
Chaining
Chatbot bercabang (mirip menu IVR) — root node dipicu keyword, balasan orang yang lagi "di" node itu dicocokkan ke key anak-anaknya buat lanjut ke node berikutnya.
/api/chains// Root node (parent_id kosong), dipicu keyword lewat "key"
{ "number_id": "ID_DEVICE", "name": "Menu Utama", "key": "menu", "message": "Ketik 1 buat Sales, 2 buat Support" }
// Node anak, parent_id ke node di atas
{ "number_id": "ID_DEVICE", "name": "Sales", "parent_id": "ID_NODE_ROOT", "key": "1", "message": "Tim Sales akan segera menghubungi kamu" }
Rotator
Link publik yang muter-muter redirect ke salah satu nomor WA tenant — buat tombol "Chat Kami" di website/bio-link biar beban CS kebagi rata.
/api/rotators{
"name": "Tombol Chat Kami",
"numbers": [{"number_id": "ID_DEVICE_1", "weight": 2}, {"number_id": "ID_DEVICE_2", "weight": 1}],
"rotation_cycle": "full",
"default_text": "Halo, saya mau tanya-tanya"
}
Link publiknya: https://geura.wibicon.com/r/ID_ROTATOR (tanpa auth, langsung redirect ke wa.me). rotation_cycle: full (round-robin berbobot) atau partial (random berbobot).
Follow Up
N jam/hari setelah kontak MASUK ke suatu grup Phonebook, kirim pesan otomatis sekali ke kontak itu (nurture/onboarding sequence).
/api/followups{
"name": "Follow up 1 hari setelah daftar",
"number_id": "ID_DEVICE",
"group_name": "leads-baru",
"after_value": 1,
"after_unit": "day",
"message": "Halo, masih tertarik dengan produk kami?"
}
Telegram
Channel tambahan di luar WhatsApp. Satu tenant bisa punya beberapa bot (masing-masing dari token @BotFather).
| Method | Endpoint | Keterangan |
|---|---|---|
| POST | /api/telegram/bots | {"label","bot_token"} — otomatis diverifikasi & daftarin webhook ke Telegram |
| POST | /api/telegram/bots/:id/send | {"chat_id","message"} — kirim sinkron (gak lewat antrian) |
| GET | /api/telegram/messages | Riwayat terkirim |
| GET | /api/telegram/incoming | Pesan masuk |
WABA (WhatsApp Business API resmi Meta)
Beda arsitektur total dari Device (Baileys) — gak ada QR scan. Kamu input phone_number_id + access_token dari Meta App dashboard sendiri.
/api/waba/numbers{
"label": "Nomor CS Utama",
"phone_number_id": "1234567890",
"access_token": "EAAxxxxxxxxxxxxxxxxxxxxxxxx",
"waba_id": "9876543210"
}
/api/waba/numbers/:id/send{ "to": "6281234567890", "message": "Halo dari WABA!" }
https://geura.wibicon.com/waba/webhook di Meta App dashboard, dengan Verify Token sesuai WABA_VERIFY_TOKEN di server. Lihat URL-nya juga dari dashboard, tab WABA, atau GET /api/waba/webhook-info.Satu setting SMTP (kirim) + IMAP (terima, opsional) per tenant — beda dari Telegram/WABA yang bisa multi-akun.
| Method | Endpoint | Keterangan |
|---|---|---|
| PATCH | /api/email/settings | Simpan setting SMTP/IMAP (lihat form di dashboard buat field lengkapnya) |
| POST | /api/email/send | {"to","subject","message"} |
| GET | /api/email/messages | Riwayat terkirim |
| GET | /api/email/incoming | Email masuk (di-poll dari IMAP tiap 1 menit, kalau diaktifkan) |
AI Auto-Reply
Fallback TERAKHIR buat pesan WA/Telegram/WABA masuk — cuma dipanggil kalau gak ada Submission/Chaining/Autoreply yang cocok. Pakai API key AI kamu sendiri (OpenAI atau Anthropic).
/api/ai{
"is_active": true,
"provider": "openai",
"api_key": "sk-...",
"model": "gpt-4o-mini",
"system_prompt": "Kamu adalah customer service toko online yang ramah dan singkat."
}
GET /api/ai gak pernah balikin api_key utuh, cuma flag has_api_key.
CS Multi Agent
Sistem CS manusia (bukan bot) yang di-assign nanganin percakapan dari semua channel (WA/Telegram/WABA).
| Method | Endpoint | Keterangan |
|---|---|---|
| POST | /api/divisions | {"name"} — grup tim CS |
| POST | /api/agents | {"name","email","phone","division_id"} |
| GET | /api/conversations?status=open | List percakapan (ter-update otomatis tiap ada pesan masuk) |
| PATCH | /api/conversations/:id | {"assigned_agent_id","division_id","status"} |
| GET | /api/conversations/report | Ringkasan open/closed per Agent + jumlah yang belum di-assign |
Invoices & Billing
Kuota gratis bulanan + top up saldo (deposit) via QRIS Midtrans.
| Method | Endpoint | Keterangan |
|---|---|---|
| GET | /api/billing | Kuota terpakai + saldo deposit tenant kamu |
| GET | /api/billing/payments | Riwayat top up (ditampilin sebagai tab Invoices) |
Setting
| Method | Endpoint | Keterangan |
|---|---|---|
| GET | /api/settings/profile | Profil tenant (nama, perusahaan, telepon) |
| PATCH | /api/settings/profile | {"name","company_name","phone"} |
| PATCH | /api/auth/password | {"current_password","new_password"} — ganti password sendiri |
Rate Limit & Anti-Banned
Channel WA di gateway ini pakai protokol WhatsApp Web (Baileys, unofficial) — bukan API resmi Meta. Buat ngurangin risiko nomor kena banned, tiap pesan blast dikirim lewat antrian dengan jeda acak (default 2–5 detik) antar pesan, bukan sekaligus.
- Kirim volume besar? Pakai beberapa Device sekaligus (fitur Rotator/Campaign multi-nomor bisa bantu bagi beban).
- Warm-up nomor baru sebelum dipakai blast volume besar (kirim wajar dulu beberapa hari).
- Channel Telegram, WABA (resmi Meta), dan Email tidak pakai jeda ini karena bukan protokol unofficial.