> ## Documentation Index
> Fetch the complete documentation index at: https://developer.z-api.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Connection SDK

> Drop-in WhatsApp connection modal to embed in your own software

## Overview

The **Connection SDK** is a ready-made modal you embed in your own software. Your customer clicks "connect", scans the QR code (or uses their phone number), and their Z-API instance connects — without you building any screen.

* Loads with a single `<script>` tag — exposes `window.ZAPIConnector`.
* Framework-agnostic (React, Vue, Angular, plain HTML…).
* Isolated via Shadow DOM: your site's CSS can't affect the modal, and the modal can't affect yours.
* Themeable (light/dark + colors) and translatable (pt/en, or your own strings).

<Card title="Try the playground" icon="flask" href="https://app.z-api.io/demo.html">
  Generate a token, pick the options and open the connector live at
  `https://app.z-api.io/demo.html`.
</Card>

<Info>
  The SDK covers the same scenarios as the Z-API panel: QR code, phone number,
  passkey authentication (extension) and migrating an already-connected WhatsApp
  Web session.
</Info>

***

## How it works

Integration has three parts: **your backend** generates a session token, **your site** loads the SDK and opens the connector with that token.

<Steps>
  <Step title="Your backend generates the token">
    Your server calls Z-API (with your Client-Token) and gets a short, disposable session token. See [generate the SDK token](/en/partner/sdk-connector-token).
  </Step>

  <Step title="Your site loads the SDK">
    Add the `<script>` tag that exposes `window.ZAPIConnector`.
  </Step>

  <Step title="Your site opens the connector">
    Call `ZAPIConnector.open({ token })` with the token returned by the backend.
  </Step>
</Steps>

***

## 1. Generate the token (on your backend)

The one talking to Z-API is **your backend**, because this call uses your **Client-Token**, which must never reach the browser.

```bash theme={"theme":{"light":"github-light","dark":"poimandres"}}
curl --location 'https://api.z-api.io/instances/{instanceId}/token/{instanceToken}/sdk-connector-token' \
--header 'Client-Token: YOUR_CLIENT_TOKEN'
```

**Response:**

```json theme={"theme":{"light":"github-light","dark":"poimandres"}}
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

Return that `token` to your frontend as-is. Full endpoint reference: [Generate the SDK token](/en/partner/sdk-connector-token).

<Warning>
  The `token` is generated by your backend and is single-use for the connector.
  Never expose your Client-Token or the instance credentials (instanceId and
  token) in the frontend.
</Warning>

***

## 2. Load the SDK

Add the `<script>` tag to your page. This URL **always serves the latest version** — you don't need to update anything when we ship fixes and improvements.

```html theme={"theme":{"light":"github-light","dark":"poimandres"}}
<script src="https://app.z-api.io/sdk.js" async></script>
```

This exposes `window.ZAPIConnector` globally.

***

## 3. Open the connector

When the customer clicks connect, fetch the token from your backend and call `open()`. It returns a `Promise<boolean>` that stays pending until the modal closes and resolves `true` if the channel connected:

```js theme={"theme":{"light":"github-light","dark":"poimandres"}}
async function connect(instanceId) {
  const { token } = await fetch(`/sdk-token/${instanceId}`).then((r) =>
    r.json(),
  );

  const connected = await ZAPIConnector.open({ token });
  if (connected) {
    refreshInstances();
  }
}
```

***

## Options

`ZAPIConnector.open(options)` accepts:

| Option      | Type                                | Description                                                                                                 |
| ----------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `token`     | `string` **(required)**             | Session token returned by your backend. Pass it as-is — the SDK picks the connection experience from it.    |
| `theme`     | `"light" \| "dark" \| ThemeOptions` | Color theme. Default: `"light"`. See [Themes](#themes).                                                     |
| `locale`    | `"pt" \| "en" \| string`            | UI language. Auto-detected from the browser when omitted.                                                   |
| `messages`  | `Partial<Messages>`                 | Override individual strings or translate to another language. See [Messages](#messages).                    |
| `methods`   | `{ qr?, phone?, migrate? }`         | Which connection options to show. Each is `true` by default. See [Connection methods](#connection-methods). |
| `container` | `string \| HTMLElement`             | Where to mount the modal. Default: `document.body`.                                                         |

***

## Themes

Pass a mode (`"light"` or `"dark"`), or a `ThemeOptions` object to override specific colors per mode:

```js theme={"theme":{"light":"github-light","dark":"poimandres"}}
ZAPIConnector.open({
  token,
  theme: {
    mode: "dark",
    light: { accent: "#25d366" },
    dark: { accent: "#00a884", surface: "#111b21" },
  },
});
```

Color tokens (`ThemeColors`, all optional):

| Token            | Description                                |
| ---------------- | ------------------------------------------ |
| `overlay`        | Dimmed backdrop behind the modal           |
| `surface`        | Modal card background                      |
| `surfaceAlt`     | Secondary background (tabs, fields, boxes) |
| `text`           | Primary text color                         |
| `textMuted`      | Secondary text color                       |
| `border`         | Border color                               |
| `accent`         | Accent color (buttons, links, highlights)  |
| `accentContrast` | Text color on top of the accent color      |

***

## Language

Built-in languages: **`pt`** and **`en`** (detected from `navigator.language`). Force one with `locale`:

```js theme={"theme":{"light":"github-light","dark":"poimandres"}}
ZAPIConnector.open({ token, locale: "en" });
```

To tweak wording or translate to a non-built-in language, use `messages` — a partial map merged over the selected locale. Pass only the keys you want to change:

```js theme={"theme":{"light":"github-light","dark":"poimandres"}}
ZAPIConnector.open({
  token,
  messages: {
    title: "Connect your number",
    subtitle: "Point your WhatsApp camera at the code.",
  },
});
```

***

## Connection methods

By default the modal shows QR code, phone number and the migration link. Use `methods` to show only what you want:

```js theme={"theme":{"light":"github-light","dark":"poimandres"}}
ZAPIConnector.open({ token, methods: { phone: false, migrate: false } });
```

| Key       | Description                                                       |
| --------- | ----------------------------------------------------------------- |
| `qr`      | QR code tab. Default `true`.                                      |
| `phone`   | Phone number tab. Default `true`.                                 |
| `migrate` | Link to migrate an existing WhatsApp Web session. Default `true`. |

<Info>
  When only one method is enabled, the tabs are hidden (it goes straight to it).
  If you disable QR and phone at the same time, the SDK re-enables both so the
  modal is never left without a way to connect.
</Info>

***

## Events

Track the connection lifecycle with `on` / `off`:

```js theme={"theme":{"light":"github-light","dark":"poimandres"}}
ZAPIConnector.on("connected", () => refreshInstances());
ZAPIConnector.on("status", ({ status }) => console.log(status));

ZAPIConnector.off("connected", handler);
```

| Event          | Payload       | Fired when                                                 |
| -------------- | ------------- | ---------------------------------------------------------- |
| `connected`    | `{ phone? }`  | the channel connected                                      |
| `disconnected` | `{ reason? }` | it dropped or was disconnected                             |
| `qr`           | `{ base64 }`  | a new QR code was rendered                                 |
| `status`       | `{ status }`  | status changed (`"qr"`, `"connected"` or `"disconnected"`) |
| `error`        | `{ error }`   | an error occurred                                          |
| `close`        | –             | the user closed the modal                                  |

***

## Methods

| Method                | Returns            | Description                                                     |
| --------------------- | ------------------ | --------------------------------------------------------------- |
| `open(options)`       | `Promise<boolean>` | Opens the modal; resolves when it closes (`true` if connected). |
| `close()`             | `void`             | Closes the modal programmatically.                              |
| `on(event, handler)`  | `void`             | Subscribe to an event.                                          |
| `off(event, handler)` | `void`             | Unsubscribe.                                                    |

***

## Messages

Every string in the modal can be overridden via `messages`. Below, each key, its default English value and what it's for. Pass only the keys you want to change.

### Home screen and QR code

| Key         | Default                                       | Description               |
| ----------- | --------------------------------------------- | ------------------------- |
| `title`     | Connect your WhatsApp                         | Modal title               |
| `subtitle`  | Scan the QR code with your phone to connect.  | Subtitle below the title  |
| `step1`     | Open **WhatsApp** on your phone               | QR instructions step 1    |
| `step2`     | Tap **Settings**, then **Linked devices**     | QR instructions step 2    |
| `step3`     | Tap **Link a device** and scan this code      | QR instructions step 3    |
| `qrLoading` | Generating QR code…                           | Text while the QR loads   |
| `qrError`   | Could not load the QR code. Please try again. | Error loading the QR      |
| `close`     | Close                                         | Close button label (aria) |
| `tabQr`     | QR code                                       | QR code tab label         |
| `tabPhone`  | Phone number                                  | Phone number tab label    |

### Phone connection (web)

| Key                | Default                                               | Description                        |
| ------------------ | ----------------------------------------------------- | ---------------------------------- |
| `phoneHint`        | Enter your WhatsApp number to receive a pairing code. | Phone tab instruction              |
| `countrySearch`    | Search country                                        | Country search placeholder         |
| `phonePlaceholder` | Phone number                                          | Phone field placeholder            |
| `submit`           | Continue                                              | Button to generate the code        |
| `phoneSending`     | Generating code…                                      | Button state while generating      |
| `codeHint`         | Enter this code in WhatsApp:                          | Instruction above the pairing code |
| `codeStep3`        | Tap **Link with phone number** and enter the code     | Step to enter the code in WhatsApp |
| `codeBack`         | Use another number                                    | Back to enter a different number   |

### Phone connection flow (mobile instances)

| Key               | Default                                                                       | Description                       |
| ----------------- | ----------------------------------------------------------------------------- | --------------------------------- |
| `mVerifying`      | Checking number…                                                              | Verifying the entered number      |
| `mMethodHint`     | How do you want to receive the code?                                          | Choose the code delivery method   |
| `mSms`            | SMS                                                                           | Receive via SMS                   |
| `mCall`           | Call                                                                          | Receive via call                  |
| `mWhatsapp`       | WhatsApp                                                                      | Receive via WhatsApp              |
| `mSending`        | Sending…                                                                      | Sending the code                  |
| `mCodeHint`       | Enter the code you received                                                   | Prompt to enter the received code |
| `mWaOldHint`      | Open WhatsApp on your phone — you'll receive the code there. Enter it below.  | WhatsApp method instruction       |
| `mConfirm`        | Confirm                                                                       | Confirm the code                  |
| `mConfirming`     | Confirming…                                                                   | State while confirming            |
| `mCaptchaHint`    | Type the characters in the image                                              | Captcha instruction               |
| `mSecurityHint`   | Enter your PIN (two-step verification)                                        | Two-step PIN instruction          |
| `mForgotPin`      | Forgot PIN                                                                    | PIN recovery link                 |
| `mConfirmOnPhone` | Confirm on your phone, then tap Confirm                                       | Confirmation on the device        |
| `mError`          | Something went wrong. Please try again.                                       | Generic error                     |
| `mWrongCode`      | Wrong code. Try again.                                                        | Wrong code entered                |
| `mBlocked`        | This number is blocked by WhatsApp.                                           | Number blocked                    |
| `mUnblock`        | Request unblock                                                               | Button to request unblock         |
| `mNoRoutes`       | We couldn't send the code right now. Check the number and try another method. | No delivery route available       |
| `mRateLimit`      | Too many attempts. Please wait before trying again.                           | Attempt limit reached             |
| `mBanned`         | This number is banned.                                                        | Number banned                     |
| `mBannedText`     | Describe why this number should be unbanned:                                  | Appeal form text                  |
| `mSend`           | Send                                                                          | Send the appeal                   |
| `mInReview`       | Your appeal is under review by WhatsApp.                                      | Appeal under review               |
| `mPinSent`        | We've sent PIN recovery instructions.                                         | Recovery instructions sent        |
| `mPhoneOffline`   | Phone offline — messages may be delayed.                                      | Phone offline warning             |

### Session migration

| Key            | Default                                                              | Description                          |
| -------------- | -------------------------------------------------------------------- | ------------------------------------ |
| `migrateOr`    | or                                                                   | Separator before the migration link  |
| `migrateLink`  | Click here to migrate an already-connected WhatsApp Web session      | Button that opens the migration flow |
| `migrateHint`  | Migrate your WhatsApp Web session with the extension. Use this code: | Migration screen instruction         |
| `migrateStep1` | Install the **Z-API Connector** extension                            | Migration step 1                     |
| `migrateStep2` | Open **web.whatsapp.com** already connected on your computer         | Migration step 2                     |
| `migrateStep3` | Open the extension and enter the **code above**                      | Migration step 3                     |
| `migrateBack`  | Back                                                                 | Back from the migration screen       |

### Connected

| Key              | Default        | Description                       |
| ---------------- | -------------- | --------------------------------- |
| `connectedTitle` | Connected      | Success screen title              |
| `disconnect`     | Disconnect     | Button to disconnect the instance |
| `disconnecting`  | Disconnecting… | State while disconnecting         |

### Passkey authentication (extension)

| Key                  | Default                                                             | Description                       |
| -------------------- | ------------------------------------------------------------------- | --------------------------------- |
| `challengeText`      | Confirm the authentication on your device to connect this instance. | Authentication screen instruction |
| `challengeButton`    | Resolve authentication                                              | Button to resolve authentication  |
| `challengeSolving`   | Authenticating…                                                     | State while authenticating        |
| `challengeCancel`    | Cancel                                                              | Cancel authentication             |
| `installTitle`       | Passkey authentication                                              | Extension install screen title    |
| `installText`        | The extension confirms your biometrics on this device to connect.   | Extension description             |
| `installStep1`       | Install the extension and add it to your browser                    | Install step 1                    |
| `installStep2`       | Come back to this window — it continues **automatically**           | Install step 2                    |
| `installButton`      | Install extension                                                   | Generic install button            |
| `installChrome`      | Install on Chrome                                                   | Install-on-Chrome button          |
| `installFirefox`     | Install on Firefox                                                  | Install-on-Firefox button         |
| `unsupportedBrowser` | Open this page in Chrome or Firefox to connect with a passkey.      | Warning on an unsupported browser |

***

## Try the playground

Open the [SDK playground](https://app.z-api.io/demo.html) to generate a token, adjust theme, language and methods, and see the real connector in action.
