> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kapso.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Setup links

> Customize the WhatsApp onboarding experience

Setup links let customers connect their WhatsApp Business accounts to your platform. Send a link, customer clicks, logs in with Facebook, and you're connected.

## Quick start

Create a basic setup link:

```bash theme={null}
curl -X POST https://api.kapso.ai/platform/v1/customers/{customer_id}/setup_links \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "setup_link": {
      "success_redirect_url": "https://your-app.com/whatsapp/success",
      "failure_redirect_url": "https://your-app.com/whatsapp/failed",
      "meta_billing_mode": "partner_managed"
    }
  }'
```

Response includes a `url` you send to your customer. Links expire after 30 days.

See [Connection detection](/docs/platform/detecting-whatsapp-connection) for handling successful connections.

<Warning>
  Do not choose **Display name only** inside Meta embedded signup. That option can create a WhatsApp profile with a generic, limited Meta-managed number, commonly a `+1 555...` number, instead of the intended setup-link number. For Kapso onboarding, use the connection type selected in the setup link: **Dedicated** for API-only numbers or **Coexistence** for WhatsApp Business App pairing.
</Warning>

If you choose **Display name only**, treat the connection as misconfigured. You may have connected a limited Meta-managed number rather than the production WhatsApp number. These numbers can stop working after about 5 messages until Meta approves the display name, and display-name approval can be slow or deferred. You may need to delete or disconnect that profile and restart from a new setup link.

## Connection types

Customers can connect their WhatsApp in two ways:

**Coexistence** - Keep using WhatsApp Business app alongside API

* 5 messages/second
* App stays active
* Good for small businesses

**Dedicated** - API-only access for automation

* Up to 1000 messages/second
* No app access
* Built for scale

## Redirect URLs

Configure where customers land after completing or failing setup:

```json theme={null}
{
  "setup_link": {
    "success_redirect_url": "https://your-app.com/whatsapp/success",
    "failure_redirect_url": "https://your-app.com/whatsapp/failed"
  }
}
```

Both URLs receive query parameters with setup details. See [Connection detection](/docs/platform/detecting-whatsapp-connection) for handling redirects and available parameters.

## Connection type control

### Show both options (default)

```json theme={null}
{
  "setup_link": {
    "allowed_connection_types": ["coexistence", "dedicated"]
  }
}
```

### Coexistence only

For customers using WhatsApp Business app:

```json theme={null}
{
  "setup_link": {
    "allowed_connection_types": ["coexistence"]
  }
}
```

### Dedicated only

For API-only automation:

```json theme={null}
{
  "setup_link": {
    "allowed_connection_types": ["dedicated"]
  }
}
```

When you provide one option, it auto-selects.

## Meta billing policy

Choose how Meta's message fees should be paid after the customer connects their WABA:

```json theme={null}
{
  "setup_link": {
    "meta_billing_mode": "partner_managed"
  }
}
```

| Value              | Behavior                                                               |
| ------------------ | ---------------------------------------------------------------------- |
| `customer_managed` | The customer pays Meta directly. This is the default.                  |
| `partner_managed`  | Kapso pays Meta and deducts the cost from the project's Kapso credits. |

`meta_billing_mode` can be set only when creating the link. The response echoes the selected value. Create a new link to change the policy.

The hosted setup page does not let the customer change this policy or add billing disclosure. Explain the billing arrangement to your customer before sharing the link. See [Meta message billing](/docs/whatsapp/meta-message-billing) for the customer-facing differences.

Kapso checks WABA-level eligibility after Meta returns the connected account. If Kapso billing cannot be attached, number setup still completes and the project owner sees a retryable warning in Kapso. A completed setup link or `meta_billing_mode: "partner_managed"` does not confirm that Kapso billing was attached.

## Theme customization

Match your brand colors:

```json theme={null}
{
  "setup_link": {
    "theme_config": {
      "primary_color": "#3b82f6",
      "background_color": "#ffffff",
      "text_color": "#1f2937",
      "muted_text_color": "#64748b",
      "card_color": "#f9fafb",
      "border_color": "#e5e7eb"
    }
  }
}
```

All colors use hex format (#RRGGBB).

## Phone number provisioning

Automatically provision a phone number for customers:

```json theme={null}
{
  "setup_link": {
    "provision_phone_number": true,
    "phone_number_country_isos": ["US"]
  }
}
```

### Country support

* Default Kapso provisioning: `["US"]`. See [Instant setup](/docs/platform/phone-numbers/instant-setup)
* For your own Twilio account, multi-country support, and project-owned pre-verified pools, see [Bring your own Twilio](/docs/platform/phone-numbers/bring-your-own-twilio)

```json theme={null}
{
  "setup_link": {
    "provision_phone_number": true,
    "phone_number_country_isos": ["US", "CL"]
  }
}
```

If the requested country has a ready project pool, setup can use a pre-verified number. If that country has no pool, or the pool is empty, the setup link still works and falls back to live provisioning.

When `provision_phone_number` is enabled, complete Meta's phone-number step with the Kapso-provided, BSP-provided, or project-pool number shown by the flow. Do not choose **Display name only** because the connected number may be a generic, limited Meta-managed number rather than the provisioned number.

## Reconnect existing numbers

When a customer's WhatsApp connection breaks (token revoked, Meta de-auth, password change), generate a setup link scoped to a specific phone number they already have on Kapso:

```json theme={null}
{
  "setup_link": {
    "reconnect_phone_number": "+14155551234"
  }
}
```

Kapso looks up the customer's existing WhatsApp config matching that number, then forces the setup flow to refresh credentials for the same WABA + phone number. Behavior:

* The number must already exist on a production WhatsApp config for this customer.
* `provision_phone_number` is forced to `false`. Passing `true` returns `422`.
* `allowed_connection_types` is locked to `["dedicated"]` or `["coexistence"]` to match the existing config. Passing a different value returns `422`.
* During Meta's embedded signup, the phone number selector is constrained to the matching number — if the customer connects a different account or number, setup fails.

If no config matches, the API returns `422` with `reconnect_phone_number must match an existing WhatsApp config for this customer`. If multiple configs match the same display number, the API returns `422` and you'll need to resolve the duplicates first.

## Full example

```javascript theme={null}
const setupLink = await fetch(
  `https://api.kapso.ai/platform/v1/customers/${customerId}/setup_links`,
  {
    method: 'POST',
    headers: {
      'X-API-Key': 'YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      setup_link: {
        success_redirect_url: 'https://app.example.com/onboarding/complete',
        failure_redirect_url: 'https://app.example.com/onboarding/error',
        meta_billing_mode: 'partner_managed',
        allowed_connection_types: ['dedicated'],
        provision_phone_number: true,
        phone_number_country_isos: ['US'],
        theme_config: {
          primary_color: '#10b981',
          background_color: '#ffffff',
          text_color: '#111827'
        }
      }
    })
  }
);

// Send link to customer
await sendEmail(customer.email, {
  subject: 'Connect your WhatsApp',
  body: `Click here to connect: ${setupLink.data.url}`
});
```

## Link management

### List all links

```bash theme={null}
curl https://api.kapso.ai/platform/v1/customers/{customer_id}/setup_links \
  -H "X-API-Key: YOUR_API_KEY"
```

### Automatic revocation

Creating a new link revokes the previous one. Only one active link per customer.

### Expiration

Links expire after 30 days. Check the `expires_at` field.
