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:
| Key | Header | Use |
|---|---|---|
wab_pub_... | x-wabery-publishable-key | Browser-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:
| Status | Meaning |
|---|---|
PENDING | The customer has not completed the WhatsApp step yet. |
JOINED | The customer sent the token and is connected. |
REJECTED | Wabery rejected the registration, with rejection_reason when available. |
EXPIRED | The 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.