WhaBuzzdocs
Guides

Connect your app to WhaBuzz

Let a WhaBuzz customer connect your app in one click. They approve on a WhaBuzz page; your server gets a scoped API key, a webhook secret and the number.

Connect lets a WhaBuzz customer hand your app access to one of their WhatsApp numbers without copying keys. It works like "Sign in with" flows: you send the user to a WhaBuzz page, they approve, WhaBuzz sends them back to you with a one-time code, and your server swaps the code for credentials.

Connect is available to apps registered with WhaBuzz. Today that is WhaLeads (app=whaleads). To register another app, write to support@whabuzz.com with its name and the host pattern of its callback.

#How it works

  1. Your app sends the user to https://app.whabuzz.com/connect with your app id, your callback URL and a random state.
  2. The user signs in to WhaBuzz, picks a workspace and a number. If the workspace has no number yet, they connect one there through Meta (coexistence with the WhatsApp Business app included).
  3. WhaBuzz shows what your app will be able to do and the host of your callback. The user presses Approve.
  4. WhaBuzz sends a verify ping to https://<your host>/api/whabuzz/webhook. If your server does not answer it, nothing is created and the user sees why.
  5. WhaBuzz redirects the browser to your callback with code and state.
  6. Your server posts the code to https://api.whabuzz.com/connect/token and receives the API key, the webhook signing secret and the number, once.

#1. Send the user to WhaBuzz

https://app.whabuzz.com/connect
  ?app=whaleads
  &callback=https://acme.example.com/api/whabuzz/callback
  &state=Qm9vcC1iZWVwLTEyMzQ1Njc4OTA
  &code_challenge=VAVLIyYOqvtuLg_z2ITRlp_41lQmqEtYFeN-BpcepQ0
ParameterRequiredMeaning
appyesYour registered app id.
callbackyeshttps://<your host>/api/whabuzz/callback exactly: HTTPS, that path, no query string or fragment. Public host names only (no IP addresses or localhost).
stateyesUp to 200 printable ASCII characters, no spaces. Make it random per attempt, keep it in the user's session, and compare it when the user comes back.
code_challengenoPKCE: base64url (no padding) of the SHA-256 of a random code_verifier of 43 to 128 characters. If you send it, the exchange needs the verifier. Recommended.

Keep the whole link under about 500 characters: WhaBuzz carries it through sign-in, and a longer one makes the user start again after signing in.

#2. Answer the verify ping

Before anything is issued, WhaBuzz POSTs a signed ping to https://<your host>/api/whabuzz/webhook:

json
{ "type": "webhook.verify", "challenge": "6f1c0b8e4a7d4f29b3e5a0c2d9f81a47", "endpoint_id": "3c2b…", "created_at": "2026-10-19T09:30:00.000Z" }

Answer 2xx within 5 seconds with the challenge echoed, as the plain-text body or as JSON {"challenge":"…"}. You do not have the signing secret yet at this point, so accept the ping without checking X-WhaBuzz-Signature (it is still signed, with the secret you receive in step 4). Check signatures on everything else.

Your webhook receives all events (*) for the whole workspace, starting the moment your server completes the exchange in step 4. See Webhooks for payloads, retries and the signature check.

#3. Handle the callback

On approve, the browser lands on:

https://acme.example.com/api/whabuzz/callback?code=7Hq0…(43 characters)&state=Qm9vcC1iZWVwLTEyMzQ1Njc4OTA

If the user pressed Cancel:

https://acme.example.com/api/whabuzz/callback?error=access_denied&state=Qm9vcC1iZWVwLTEyMzQ1Njc4OTA

Compare state with the one you stored before doing anything else. The code works once and expires after 5 minutes.

#4. Exchange the code

Server to server, never from the browser:

bash
curl -X POST https://api.whabuzz.com/connect/token \
  -H "Content-Type: application/json" \
  -d '{"app":"whaleads","code":"7Hq0…","state":"Qm9vcC1iZWVwLTEyMzQ1Njc4OTA","code_verifier":"dBjftJeZ4CVP-mJ92K1RmuIBRHzyl1Ftw7gJA4KiBnI"}'

No Authorization header: the code is the credential. Send code_verifier only if you sent a code_challenge.

200 OK, shown once (the response carries Cache-Control: no-store):

json
{
  "api_key": "wb_live_…",
  "webhook_secret": "whsec_…",
  "phone_number_id": "106540352242922",
  "waba_id": "102290129340398",
  "tenant_id": "a578246e-b97f-48e6-ae42-939ec3ccf917",
  "display_phone_number": "+91 98765 43210"
}

Store api_key and webhook_secret encrypted. WhaBuzz keeps only hashes and cannot show them again; if they are lost, the user connects again.

Statuserror.codeMeaning
400unknown_appapp is not a registered app.
400invalid_codeThe code, state or code_verifier is wrong or malformed. A wrong state or verifier also burns the code.
410code_usedThe code was already exchanged. WhaBuzz treats this as a leaked code and revokes the connection it created. Ask the user to connect again.
410code_expiredMore than 5 minutes passed. Ask the user to connect again.
410connection_goneThe user revoked or replaced the connection before you exchanged the code.
409connection_unavailableThe number was disconnected or the webhook endpoint deleted since the user approved.
429rate_limitedMore than 10 exchanges a minute from your IP. Retry after Retry-After seconds.

#What the key can do

The key is limited to the one number the user picked and to these scopes:

ScopeAllows
messagesPOST /v1/messages, GET /v1/messages/…
templates/v1/templates…, for the number's WhatsApp Business Account only
media/v1/media…
numbers:readGET /v1/numbers… (only this number is listed)
events:readGET /v1/events…, GET /v1/stream (workspace-wide)

Anything else answers 403 insufficient_scope: API keys, webhooks, billing, tenant settings, exports, other numbers. A request that names another number answers 404. A connected app's key cannot be rotated (409); connect again instead.

#Revoking and reconnecting

The user sees every connection under Settings, Connected apps in the console and can revoke it. Revoking deletes the key and the webhook endpoint at once: your next API call answers 401, and deliveries stop.

Connecting the same workspace to the same host again replaces the earlier connection: after the new exchange succeeds, the old key and endpoint are revoked. Use the newest credentials.

#Checklist

This page as Markdown: /guides/connect-apps.md. All docs in one file: /llms-full.txt. Status.