Registration intents

Create single-use WhatsApp registration links with publishable keys.

Registration intents let you enroll end customers from your own product without exposing a secret API key. Wabery returns a single-use wa.me link. The customer taps it, sends the prefilled token to your Wabery WhatsApp number, and Wabery links that WhatsApp identity to your customer_reference.

Use this for self-serve onboarding, account linking, or "connect your WhatsApp" flows in your app.

Authentication

Registration intents support two key types:

KeyHeaderUse
wab_pub_...x-wabery-publishable-keyBrowser-safe widget calls. Metadata is treated as untrusted.
wab_live_...Authorization: Bearer ...Server-side minting with the registrations:create scope.

Polling an intent with GET /registration-intents/{id} works with either key type. The SDK and CLI automatically send x-wabery-publishable-key when the key starts with wab_pub_; otherwise they use Bearer auth.

Create an intent

import { Wabery } from "@wabery/sdk";

const wabery = new Wabery({ apiKey: "wab_pub_..." });

const intent = await wabery.registrationIntents.create({
	customerReference: "user_123",
	metadata: { plan: "starter" },
});

console.log(intent.wa_link);
WABERY_API_KEY="wab_pub_..." wabery registration-intents create \
  --customer-reference "user_123" \
  --metadata '{"plan":"starter"}'
curl https://api.wabery.com/v1/registration-intents \
  -H "x-wabery-publishable-key: $WABERY_PUBLISHABLE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_reference": "user_123",
    "metadata": { "plan": "starter" }
  }'

The response includes:

{
  "object": "registration_intent",
  "id": "reg_...",
  "token": "wjr_...",
  "status": "PENDING",
  "wa_link": "https://wa.me/...",
  "expires_at": "2026-06-27T00:00:00.000Z"
}

Send the customer to wa_link. Do not edit the prefilled message; Wabery uses the token to match the customer to the intent.

Poll status

const status = await wabery.registrationIntents.get(intent.id);

if (status.status === "JOINED") {
	// The customer is connected. Future message.received events include
	// customer_reference/contact_reference for correlation.
}
wabery registration-intents get "reg_..."
curl https://api.wabery.com/v1/registration-intents/reg_... \
  -H "x-wabery-publishable-key: $WABERY_PUBLISHABLE_KEY"

Server-side polling can use a scoped secret key instead:

curl https://api.wabery.com/v1/registration-intents/reg_... \
  -H "Authorization: Bearer $WABERY_API_KEY"

Statuses are:

StatusMeaning
PENDINGThe customer has not completed the WhatsApp step yet.
JOINEDThe customer sent the token and is connected.
REJECTEDWabery rejected the registration, with rejection_reason when available.
EXPIREDThe intent expired before the customer joined.

Webhooks

When the customer joins, Wabery emits a signed participant.joined webhook. The payload includes your customer_reference and metadata so you can link the WhatsApp contact to your own user record.

Use Webhooks & events to verify the signature and handle the event.

Registration intents | Wabery Docs | Wabery