Langsung ke konten
WbizTool

API v2 (beta)

API v2

API v2 adalah REST API WbizTool yang baru: satu kunci per aplikasi dengan akses yang benar-benar dibutuhkan saja, URL bergaya resource, kode status HTTP yang sebenarnya, webhook JSON yang ditandatangani, dan percobaan ulang yang aman. Halaman ini membahas hal-hal yang sama untuk setiap request. Halaman sumber daya membahas setiap endpoint.

URL dasar#

https://wbiztool.com/api/v2

Path tidak memakai garis miring di akhir (/api/v2/messages), tetapi garis miring di akhir juga diterima. Alamat yang tidak ada dijawab dengan 404 dan kode not_found.

Contoh singkat#

Periksa kunci Anda dengan GET /me. Request ini berfungsi dengan scope apa pun dan tidak mengirim apa pun:

curl https://wbiztool.com/api/v2/me \
  -H "Authorization: Bearer $WBIZTOOL_API_KEY"
{
  "workspace": { "id": 5012, "name": "Acme Bakery" },
  "key": {
    "id": 7,
    "name": "Order system",
    "mode": "live",
    "scopes": ["messages:send", "messages:read"],
    "limited_to_numbers": false,
    "number_ids": [],
    "expires_at": null
  },
  "plan": { "name": "Starter" },
  "limits": {
    "requests_per_minute": 60,
    "requests_per_day": 10000,
    "messages_per_number_per_day": 1000,
    "messages_remaining": null
  }
}

messages_remaining bernilai null jika paket mengirim pesan tanpa batas. plan bernilai null jika workspace tidak memiliki paket aktif.

Kunci#

Kirim kunci Anda di header Authorization pada setiap request:

Authorization: Bearer wbz_live_…

Tidak ada client_id: kunci sudah menunjukkan workspace-nya. Kunci v2 diawali wbz_live_ atau wbz_test_, diikuti 38 huruf dan angka. Kunci v1 tidak berfungsi di v2 (mendapat v1_key_on_v2), dan kunci v2 tidak berfungsi di v1.

Membuat kunci#

Pemilik membuat kunci di Pengaturan → Kunci API, pada kartu Kunci API v2: klik Buat kunci v2, lalu pilih:

  • Nama: aplikasi yang akan menggunakannya, maksimal 50 karakter.
  • Jenis kunci: Live mengirim pesan sungguhan; Uji memeriksa semuanya dan tidak mengirim apa pun (lihat Mode uji).
  • Yang dapat dilakukan: scope-nya, atau Semuanya.
  • Nomor yang dapat digunakan: semua nomor, termasuk yang ditambahkan nanti, atau hanya sebagian (lihat Kunci yang dibatasi ke sebagian nomor).
  • Kedaluwarsa: tidak pernah, atau dalam 30 hari, 90 hari, atau 1 tahun.

Kunci hanya ditampilkan sekali. Salin segera dan simpan di server Anda, misalnya dalam environment variable. WbizTool hanya menyimpan hash kunci dan empat karakter terakhirnya, sehingga kunci yang hilang tidak dapat ditampilkan lagi: cabut kunci itu dan buat yang baru.

Satu workspace dapat memiliki hingga 10 kunci v2 yang belum dicabut. Kartu ini menampilkan empat karakter terakhir setiap kunci, scope, nomor, tanggal kedaluwarsa, serta kapan dan dari alamat IP mana kunci itu terakhir digunakan. Cabut langsung menghentikan kunci, beserta endpoint webhook yang dibuatnya. Kunci yang melewati tanggal kedaluwarsanya mendapat api_key_expired.

Scope#

Setiap kunci hanya dapat melakukan apa yang diizinkan scope-nya. Request di luar scope tersebut dijawab dengan 403 dan missing_scope, dan required_scope di error menyebutkan scope yang dibutuhkan.

ScopeYang diizinkan
messages:sendMengirim pesan dan batch, serta membatalkan pesan yang menunggu: POST /messages, POST /messages/batch, DELETE /messages/{id}
messages:readMembaca pesan dan statusnya (GET /messages, GET /messages/{id}), serta mengelola endpoint webhook
remindersMembuat, menampilkan, mengubah, menjeda, dan menghapus pengingat
numbersMenampilkan nomor, melihat koneksinya, dan menghubungkan nomor WhatsApp
mediaMengunggah, menampilkan, dan menghapus file di Direktori media
contactsPemeriksaan nomor (endpoint kontak menyusul)

GET /me tidak membutuhkan scope tertentu. Mengirim ke kontak tersimpan dengan to.contact_id hanya membutuhkan messages:send.

Kunci yang dibatasi ke sebagian nomor#

Kunci yang dibatasi ke sebagian nomor hanya berfungsi dengan nomor-nomor tersebut:

  • Kunci ini hanya mengirim dari nomor-nomor itu, serta hanya menampilkan, membaca, dan membatalkan pesan dari nomor-nomor itu. Nomor lain di from mendapat number_not_allowed.
  • GET /numbers hanya menampilkan nomor-nomor itu. Kunci ini dapat menghubungkannya kembali, tetapi tidak dapat menambahkan nomor baru.
  • Kunci ini hanya melihat dan mengubah pengingat yang dikirim dari nomor-nomor itu, dan pengingat baru harus menyebutkan salah satunya sebagai from.
  • Kunci ini sama sekali tidak dapat mengelola endpoint webhook, karena endpoint menerima peristiwa seluruh workspace.

GET /me menampilkan limited_to_numbers dan number_ids yang boleh digunakan kunci.

Request#

  • JSON masuk dan keluar. Kirim body sebagai Content-Type: application/json. Satu-satunya pengecualian adalah mengunggah file, yang memakai multipart/form-data. Setiap respons berupa JSON, termasuk error.
  • Nama field memakai snake_case, dan field yang tidak dikenal ditolak: salah ketik seperti txt dijawab dengan validation_failed, bukan diabaikan.
  • Nomor telepon dalam format internasional dengan + (E.164), misalnya +919876543210. Spasi dan tanda hubung boleh dipakai; nomor tanpa + ditolak dengan invalid_phone.
  • Waktu dalam ISO 8601 dengan offset, misalnya 2026-10-20T09:30:00+05:30 atau 2026-10-20T04:00:00Z. Waktu tanpa offset ditolak dengan invalid_datetime. Waktu di respons dalam UTC dan diakhiri Z, kecuali next_run_at pengingat, yang memakai zona waktu pengingat tersebut.
  • ID berupa integer, seperti id nomor (from saat Anda mengirim) atau id pesan.
  • Kode status sesuai artinya: 200 OK, 201 dibuat, 202 diterima (masuk antrean), 400 request salah, 401 kunci salah, 402 pesan habis, 403 tidak diizinkan, 404 tidak ditemukan, 409 konflik, 413 terlalu besar, 415 jenis konten salah, 422 nilai tidak dapat digunakan, 429 terlalu banyak request, 5xx masalah di pihak kami.

Respons membawa Cache-Control: no-store.

Error#

Setiap error memiliki bentuk yang sama:

{
  "error": {
    "code": "invalid_phone",
    "message": "This is not a valid phone number. Write it in international format with +, e.g. +919876543210.",
    "field": "to.phone",
    "docs": "https://wbiztool.com/docs/api/v2/errors/#invalid_phone",
    "request_id": "req_4f1c2a9b8e7d6c5b4a392817"
  }
}
  • code bersifat tetap: gunakan untuk percabangan di kode Anda. message adalah teks bahasa Inggris untuk developer dan dapat berubah.
  • field menyebutkan field yang menjadi masalah (to.phone, to[3].phone, schedule.cron), atau bernilai null.
  • docs menautkan ke kode tersebut di halaman error.
  • request_id sama dengan header X-Request-Id. Sebutkan nilainya jika Anda menghubungi kami.
  • Beberapa error menambahkan detail, misalnya status pada not_cancellable atau used dan limit pada storage_full. Jika satu request memiliki beberapa masalah, errors mencantumkan masalah lainnya, masing-masing dengan field dan message.

Setiap kode, status HTTP-nya, dan apa yang harus dilakukan ada di halaman error.

Idempotency-Key#

Error jaringan atau timeout membuat Anda tidak yakin apakah request berhasil. Kirim header Idempotency-Key bersama POST yang membuat sesuatu, dan Anda dapat mengirimnya lagi dengan aman:

curl -X POST https://wbiztool.com/api/v2/messages \
  -H "Authorization: Bearer $WBIZTOOL_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1042-ready" \
  -d '{"to": {"phone": "+919876543210"}, "text": "Hi Asha, your order #1042 is ready."}'
  • Nilainya Anda tentukan sendiri: string unik apa pun sepanjang 1 hingga 255 karakter yang dapat dicetak, seperti UUID atau ID pesanan Anda sendiri. Buat nilai baru untuk setiap request baru, dan gunakan ulang hanya untuk percobaan ulang request yang sama.
  • Percobaan ulang mendapat respons pertama dengan header Idempotent-Replayed: true. Tidak ada yang dilakukan dua kali: tidak ada pesan, pengingat, file, atau endpoint kedua.
  • Key berlaku 24 jam sejak request pertama, dan terikat pada kunci API Anda: kunci API lain di workspace dapat memakai nilai yang sama tanpa bentrok.
  • Key sama, request berbeda: request dengan key yang sudah dipakai untuk method, path, atau body yang berbeda dijawab dengan 422 idempotency_key_reused.
  • Masih berjalan: selama request pertama dengan key tersebut masih diproses, percobaan ulang dijawab dengan 409 idempotency_in_progress beserta Retry-After: 1. Tunggu sebentar dan kirim lagi.
  • Error tidak disimpan. Jika request pertama dijawab dengan error, tidak ada yang disimpan: perbaiki request dan kirim lagi dengan key yang sama.
  • Rahasia tidak diputar ulang. Pemutaran ulang POST /webhooks tidak menyertakan secret endpoint, yang hanya ditampilkan di respons pertama.

Header ini berfungsi pada POST /messages, POST /messages/batch, POST /numbers, POST /reminders, POST /media, POST /number-checks, dan POST /webhooks, dan bersifat opsional di masing-masing. Request lain mengabaikan header ini. Nilai yang kosong atau terlalu panjang dijawab dengan 400 invalid_idempotency_key.

Batas laju#

Setiap kunci dapat membuat 60 request per menit dan 10.000 request per hari. Ini adalah jendela tetap: jendela menit dimulai pada menit jam, jendela hari pada pukul 00.00 UTC. Jika melewati batas, request dijawab dengan 429 rate_limited.

Respons untuk request dengan kunci yang valid membawa header berikut:

HeaderArti
RateLimit-LimitRequest yang diizinkan di jendela saat ini (60, atau 10000 setelah batas harian tercapai)
RateLimit-RemainingSisa request di jendela itu
RateLimit-ResetDetik hingga jendela itu dimulai lagi
RateLimit-PolicyKedua batas: 60;w=60, 10000;w=86400
Retry-AfterPada 429: detik yang perlu ditunggu sebelum Anda mencoba lagi

Terpisah dari batas ini:

  • Kunci salah: lebih dari 30 request per menit dengan kunci yang salah dari satu alamat IP dijawab dengan 429 too_many_auth_failures beserta Retry-After: 60.
  • Pesan per nomor: satu nomor mengirim paling banyak 1.000 pesan dalam 24 jam (penggunaan wajar). Pengiriman yang melewatinya dijawab dengan 429 number_daily_cap_reached.

Paginasi#

Daftar yang dapat bertambah (GET /messages, /reminders, /media, /number-checks, dan /results sebuah pemeriksaan) dibagi per halaman, yang terbaru lebih dulu:

{
  "data": [ … ],
  "next_cursor": "eyJpZCI6OTgxNzI2MywidCI6IjIwMjYtMTAtMThUMTA6MTU6MDIuMzExWiIsImYiOiI0NGIxMzZmYTM1NWIifQ"
}
  • limit menentukan ukuran halaman, dari 1 hingga 100 (default 25).
  • Untuk mendapatkan halaman berikutnya, kirim request yang sama dengan cursor diisi next_cursor dari halaman terakhir. next_cursor bernilai null pada halaman terakhir.
  • Gunakan filter lain yang sama: cursor yang dipakai dengan filter berbeda dijawab dengan 400 invalid_cursor. Mulai lagi tanpa cursor.
  • Perlakukan cursor sebagai string yang tidak perlu diurai. Item yang ditambahkan selama Anda menelusuri halaman tidak menggeser halaman.
curl "https://wbiztool.com/api/v2/messages?limit=100&cursor=eyJpZCI6OTgxNzI2MywidCI6..." \
  -H "Authorization: Bearer $WBIZTOOL_API_KEY"

GET /numbers dan GET /webhooks mengembalikan semuanya dalam satu daftar data.

ID request#

Setiap respons, termasuk error, memiliki header X-Request-Id seperti req_4f1c2a9b8e7d6c5b4a392817. Error membawa nilai yang sama sebagai request_id. Catat nilainya, dan sebutkan jika Anda menghubungi kami: dengan nilai ini kami dapat menemukan request di log kami, yang mencatat ID kunci Anda tetapi tidak pernah kuncinya.

Jika Anda mengirim X-Request-Id sendiri (hingga 100 karakter yang dapat dicetak), nilainya kembali sebagai X-Client-Request-Id, sehingga Anda dapat mencocokkan respons dengan log Anda sendiri.

Mode uji#

Kunci uji (wbz_test_…) memungkinkan Anda membangun dan menguji integrasi tanpa mengirim apa pun. Buat kunci uji di Pengaturan → Kunci API dengan Jenis kunci: Uji. GET /me menampilkan "mode": "test".

Yang dilakukan kunci uji sama seperti kunci live:

  • POST /messages dan POST /messages/batch memeriksa semua yang diperiksa pada pengiriman live: penerima, teks, media, send_at dan expires_at, nomor pengirim, serta scope dan nomor kunci. Kesalahan yang sama mendapat error yang sama.
  • Scope, nomor, batas laju, dan Idempotency-Key berfungsi sama.
  • Setiap pembacaan bagian lain workspace (GET /me, /numbers, /reminders, /media, /number-checks, /webhooks) menampilkan data sebenarnya, hanya-baca.

Yang berbeda:

  • Tidak ada yang dikirim. Pengiriman uji disimpan sebagai pesan uji, dan tidak memakai pesan paket atau jatah harian 1.000 nomor tersebut, sehingga tidak pernah mendapat no_credits atau number_daily_cap_reached.
  • Statusnya berpindah dengan sendirinya: queued, lalu sent 5 detik kemudian dan delivered 15 detik setelah dibuat (dihitung dari send_at untuk pesan terjadwal). Pesan yang expires_at-nya lebih awal dari waktu pengirimannya menjadi expired. Pesan uji tidak pernah menjadi read atau failed.
  • Kunci uji hanya melihat pesan ujinya sendiri. GET /messages dan GET /messages/{id} hanya menampilkan pesan-pesan itu, dan DELETE /messages/{id} membatalkannya selama berstatus queued atau scheduled. Kunci live tidak pernah melihat pesan uji. Filter status di GET /messages tidak didukung untuk kunci uji dan dijawab dengan test_mode_unsupported; number, since, dan until berfungsi.
  • Penulisan lain ditolak dengan 403 test_mode_unsupported: menghubungkan nomor, membuat, mengubah, atau menghapus pengingat, mengunggah atau menghapus media, memulai pemeriksaan nomor, serta menambahkan, menghapus, merotasi, atau menguji endpoint webhook.
  • Tidak ada peristiwa webhook yang dikirim untuk pesan uji.
  • Pesan uji disimpan selama 30 hari.

Sumber daya#

  • Pesan: kirim sekarang atau nanti, kirim ke hingga 1.000 penerima, baca riwayat, batalkan.
  • Nomor: tampilkan nomor WhatsApp dan akun Telegram Anda, dan hubungkan nomor WhatsApp dengan kode QR atau kode penautan.
  • Pengingat: pesan berulang dengan jadwal cron.
  • Media: unggah file sekali dan kirim dengan media_id.
  • Pemeriksaan nomor: cari tahu nomor mana yang ada di WhatsApp.
  • Webhook: peristiwa bertanda tangan saat pesan terkirim, gagal, dibatalkan, atau kedaluwarsa.
  • Error: semua kode error.
  • Pindah dari v1 ke v2: setiap endpoint dan field v1, beserta padanannya di v2.