> ## 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.

# Kapso infrastructure

> Connect customers through setup links or embed WhatsApp onboarding in your product

<span id="kapso-runs-messaging" />

Use this path after [setting up MPS](/docs/platform/tech-providers/multi-partner-solutions) with **Messages processed by: Kapso**. Kapso runs messaging and completes onboarding for you.

## At a glance

1. **Choose the onboarding experience:** [send a hosted setup link](#send-a-setup-link) or [embed onboarding in your app](#embed-in-your-app) with `@kapso/sdk`.
2. [Create a setup link for each customer](/docs/platform/setup-links/create-and-configure), choosing the connection type and who pays Meta fees.
3. **Let the customer connect:** share the link's URL, or [pass its token to the SDK](#connect-from-the-browser).
4. [Confirm the connection and billing](#confirm-connection-and-billing) through a completion webhook and a funding check if you selected Kapso credits.

Both options use a setup link. Hosting onboarding on your domain does not change who processes messages: Kapso still does.

## Send a setup link

The customer completes onboarding on a page hosted by Kapso. No frontend SDK is needed.

1. Create a [customer setup link](/docs/platform/setup-links/create-and-configure). Choose `customer_managed` for direct Meta billing or `partner_managed` to use Kapso credits.
2. Send the returned `url` to the customer or open it from your product.
3. [Confirm the connection and billing](#confirm-connection-and-billing) after the customer finishes.

## Embed in your app

Use `@kapso/sdk` to open onboarding directly from your product. Your backend creates the same setup link, but passes its token to the browser instead of sharing its URL. Never expose your Kapso API key.

<Warning>
  `@kapso/sdk` requires an active Kapso [Multi-partner Solution](/docs/platform/tech-providers/multi-partner-solutions). It is not a generic embedded signup SDK and does not work with standalone custom Meta apps.
</Warning>

### Requirements

* an active Multi-partner Solution with **Messages processed by: Kapso**
* the browser origin in the setup link's `allowed_origins`
* the same HTTPS domain [added in Meta's Facebook Login for Business settings](/docs/platform/onboard-customers-own-meta-app#add-domains-for-embedded-signup)

The setup link must allow exactly one connection type: `dedicated` or `coexistence`. Create separate setup links if your product offers both paths.

### Install the SDK

<CodeGroup>
  ```bash npm theme={null}
  npm install @kapso/sdk
  ```

  ```bash yarn theme={null}
  yarn add @kapso/sdk
  ```

  ```bash pnpm theme={null}
  pnpm add @kapso/sdk
  ```
</CodeGroup>

### Create a setup link on your backend

Keep your Kapso API key on the server. Create one setup link for the customer and specify every browser origin that may launch it.

<CodeGroup>
  ```bash cURL 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": {
        "allowed_origins": ["https://app.example.com"],
        "allowed_connection_types": ["dedicated"],
        "meta_billing_mode": "partner_managed"
      }
    }'
  ```

  ```javascript JavaScript theme={null}
  const res = 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: {
          allowed_origins: ['https://app.example.com'],
          allowed_connection_types: ['dedicated'],
          meta_billing_mode: 'partner_managed'
        }
      })
    }
  );

  const { data } = await res.json();
  ```
</CodeGroup>

Return only `data.token` to your frontend. Do not expose your Kapso API key.

### Connect from the browser

```typescript theme={null}
import { createWhatsAppOnboarding } from '@kapso/sdk';

const whatsapp = await createWhatsAppOnboarding({ token: setupLinkToken });

connectButton.onclick = async () => {
  const connection = await whatsapp.connect();
  onConnected(connection);
};
```

The resolved connection includes:

```typescript theme={null}
type WhatsAppConnection = {
  whatsappConfigId: string;
  wabaId: string;
  phoneNumberId: string;
};
```

The SDK validates the token and browser origin, loads the Meta JavaScript SDK, runs embedded signup with your Multi-partner Solution, and resolves once Kapso confirms the connection.

### Configure the setup path

The setup link controls the customer experience:

* `allowed_connection_types: ["dedicated"]` — API-only WhatsApp number
* `allowed_connection_types: ["coexistence"]` — keep using WhatsApp Business App
* `provision_phone_number: true` — use a Kapso-provided or project-pool number
* `meta_billing_mode: "partner_managed"` — use Kapso credits for Meta fees

Set these on the server when you create the link. The browser receives only the setup token.

### Handle cancellation and errors

Catch SDK initialization failures separately from connection failures. Keep `connect()` inside the button's click handler so the browser allows Meta's popup.

```typescript theme={null}
import {
  createWhatsAppOnboarding,
  WhatsAppOnboardingError,
} from '@kapso/sdk';

connectButton.disabled = true;

try {
  const whatsapp = await createWhatsAppOnboarding({ token: setupLinkToken });
  connectButton.disabled = false;

  connectButton.onclick = async () => {
    connectButton.disabled = true;

    try {
      onConnected(await whatsapp.connect());
    } catch (error) {
      if (!(error instanceof WhatsAppOnboardingError && error.code === 'user_cancelled')) {
        showConnectionError();
      }
    } finally {
      connectButton.disabled = false;
    }
  };
} catch {
  showConnectionError();
}
```

Call `whatsapp.destroy()` if your application removes the onboarding component before setup completes.

<span id="confirm-connection-on-your-backend" />

## Confirm connection and billing

For either onboarding option, use the setup redirect or SDK result for immediate UI feedback. For server-side reliability, subscribe to Kapso project webhooks and listen for `whatsapp.phone_number.created`.

If you selected `partner_managed`, also confirm that managed funding is verified before sending paid messages. A successful WhatsApp connection alone does not confirm funding. Resolve any billing attention state first.

See [Detect connection](/docs/platform/setup-links/detect-connection) and [Webhooks](/docs/platform/webhooks/overview).

## You run messaging

If your MPS uses **Messages processed by: Your infrastructure**, follow [Your infrastructure](/docs/platform/tech-providers/your-infrastructure). That path uses Meta's SDK, not `@kapso/sdk`.
