Skip to main content
You have two ways to detect when customers connect their WhatsApp account through setup links.

1. Project webhooks

Configure a project webhook to receive the whatsapp.phone_number.created event. This is the recommended approach for server-to-server notifications.

Setup

  1. Open Integrations → Webhooks
  2. Go to the Platform webhooks tab
  3. Click Add Webhook
  4. Enter your HTTPS endpoint URL
  5. Copy the auto-generated secret key
  6. Subscribe to whatsapp.phone_number.created event

Webhook payload

{
  "phone_number_id": "123456789012345",
  "project": {
    "id": "990e8400-e29b-41d4-a716-446655440004"
  },
  "customer": {
    "id": "880e8400-e29b-41d4-a716-446655440003"
  }
}

Handle the webhook

app.post('/webhooks/project', async (req, res) => {
  const { event, data } = req.body;

  if (event === 'whatsapp.phone_number.created') {
    const { phone_number_id, customer } = data;

    // Update your database
    await db.customers.update(customer.id, {
      phone_number_id,
      whatsapp_connected: true,
      connected_at: new Date()
    });

    // Trigger welcome flow
    await sendWelcomeMessage(phone_number_id, customer.id);
  }

  res.status(200).send('OK');
});
See webhooks documentation for signature verification and best practices.

2. Success redirect URL

When customers complete WhatsApp setup, they’re redirected to your success_redirect_url with query parameters.

Setup

When creating a setup link, provide redirect URLs:
const setupLink = await fetch('https://api.kapso.ai/platform/v1/customers/customer-123/setup_links', {
  method: 'POST',
  headers: {
    'X-API-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    setup_link: {
      success_redirect_url: 'https://your-app.com/whatsapp/success',
      failure_redirect_url: 'https://your-app.com/whatsapp/failed'
    }
  })
});

Query parameters

After successful setup, customer is redirected to:
https://your-app.com/whatsapp/success?setup_link_id=...&status=completed&phone_number_id=123456789012345&business_account_id=...&whatsapp_config_id=...&provisioned_phone_number_id=...&display_phone_number=%2B15551234567
Parameters:
  • setup_link_id - UUID of the setup link
  • status - Always completed for success
  • phone_number_id - WhatsApp phone number ID (primary identifier)
  • business_account_id - Meta WABA ID (if available)
  • whatsapp_config_id - Legacy identifier (provided for backward compatibility)
  • provisioned_phone_number_id - Kapso phone number ID (if provisioning was used)
  • display_phone_number - E.164 formatted phone number (URL encoded)

Handle the redirect

app.get('/whatsapp/success', async (req, res) => {
  const {
    setup_link_id,
    status,
    phone_number_id,
    business_account_id,
    whatsapp_config_id, // Legacy, use phone_number_id instead
    provisioned_phone_number_id,
    display_phone_number
  } = req.query;

  // Update your database
  await db.customers.update({
    phone_number_id,
    business_account_id,
    display_phone_number: decodeURIComponent(display_phone_number),
    whatsapp_connected: true,
    connected_at: new Date()
  });

  // Show success page to customer
  res.render('whatsapp-connected', {
    phoneNumber: decodeURIComponent(display_phone_number)
  });
});
These parameters are convenience identifiers to avoid extra API fetches. Use phone_number_id as the primary identifier.

Failure redirect

If setup fails, customer is redirected to your failure_redirect_url:
https://your-app.com/whatsapp/failed?setup_link_id=...&error_code=facebook_auth_failed
Error codes:
  • facebook_auth_failed - Facebook login cancelled
  • phone_verification_failed - Phone verification failed
  • waba_limit_reached - Too many WhatsApp accounts
  • token_exchange_failed - OAuth failed
  • link_expired - Link expired (30 days)
  • already_used - Link already used
app.get('/whatsapp/failed', (req, res) => {
  const { setup_link_id, error_code } = req.query;

  // Log failure for monitoring
  await logSetupFailure(setup_link_id, error_code);

  // Show user-friendly error message
  res.render('whatsapp-setup-failed', {
    errorMessage: getErrorMessage(error_code)
  });
});

Choosing the right method

Use project webhooks when:
  • You need server-to-server notification
  • Customer doesn’t need immediate visual feedback
  • You’re building automated onboarding flows
  • You need to process the connection before showing UI
Use success redirect when:
  • Customer needs immediate confirmation in your app
  • You want to show a custom success page
  • You’re building a wizard-style onboarding flow
  • You need to collect additional information after connection
Use both:
  • Webhook for backend processing (database updates, welcome messages)
  • Redirect for frontend experience (success page, next steps)