# vybeflow — seluruh endpoint publik Base URL: https://vybeflow.vyber.id Autentikasi: `x-api-key: vf_live_…` (atau `Authorization: Bearer vf_live_…`). Setiap baris menyebut izin yang harus dimiliki kunci, dan risikonya. risk: safe = hanya membaca · confirm = mengubah data · destructive = mengirim ke pelanggan, memotong kuota, atau menghapus permanen. ## contact ### contact.list GET /api/user/users - Daftar kontak pelanggan milik tenant. - izin: `contact.read` · risk: safe - mengembalikan: _id, name, msisdn, email, tags, createdAt ### contact.create POST /api/user/users - Tambah satu kontak baru. - izin: `contact.manage` · risk: confirm - body: name*, msisdn*, email ### contact.update PUT /api/user/users/:id - Ubah satu kontak. - izin: `contact.manage` · risk: confirm - body: name, msisdn, email ### contact.delete DELETE /api/user/users/:id - Hapus satu kontak. Tidak bisa dibatalkan. - izin: `contact.delete` · risk: destructive - ⚠ Kontak yang dihapus tidak dapat dikembalikan; riwayat percakapannya tetap ada. ### contact.import POST /api/user/users/import - Impor banyak kontak sekaligus. - izin: `contact.manage` · risk: confirm - body: users* ### contact.byCampaign GET /api/user/users/campaign/:campaignID - Kontak yang termasuk dalam satu kampanye. - izin: `contact.read` · risk: safe - mengembalikan: _id, name, msisdn, email ## campaign ### campaign.list GET /api/campaign/campaigns - Daftar kampanye beserta status dan jumlah penerima. - izin: `campaign.read` · risk: safe - mengembalikan: _id, name, status, channel, totalRecipients, sentCount, createdAt ### campaign.analytics GET /api/campaign/campaigns/analytics - Ringkasan performa kampanye: terkirim, dibuka, gagal. - izin: `campaign.read` · risk: safe ### campaign.create POST /api/campaign/campaigns - Buat kampanye baru. Membuat TIDAK mengirim — pakai campaign.send. - izin: `campaign.manage` · risk: confirm - body: name*, message*, channel* ### campaign.send POST /api/campaign/campaigns/:id/send - MULAI mengirim kampanye ke seluruh penerimanya. - izin: `campaign.send` · risk: destructive - ⚠ Ini mengirim pesan sungguhan ke pelanggan sungguhan dan memotong kuota. Tidak ada tombol batal setelah terkirim — campaign.cancel hanya menghentikan sisa antrean. ### campaign.cancel POST /api/campaign/campaigns/:id/cancel - Hentikan kampanye yang sedang berjalan. Pesan yang sudah terkirim tetap terkirim. - izin: `campaign.control` · risk: confirm ### campaign.progress GET /api/campaign/campaigns/:id/progress - Kemajuan pengiriman satu kampanye. - izin: `campaign.read` · risk: safe - catatan: Ada juga /campaigns/:id/progress/stream yang berbasis SSE. Tidak didaftarkan di sini: sebuah stream tidak punya akhir, dan call_api menunggu respons selesai. ### campaign.delete DELETE /api/campaign/campaigns/:id - Hapus kampanye beserta statistiknya. - izin: `campaign.manage` · risk: destructive - ⚠ Statistik kampanye ikut hilang dan tidak dapat dikembalikan. ## inbox ### inbox.ticket.list GET /api/ai/v1/tickets - Daftar tiket percakapan. - izin: `inbox.read` · risk: safe - mengembalikan: _id, ticketID, status, channel, customerName, msisdn, lastMessageAt, unread ### inbox.ticket.stats GET /api/ai/v1/tickets/stats - Jumlah tiket per channel dan per status. - izin: `inbox.read` · risk: safe ### inbox.ticket.get GET /api/ai/v1/tickets/:ticketID - Satu tiket beserta riwayat pesannya. - izin: `inbox.read` · risk: safe - catatan: Riwayat pesan bisa panjang. Jika jawabannya ditolak karena too_large, pakai `slice` untuk membaca sebagiannya, jangan meminta ulang berharap hasilnya lebih pendek. ### inbox.ticket.byStatus GET /api/ai/v1/tickets/status/:status - Tiket dengan satu status tertentu. - izin: `inbox.read` · risk: safe - mengembalikan: _id, ticketID, status, channel, customerName, lastMessageAt ### inbox.ticket.create POST /api/ai/v1/tickets - Buat tiket baru. - izin: `inbox.manage` · risk: confirm - body: msisdn*, channel*, message ### inbox.ticket.reply POST /api/ai/v1/tickets/:ticketID/reply - Kirim balasan ke pelanggan pada satu tiket. - izin: `inbox.reply` · risk: destructive - body: message* - ⚠ Pesan ini sampai ke pelanggan sungguhan dan tidak bisa ditarik kembali. ### inbox.ticket.close POST /api/ai/v1/tickets/:ticketID/close - Tutup tiket. - izin: `inbox.manage` · risk: confirm ## channel ### channel.list GET /api/channel/v1/channels - Daftar channel yang terhubung beserta statusnya. - izin: `channel.read` · risk: safe - mengembalikan: channelId, type, name, status, connectedAt ### channel.get GET /api/channel/v1/channels/:channelId - Detail satu channel. - izin: `channel.read` · risk: safe - mengembalikan: channelId, type, name, status, connectedAt - catatan: Kredensial channel (token, secret, app id) tidak pernah dikembalikan lewat jalur ini — `project` sengaja tidak memuatnya. ### channel.whatsapp.status GET /api/channel/v1/whatsapp/status - Status sambungan WhatsApp tenant. - izin: `channel.read` · risk: safe ### channel.whatsapp.templates GET /api/channel/v1/whatsapp/cloud/templates - Template WhatsApp Cloud yang sudah disetujui Meta. - izin: `channel.read` · risk: safe - mengembalikan: name, language, status, category ### channel.whatsapp.send POST /api/channel/v1/notification/send/whatsapp - Kirim satu pesan WhatsApp ke satu nomor. - izin: `inbox.reply` · risk: destructive - body: msisdn*, message* - ⚠ Pesan sampai ke nomor sungguhan dan memotong kuota. Tidak bisa ditarik kembali. ## product ### product.list GET /api/product/v1/products - Daftar produk milik tenant. - izin: `product.read` · risk: safe - mengembalikan: _id, productID, name, price, stock, category, description - catatan: Gambar produk TIDAK ada di sini. Endpoint gambar mengembalikan byte untuk tag , bukan JSON, dan sengaja tidak didaftarkan. ### product.get GET /api/product/v1/products/:productID - Detail satu produk. - izin: `product.read` · risk: safe - mengembalikan: _id, productID, name, price, stock, category, description ### product.create POST /api/product/v1/products - Tambah produk baru. - izin: `product.manage` · risk: confirm - body: name*, price*, stock, category, description ### product.update PUT /api/product/v1/products/:productID - Ubah satu produk. - izin: `product.manage` · risk: confirm - body: name, price, stock, category, description ### product.delete DELETE /api/product/v1/products/:productID - Hapus satu produk beserta gambarnya. - izin: `product.manage` · risk: destructive - ⚠ Produk dan gambarnya hilang permanen. ## billing ### billing.history GET /api/payment/v1/payment/history - Riwayat transaksi pembayaran tenant. - izin: `billing.read` · risk: safe - mengembalikan: orderID, amount, status, productName, createdAt, paidAt ### billing.transaction GET /api/payment/v1/payment/history/:orderID - Satu transaksi berdasarkan orderID. - izin: `billing.read` · risk: safe - mengembalikan: orderID, amount, status, productName, createdAt, paidAt ### billing.subscription GET /api/user/v1/dashboard/subscription - Paket langganan yang sedang aktif. - izin: `billing.read` · risk: safe ### billing.quota GET /api/ai/v1/quota - Sisa kuota AI dan pesan untuk tenant ini. - izin: `quota.read` · risk: safe ### billing.usage GET /api/ai/v1/usage - Riwayat pemakaian kuota. - izin: `quota.read` · risk: safe ## tenant ### tenant.setting GET /api/user/v1/dashboard/setting - Profil perusahaan: nama, alamat, kontak, jam kerja. - izin: `tenant.setting.read` · risk: safe - mengembalikan: companyName, companyNickName, companyAddress, companyPhoneNumber, companyMobileNumber, companyCSPhoneNumber, jamKerjaCustomerService, jamKerjaOperasional, jamKerjaBukaKantorPembayaran - catatan: Kredensial pembayaran, SMTP, lisensi dan domain kustom ADA di record yang sama tetapi tidak pernah dikembalikan lewat jalur ini. Jangan menyimpulkan bahwa tenant belum mengaturnya hanya karena tidak terlihat. ### tenant.list GET /api/user/v1/dashboard/tenant/list - Tenant yang dapat diakses pemegang kredensial ini. - izin: `tenant.read` · risk: safe - mengembalikan: tenantID, name, type - catatan: Sebuah API key terikat pada SATU tenant, jadi daftar ini praktis selalu berisi satu baris. Ia ada supaya jawabannya eksplisit, bukan supaya kunci bisa berpindah tenant.