Skip to content
WbizTool

API v2 (beta)

Moving from v1 to v2

API v2 does what v1 does, with safer keys, one URL style, real HTTP status codes and signed JSON webhooks. This page maps each v1 endpoint and field to its v2 equivalent. What's new in v2 itself is in the overview.

What changes everywhere#

  • Keys: v1's client_id + api_key become one header, Authorization: Bearer wbz_live_…. Make a v2 key on Settings → API keys, in the API v2 keys card, with only the scopes the app needs. v1 keys don't work on v2, and v2 keys don't work on v1.
  • JSON only: no form fields. File uploads go to POST /media (multipart) and are sent by media_id.
  • Methods and URLs: GET to read, POST to create, PATCH to change, DELETE to cancel or delete, under https://wbiztool.com/api/v2.
  • HTTP status codes instead of "status": 0 or 1 (see Responses and errors).
  • Phone numbers in international format with +, no country_code.
  • Times in ISO 8601 with an offset, instead of separate date, time and timezone fields.
  • Webhooks are endpoints you add once for the workspace, with signed JSON events, instead of a webhook URL on each message.

Endpoint by endpoint#

v2 paths are relative to https://wbiztool.com/api/v2.

Sending, field by field#

v1v2Notes
client_id + api_key (body or Authorization: Bearer)Authorization: Bearer wbz_live_…A new v2 key; no client_id
phone + country_codeto.phoneOne number in E.164 with +: "9876543210" with "country_code": "91" becomes {"phone": "+919876543210"}. No country code is added for you
phone with an @username (Telegram)to.username@name, t.me/name or tg: and an id, from a Telegram account
group_nameto.groupThe group's exact name
(not in v1)to.contact_idA saved contact
whatsapp_clientfromThe number's id; optional when one number is connected, as before
msg (or message)textUp to 3,000 characters, as before
msg_type 0, 1, 2noneA message with media is a media message; media.type (image or file) when the link doesn't say
img_url / file_urlmedia.urlA public http(s) link
file (upload in the same request)media.media_idUpload first, then send the id as often as you like
file_namemedia.file_nameFor files
schedule_msg/'s date + time + timezonesend_atOne time with its offset: 24/12/2026, 10:30 and Asia/Kolkata become "2026-12-24T10:30:00+05:30"
expire_after_secondsexpires_atA time, not a duration: now plus the seconds, with its offset
webhookwebhook endpointsAdded once with POST /webhooks, for every message of the workspace
msg_id in the answeridThe Message itself comes back, with its status

The same send in v1 and v2:

# v1
curl -X POST https://wbiztool.com/api/v1/send_msg/ \
  -H "Authorization: Bearer YOUR_V1_KEY" \
  -H "Content-Type: application/json" \
  -d '{"whatsapp_client": 101, "msg_type": 1, "country_code": "91", "phone": "9876543210",
       "img_url": "https://example.com/offers/diwali-sale.jpg", "msg": "Our Diwali sale starts today",
       "expire_after_seconds": 3600}'

# v2
curl -X POST https://wbiztool.com/api/v2/messages \
  -H "Authorization: Bearer $WBIZTOOL_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: diwali-9876543210" \
  -d '{"from": 101, "to": {"phone": "+919876543210"},
       "media": {"url": "https://example.com/offers/diwali-sale.jpg"}, "text": "Our Diwali sale starts today",
       "expires_at": "2026-10-20T11:30:00+05:30"}'

A few v1 behaviours are gone on purpose:

  • No guessing of country codes. v1 put country_code in front of a number (with 91, always in front of a 10-digit one). v2 takes the number exactly as written with +.
  • No file download when you call. v1 fetched img_url and file_url during the request. v2 checks that the link is public and fetches the file when the message is sent; a bad link shows up as a failed message.
  • No failed row on refusal. When v1 refuses a send over the daily 1,000, it still stores the message as failed. v2 stores nothing when it refuses a send.
  • Unknown fields are refused instead of being ignored.

Statuses#

v1's numbers and words become one status field:

v1v2 status
0 Created / Pendingqueued, or scheduled while its send_at is ahead
1 Sentsent, delivered or read (the WhatsApp ticks)
2 Failedfailed
3 Cancelledcancelled
4 Expiredexpired

Webhook events are message.sent, message.failed, message.cancelled and message.expired, matching v1's SENT, FAILED, CANCELLED and EXPIRED.

Responses and errors#

v1 answers many errors with HTTP 200 or 400 and "status": 0, and success with "status": 1. v2 uses the HTTP status code:

  • Success is 200, 201 (created) or 202 (queued), and the body is the object itself, such as the Message. There's no status: 1 wrapper.
  • Errors are 4xx or 5xx with one shape: {"error": {"code", "message", "field", "docs", "request_id"}}. Branch on code, not on the English message. Every code is on the errors page.
# v1
result = response.json()
if result.get("status") == 1:
    msg_id = result["msg_id"]

# v2
if response.status_code == 202:
    message_id = response.json()["id"]
else:
    error = response.json()["error"]
    if error["code"] == "number_daily_cap_reached":
        ...  # try again tomorrow

Some v1 messages and their v2 codes:

v1 messagev2 code
Auth Error: invalid api key401 invalid_api_key, api_key_revoked or api_key_expired
Invalid phone number / Invalid Contact Number "…"422 invalid_phone
Msg cant be null400 text_required
Message length is too long400 text_too_long
Invalid whatsapp client422 number_not_found
Invalid whatsapp client id.422 from_required
Not enough credits402 no_credits
Daily limit reached: …429 number_daily_cap_reached
Demo Account can not access apis403 demo_account
Account Disabled403 account_disabled
Invalid JSON format: …400 invalid_json

Webhooks#

In v1, each message can carry a webhook URL that gets a form-encoded msg_id=…&status=SENT. In v2:

  1. Add an endpoint once with POST /webhooks and store its secret.
  2. It gets JSON events for every message of the workspace, with the whole Message in data.message. Match them to your records by data.message.id.
  3. Verify the signature: the same scheme as v1's (WbizTool-Timestamp, WbizTool-Signature: v1=…), but with the endpoint's own secret instead of the workspace's.
  4. Drop repeats with WbizTool-Event-Id. Retries go on for about 23 hours, not 4 tries over a few minutes as in v1, and 4xx answers are retried too.

v1's connect events (webhook_url on whatsapp/connect/) have no v2 event yet: poll GET /numbers/{id} instead.

A checklist#

  1. Make a v2 key per app

    On Settings → API keys, with only the scopes it needs. Try it first with a test key, which checks everything and sends nothing.

  2. Change the requests

    New URLs and methods, JSON bodies, to / from / text / media, phone numbers with +, times with offsets. Add an Idempotency-Key to each send.

  3. Change the error handling

    Check the HTTP status, then error.code. Handle 429 by waiting for Retry-After.

  4. Move webhooks

    Add an endpoint, verify signatures with its secret, and drop repeats by event id.

  5. Switch over and revoke

    Once the app runs on v2, delete its v1 key on Settings → API keys.