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

# Build your own integration

> Connect a platform you run to Tawked: each merchant connects their own application with its keys, or you hold one partner account for all of them. How to choose, and how to build each.

You run a platform, a plugin or a connector, and your merchants want Tawked in it. There are two ways to build it. The question that decides is who holds the Tawked account: each merchant, or you.

| | The merchant's own application | The Partner API |
| - | - | - |
| Who holds the Tawked account and its balance | Each merchant | You, for all your merchants |
| Who signs up and connects WhatsApp | The merchant, in the Tawked console | You provision applications by API |
| Products | Tawked Verify and Tawked Notifications | Tawked Verify only, for client applications |
| The key your code holds | The merchant's application key, pasted into your settings | Your one partner key (`tk_partner_`) |
| Who pays | The merchant, from their own balance | You, from your balance |
| Example | A WordPress plugin, a store app, a connector a merchant installs | A platform that offers sign-in codes to every merchant under one bill |

Never ask a merchant for a partner key, and never ship your partner key to a merchant's server. A partner key acts for every application of your account.

## Model A: the merchant's own application

The merchant signs up to Tawked, creates an application with the products they need, and gives your integration that application's keys. Your code calls the public API exactly as any developer does. Every limit, price and review rule is the merchant's own.

<Steps>
  <Step title="Ask for keys with the least access">
    Tell the merchant which access to give the key. They choose it on **Application settings → API keys**, **Create a key**, under **Access**: **Custom**, then a level per product (see [Key access](/authentication#key-access)):

    | Your integration | Access |
    | - | - |
    | Sends and checks codes | Verify: **Send and check** (`verify:send`) |
    | Only checks codes another system started | Verify: **Check only** (`verify:check`) |
    | Sends WhatsApp messages | Notifications: **Send** (`notifications:send`) |
    | Reads templates or message statuses | Notifications: **Read only** (`notifications:read`) |

    A key is created by the owner, or an admin or developer whose access covers the whole application. It shows once. Store it as a secret on the merchant's server: encrypted at rest, never printed back in full, never sent to a browser.
  </Step>

  <Step title="Take a test key during review">
    A live key sends codes only once the application is approved. Until then, a test key (`tk_test_`) sends real codes, only to the account owner's verified phone, stamped as a test, and capped per application (see [Testing and the sandbox](/sandbox)). Give your settings a field for each key and a switch for "use the test key for codes". WhatsApp has no test key: the live key sends WhatsApp messages while the application is in review or approved.
  </Step>

  <Step title="Identify your integration">
    Send a `User-Agent` that names your integration and its version, such as `YourPlatform-Tawked/1.4.0`. Send `Authorization: Bearer <key>` and JSON bodies.
  </Step>

  <Step title="Add a Test connection button">
    Let the merchant check the keys without sending anything. Probe with a resend of the all-zeros id: it needs the scope that sends, checks the application's state, and sends nothing.

    ```bash title="Test connection" theme={"dark"}
    curl -X POST https://tawked.com/v1/verify/00000000-0000-0000-0000-000000000000/resend \
      -H "Authorization: Bearer $TAWKED_KEY" \
      -H "Content-Type: application/json" \
      -d '{}'
    ```

    | Answer | Tell the merchant |
    | - | - |
    | `404 not_found` | The key works, and codes can go out. |
    | `403 account_not_active` | The application is in review, rejected or suspended. During review the test key works and WhatsApp works with the live key. |
    | `403 insufficient_scope` | This key cannot send codes. Create one with Verify send access. |
    | `401 unauthorized` | Tawked does not know this key: revoked, mistyped, or the wrong mode for its field. |
    | `401 key_expired` | The key has expired. Create a new one. |

    For WhatsApp, `GET /v1/whatsapp/templates` with the live key answers `200` with the templates when the number is ready. `409 no_whatsapp_number` and `409 number_disconnected` mean the merchant has to connect the number in the console.
  </Step>

  <Step title="Send, and retry safely">
    Send an `Idempotency-Key` on every `POST`, one per business event (an order and its status, a sign-in attempt), so a retry never sends twice. Retry with the same key only on `502 send_failed`, `503 templates_unavailable`, `429 too_many_requests` and network timeouts. Every other error is final: show the merchant a sentence for it. The [Errors](/errors) page lists every code. Match on the `error` string, never on the HTTP status alone.
  </Step>
</Steps>

Rules that keep merchants out of trouble:

* **Saudi mobiles only.** Normalise numbers to `+9665…` before calling, and skip any other number without calling.
* **Pass `client_ip`** on `POST /v1/verify/start`: the visitor's address, never your server's. The [protection guard](/reliability#the-protection-guard) needs it.
* **Never promise a sender name.** A Verify SMS goes out under Tawked's sender ID and names the merchant's reviewed application. A WhatsApp message comes from the merchant's own number.
* **Utility templates for order updates.** Marketing templates need the customer's consent, which your integration must collect first.
* **Send in the background.** A WhatsApp send answers `202` once accepted. Queue it outside the customer's request, and read the outcome from the `message.*` [webhooks](/webhooks) or `GET /v1/whatsapp/messages/{id}`.

## Model B: the Partner API

You hold one partner account. You provision a Verify application for each merchant by API, under your own `external_id`, and send codes for it with your partner key and an `application` field. Each application is reviewed or activated at once, by your account's approval mode, and the outcome reaches your webhook as `service.approved` or `service.rejected`. You hold the balance and the relationship; the SMS names the merchant's reviewed application.

Client applications carry Tawked Verify only. A merchant who also wants WhatsApp from their own number connects their own application (model A).

Start with the [Partner API overview](/partners/overview), then [Applications](/partners/applications) and [Sending codes for an application](/partners/sending).

## Questions while you build

Write to [support@tawked.com](mailto:support@tawked.com) with the `X-Request-Id` of the call in question.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.