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

# Provision in bulk

> Up to 100 provisioning bodies in one call, for a migration or a sync. Items run in order, one at a time, each exactly like a single provision (screened, queued or activated, its own events); a refused item never stops the rest. Always `200` with the counts and one result per item in the same order: `created`, `existing` (the id was already yours; nothing applied from the item) or `refused` (`fields` names the refused ones, `application` is `null`). The same `external_id` twice in a batch is `created` then `existing`.

Guide: [Applications](https://docs.tawked.com/partners/applications.md)


## OpenAPI

````yaml https://tawked.com/openapi.json post /v1/partner/applications/batch
openapi: 3.1.0
info:
  title: Tawked API
  version: 2026-09
  summary: >-
    Tawked Verify: OTP verification for Saudi mobile numbers over SMS, in two
    calls. Tawked Notifications: WhatsApp template messages from the
    application's own number. Tawked Email: transactional e-mail from the
    application's own verified domain. Tawked Chat: the conversation menus a
    connected app adds beside the conversations of its connection's application,
    and the auto-attendant it sets up there. The Partner API for platforms that
    run Tawked Verify for their merchants.
  description: >-
    The public API of Tawked, a Saudi messaging platform: Tawked Verify
    (one-time codes), Tawked Notifications (WhatsApp templates from the
    application's own number), Tawked Email (transactional e-mail from the
    application's own domain) and the Partner API. Tawked Verify is an OTP
    verification API for Saudi numbers. One call sends a one-time code by SMS to
    a Saudi mobile number, and a second call checks it. SAR 0.09 per SMS code
    sent, prepaid; a send the network refuses is refunded. Authenticate with a
    Bearer API key from the dashboard (tk_live_ for production, tk_test_ for the
    sandbox, tk_partner_ for partners, tk_partner_test_ for the partner
    sandbox). Partners (tk_partner_) provision a Verify application per merchant
    under /v1/partner/applications and name it as application on every Verify
    call. Both /v1/... and /api/v1/... answer identically. Rate limit: 120
    requests per minute per key.
  termsOfService: https://tawked.com/en/terms
  license:
    name: Proprietary (Tawked terms of service)
    url: https://tawked.com/en/terms
  contact:
    name: Tawked support
    email: support@tawked.com
    url: https://tawked.com/en/contact
servers:
  - url: https://tawked.com
    description: Production (the sandbox is a tk_test_ key on the same host)
  - url: https://tawked.com/api
    description: The same API under /api/v1/..., kept for older integrations
security:
  - bearerKey: []
  - headerKey: []
tags:
  - name: Verify
    x-group: Verify
    description: Send and check one-time codes.
  - name: WhatsApp
    x-group: Notifications
    description: >-
      Tawked Notifications: send approved WhatsApp templates through the number
      connected to an application. An application in review or approved connects
      its own number from the dashboard.
  - name: Email
    x-group: Email
    description: >-
      Tawked Email: send transactional e-mail from an address on a verified
      domain of the application, to up to 50 recipients a message, in batches or
      scheduled, and read and list what was sent. Live keys only.
  - name: Chat
    x-group: Chat
    description: >-
      Tawked Chat: the conversation menus a connected app adds beside the
      conversations of its connection's application, and reads, changes and
      removes, with `chat:menus`; and the application's auto-attendant, which a
      connected app sets up, publishes and switches on or off, with
      `chat:attendant`. A connected app's key only; a business adds its own
      menus and builds its auto-attendant in the console.
  - name: Partner
    x-group: Partner API
    description: >-
      For platforms that run Tawked Verify for their merchants: provision a
      Verify application per merchant, keep its brand and verify settings
      current, switch it off and on, and read usage and the code log. Partner
      keys (tk_partner_) only; every Verify operation then takes `application`
      with the partner's own id for the application.
  - name: Webhooks
    x-group: Webhooks
    description: >-
      The events Tawked sends to your endpoint: an application's verification
      outcomes and message statuses, and a partner account's lifecycle, balance
      and opt-in verification events. Every delivery is signed the same way and
      retried the same way.
externalDocs:
  description: Developer docs, with code samples
  url: https://docs.tawked.com
paths:
  /v1/partner/applications/batch:
    post:
      tags:
        - Partner
      summary: Provision in bulk
      description: >-
        Up to 100 provisioning bodies in one call, for a migration or a sync.
        Items run in order, one at a time, each exactly like a single provision
        (screened, queued or activated, its own events); a refused item never
        stops the rest. Always `200` with the counts and one result per item in
        the same order: `created`, `existing` (the id was already yours; nothing
        applied from the item) or `refused` (`fields` names the refused ones,
        `application` is `null`). The same `external_id` twice in a batch is
        `created` then `existing`.
      operationId: partner_batch
      parameters:
        - name: Idempotency-Key
          in: header
          required: false
          description: >-
            A 1 to 128 printable-ASCII key you generate, scoped to your API key.
            Replaying it with the same request answers the original 2xx
            unchanged, with the response header `Idempotent-Replayed: true`, and
            runs nothing again; the same key with another request answers `409
            idempotency_key_reused`, and a request still in flight `409
            idempotency_in_progress`. A refused request is never stored, so a
            corrected retry under the same key runs. Keys expire after 24 hours.
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                applications:
                  type: array
                  description: >-
                    A list of 1 to 100 objects, each the body of a single
                    provision (`external_id`, `name_ar`, `name_en`, `website`,
                    and the optional `industry`, `merchant`, `metadata`,
                    `verify`). Anything else answers `400 invalid_request` with
                    `fields: ["applications"]`; an item that is not an object is
                    refused with `fields: ["item"]`.
              required:
                - applications
      responses:
        '200':
          description: The batch, item by item / One item refused
          content:
            application/json:
              schema:
                type: object
                properties:
                  created:
                    type: integer
                  existing:
                    type: integer
                  refused:
                    type: integer
                  results:
                    type: array
                    items:
                      type: object
                      properties:
                        index:
                          type: integer
                        external_id:
                          type: string
                        outcome:
                          type: string
                        application:
                          type: object
                          properties:
                            service_id:
                              type: string
                            application_id:
                              type: string
                            external_id:
                              type: string
                            status:
                              type: string
                            screening:
                              type: object
                              properties:
                                result:
                                  type: string
                                rules:
                                  type: array
                                  items:
                                    type:
                                      - string
                                      - 'null'
                            verify:
                              type: object
                              properties:
                                code_length:
                                  type: integer
                                ttl_seconds:
                                  type: integer
                                max_attempts:
                                  type: integer
                                max_per_hour:
                                  type: integer
                                autofill_domain:
                                  type: string
                                autofill_domain_enabled:
                                  type: boolean
                                android_app_hash:
                                  type:
                                    - string
                                    - 'null'
                                daily_spend_cap_halalas:
                                  type:
                                    - string
                                    - 'null'
                                max_per_ip_per_hour:
                                  type: integer
                                max_new_destinations_per_hour:
                                  type: integer
                            paused:
                              type: boolean
              examples:
                the_batch_item_by_item:
                  summary: The batch, item by item
                  value:
                    created: 1
                    existing: 1
                    refused: 0
                    results:
                      - index: 0
                        external_id: store_88
                        outcome: existing
                        application:
                          service_id: c2a10f3e-8b7a-4d2e-9c1a-1a2b3c4d5e6f
                          application_id: c2a10f3e-8b7a-4d2e-9c1a-1a2b3c4d5e6f
                          external_id: store_88
                          status: active
                          screening:
                            result: clean
                            rules: []
                          verify:
                            code_length: 6
                            ttl_seconds: 300
                            max_attempts: 3
                            max_per_hour: 5
                            autofill_domain: flowers.example
                            autofill_domain_enabled: true
                            android_app_hash: null
                            daily_spend_cap_halalas: null
                            max_per_ip_per_hour: 20
                            max_new_destinations_per_hour: 300
                          paused: false
                      - index: 1
                        external_id: store_89
                        outcome: created
                        application:
                          service_id: 9d1c2b3a-4e5f-4a6b-8c7d-0e1f2a3b4c5d
                          application_id: 9d1c2b3a-4e5f-4a6b-8c7d-0e1f2a3b4c5d
                          external_id: store_89
                          status: review
                          screening:
                            result: clean
                            rules: []
                          verify:
                            code_length: 6
                            ttl_seconds: 300
                            max_attempts: 3
                            max_per_hour: 5
                            autofill_domain: flowers.example
                            autofill_domain_enabled: true
                            android_app_hash: null
                            daily_spend_cap_halalas: null
                            max_per_ip_per_hour: 20
                            max_new_destinations_per_hour: 300
                          paused: false
                one_item_refused:
                  summary: One item refused
                  value:
                    created: 0
                    existing: 0
                    refused: 1
                    results:
                      - index: 0
                        external_id: store_90
                        outcome: refused
                        fields:
                          - website
                        application: null
        '400':
          description: >-
            Not a list of 1 to 100 / `invalid_json`: The request body is not
            valid JSON.; `invalid_request`: A field is missing or refused.
            `fields` names them: bare names on the verify-settings endpoint
            (`verify` alone for an empty or unrecognised patch), `verify.`
            followed by the field name for a setting refused on provision or a
            brand update, `metadata.` followed by the key for a refused tag
            (`metadata` alone for a wrong shape, on a write or on the list
            filter), `logo` for a missing, oversized or non-image file, `events`
            for an unknown event name, `url` or `secret` on the webhook
            (console-only, with `message`), `cursor`, `since`, `event` or
            `status` on the feeds; on usage, `message` says that `from` and `to`
            must be ISO dates; a malformed `Idempotency-Key` header is refused
            with `message` too.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Error'
                  - properties:
                      error:
                        enum:
                          - invalid_json
                          - invalid_request
              examples:
                not_a_list_of_1_to_100:
                  summary: Not a list of 1 to 100
                  value:
                    error: invalid_request
                    fields:
                      - applications
        '401':
          description: >-
            `unauthorized`: Missing, unknown or revoked key; a key of another
            mode (`tk_live_` and `tk_test_` keys cannot call the partner API);
            or a partner account Tawked suspended.; `key_expired`: The key's
            `expires_at` has passed. Checked right after the key is recognised.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Error'
                  - properties:
                      error:
                        enum:
                          - unauthorized
                          - key_expired
        '403':
          description: >-
            `ip_not_allowed`: The caller's IP is outside the key's allowlist.;
            `partner_suspended`: Your partner account was suspended by Tawked
            between the key check and the write. In practice the key already
            answers `401 unauthorized`; this is defense in depth.;
            `live_key_required`: A `tk_partner_test_` key on a management write.
            The sandbox key reads every partner endpoint and sends; use your
            live key to change anything.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Error'
                  - properties:
                      error:
                        enum:
                          - ip_not_allowed
                          - partner_suspended
                          - live_key_required
        '409':
          description: >-
            `idempotency_in_progress`: A request with this `Idempotency-Key` is
            still running. Wait for its answer, or retry in a moment.;
            `idempotency_key_reused`: This `Idempotency-Key` was already used
            for a different request (another body, path or method). Use one key
            per business event.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Error'
                  - properties:
                      error:
                        enum:
                          - idempotency_in_progress
                          - idempotency_key_reused
        '429':
          description: >-
            `too_many_requests`: Per-key rate limit exceeded (120 requests per
            minute, fixed 60-second window). Checked before authentication.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Error'
                  - properties:
                      error:
                        enum:
                          - too_many_requests
        '500':
          description: >-
            `internal_error`: An unhandled server error. Quote the X-Request-Id
            header if you report it.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Error'
                  - properties:
                      error:
                        enum:
                          - internal_error
      x-codeSamples:
        - lang: bash
          label: cURL
          source: |-
            curl -X POST https://tawked.com/v1/partner/applications/batch \
              -H "Authorization: Bearer tk_partner_xxxxxxxxxxxxxxxxxxxx" \
              -H "Content-Type: application/json" \
              -H "Idempotency-Key: sync-2026-09-27" \
              -d '{
                "applications": [
                    {
                        "external_id": "store_88",
                        "name_ar": "متجر الورد",
                        "name_en": "Flower Shop",
                        "website": "https://flowers.example"
                    },
                    {
                        "external_id": "store_89",
                        "name_ar": "مخبز السنابل",
                        "name_en": "Sanabel Bakery",
                        "website": "https://sanabel.example"
                    }
                ]
            }'
        - lang: javascript
          label: Node.js
          source: >-
            const res = await
            fetch("https://tawked.com/v1/partner/applications/batch", {
              method: "POST",
              headers: {
                Authorization: "Bearer tk_partner_xxxxxxxxxxxxxxxxxxxx",
                "Content-Type": "application/json",
                "Idempotency-Key": "sync-2026-09-27",
              },
              body: JSON.stringify({
                  "applications": [
                      {
                          "external_id": "store_88",
                          "name_ar": "متجر الورد",
                          "name_en": "Flower Shop",
                          "website": "https://flowers.example"
                      },
                      {
                          "external_id": "store_89",
                          "name_ar": "مخبز السنابل",
                          "name_en": "Sanabel Bakery",
                          "website": "https://sanabel.example"
                      }
                  ]
              }),
            });

            const data = await res.json();
        - lang: python
          label: Python
          source: |-
            import requests

            res = requests.post(
                "https://tawked.com/v1/partner/applications/batch",
                headers={"Authorization": "Bearer tk_partner_xxxxxxxxxxxxxxxxxxxx", "Idempotency-Key": "sync-2026-09-27"},
                json={
                    "applications": [
                        {
                            "external_id": "store_88",
                            "name_ar": "متجر الورد",
                            "name_en": "Flower Shop",
                            "website": "https://flowers.example"
                        },
                        {
                            "external_id": "store_89",
                            "name_ar": "مخبز السنابل",
                            "name_en": "Sanabel Bakery",
                            "website": "https://sanabel.example"
                        }
                    ]
                },
            )
            data = res.json()
components:
  schemas:
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          description: A stable machine-readable code; the docs list every one.
      additionalProperties: true
  securitySchemes:
    bearerKey:
      type: http
      scheme: bearer
      description: >-
        Authorization: Bearer <api key>. An application key (tk_live_, tk_test_)
        has full access, which covers every product and any product added later,
        or custom access, chosen when the key is created: one or more of the
        scopes `verify:check`, `verify:send` (includes `verify:check`),
        `notifications:read`, `notifications:send` (includes
        `notifications:read`), `email:read`, `email:send` (includes
        `email:read`), `email:manage` (includes `email:send`),
        `webhooks:manage`, `email:inbound`, `notifications:templates` (includes
        `notifications:read`), `chat:menus`, `chat:attendant`. No key made on
        the API keys page holds `notifications:templates`, full access included:
        the three template writes answer such a key 403 `insufficient_scope`. A
        connected app's key holds it. Nor `chat:menus`: the five conversation
        menu operations answer such a key 403 `insufficient_scope`, and a
        connected app's key holds it once the client approved it. Nor
        `chat:attendant`: the five auto-attendant operations answer such a key
        403 `insufficient_scope` too, and a connected app's key holds it once
        the client approved it. `email:manage` and `webhooks:manage` are held
        only by a key someone chose them for: a full-access key, old or new,
        never holds them. `email:inbound`, which reads, deletes and forwards
        received e-mail, is opt-in on every key, full access included: a key
        holds it only when it was turned on when the key was created. A call
        outside the key's access answers 403 `insufficient_scope` and names the
        scope it needs in the `WWW-Authenticate` response header. A partner key
        (tk_partner_) always has full access. Whatever its access, a key is a
        server-side secret.
    headerKey:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        The same API key, with the same access, as a header, for clients that
        cannot set Authorization.

````

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