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

# Quickstart

> Mint your first Personal Access Token and send a WhatsApp message through the Keebai public API in under five minutes.

Goes from signup to first successful API call.

## Before you start

* A Keebai account at [app.keebai.com](https://app.keebai.com).
* The `developer.manage_tokens` permission on your role. If your account doesn't show **API Keys**, ask your tenant admin to grant it under **System Settings → Roles**.
* At least one WhatsApp channel connected and one template approved by Meta.
* Anything that speaks HTTP — `curl`, Postman, Insomnia, or your favorite SDK.

## 1. Create a token

<Steps>
  <Step title="Open API Keys">
    Go to **System Settings → API Keys** in the dashboard: [app.keebai.com/system-settings/api-keys](https://app.keebai.com/system-settings/api-keys).

    Not seeing it? Your role is missing `developer.manage_tokens`. Ask an admin.
  </Step>

  <Step title="Create a new key">
    Click **Create API Key**. Three fields:

    * **Name** — anything descriptive. `Sales backend`, `Nightly reports`, `Local dev`.
    * **Permissions (scopes)** — only the ones the token will actually use. For this quickstart, pick `messages:send` and `templates:read`.
    * **Expiration** *(optional)* — we recommend 90 days. Leave blank for no expiry.
  </Step>

  <Step title="Copy the token">
    Keebai shows the token **once**. Format: `kbai_pk_<64 hex chars>`.

    <Warning>
      This is the only time you'll see the full token. Store it in a secret manager (1Password, AWS Secrets Manager, GitHub Actions secrets, a local `.env`). If you lose it, you'll have to revoke and create a new one.
    </Warning>
  </Step>
</Steps>

## 2. List your approved templates

To send a template you need its `template_name`, `language`, and variable names. Pull them with `GET /v1/templates`:

```bash theme={null}
curl https://api.keebai.com/v1/templates \
  -H "Authorization: Bearer kbai_pk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

Expected response (HTTP 200):

```json theme={null}
{
  "items": [
    {
      "id": "65f3a1b2c3d4e5f6a7b8c9d0",
      "name": "welcome_v2",
      "language": "es",
      "status": "APPROVED",
      "category": "MARKETING",
      "parameter_format": "NAMED",
      "variables": ["name", "amount"]
    }
  ],
  "page": 0,
  "limit": 50,
  "total": 1
}
```

## 3. Send your first message

Grab the `phone_number_id` of your channel from [`GET /v1/whatsapp/numbers`](/dev/endpoints/whatsapp-numbers), then call `POST /v1/messages` with a `template` message:

```bash theme={null}
curl -X POST https://api.keebai.com/v1/messages \
  -H "Authorization: Bearer kbai_pk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "whatsapp",
    "phone_number_id": "100000000000001",
    "to": "+15551234567",
    "message": {
      "type": "template",
      "name": "welcome_v2",
      "language": "en_US",
      "variables": {
        "name": "Alex",
        "amount": "1500"
      }
    }
  }'
```

Expected response (HTTP 202):

```json theme={null}
{
  "message_id": "wamid.HBgL...",
  "status": "sent",
  "sent_at": "2026-05-13T00:00:00.000Z"
}
```

The message is on its way — WhatsApp usually delivers within seconds.

## 4. If something breaks

| Status                                 | Meaning                                                                           | What to do                                                                                                           |
| -------------------------------------- | --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `401 Unauthorized`                     | Token is invalid, revoked, or expired.                                            | Check you copied the full token (`kbai_pk_` prefix included). If it's not in your active token list, mint a new one. |
| `403 Forbidden` (`INSUFFICIENT_SCOPE`) | Token doesn't carry the scope the endpoint needs.                                 | Mint a new token with the missing scopes checked.                                                                    |
| `400 Bad Request`                      | Body is malformed or `phone_number_id` is off.                                    | Check the JSON against the [endpoint contract](/dev/endpoints/messages-send).                                        |
| `429 Too Many Requests`                | You hit the rate limit (60 req/min, 200 req/hour, **1,000 req/day** per project). | Read `Retry-After-<window>` and wait. See [Rate limits](/dev/rate-limits).                                           |

## 5. Where to next

<CardGroup cols={2}>
  <Card title="TypeScript SDK" icon="code" href="/dev/sdks/typescript">
    Skip writing HTTP by hand — use the typed client.
  </Card>

  <Card title="CLI" icon="terminal" href="/dev/sdks/cli">
    `keebai login` and `keebai whatsapp messages send` from your shell.
  </Card>

  <Card title="Manage tokens" icon="key" href="/dev/api-keys">
    Create, list, revoke, and rotate tokens.
  </Card>

  <Card title="Scopes" icon="shield" href="/dev/scopes">
    What each scope does and when to use it.
  </Card>

  <Card title="Bulk send" icon="paper-plane" href="/dev/endpoints/messages-bulk">
    Send the same template to thousands of recipients and track status.
  </Card>

  <Card title="OpenAPI spec" icon="file-code" href="https://api.keebai.com/v1/docs">
    Swagger UI with every endpoint, schema, and example.
  </Card>
</CardGroup>
