BrightshoalDocsOpen console
MenuWhatsApp

API reference

WhatsApp

Connect a WhatsApp Business Account from Meta and assign its numbers to assistants.

List WhatsApp accounts and numbers

GET/api/integrations/whatsapp/connections

Every connected WhatsApp Business Account with its numbers, the assistant each number is assigned to, and counts of replies and turns that failed. Credentials are never returned. Needs an org-wide key.

Secret API key, org-wide (not pinned to a project). How it works

Returns

200 Connections

Response attributes
  • dataarray of WhatsAppConnectionrequired

    9 attributes
    • idstring

    • org_idstring

    • namestring

    • waba_idstring

      The WhatsApp Business Account id.

    • api_versionstring

    • configuredboolean

      Credentials are stored. False after a disconnect.

    • enabledboolean

      False while paused: messages are not answered.

    • webhook_pathstring

      The path of the callback URL to give Meta (on the API origin).

    • numbersarray of WhatsAppNumber

      10 attributes
      • idstring

      • connection_idstring

      • phone_number_idstring

      • display_phone_numberstring

      • verified_namestring | null

      • assistant_idstring | null

      • enabledboolean

      • modestring

        One of live test

      • failed_repliesinteger

        List only: replies that could not be sent.

      • failed_turnsinteger

        List only: incoming messages the assistant failed to answer.

  • 400 invalid_request: the body failed validation
  • 403 org_scope_required (needs an org-wide key; project keys get 403) or the role is too low
  • 404 not_found: no such connection or number in this organization
  • 409 whatsapp_already_connected, whatsapp_credentials_required, whatsapp_disconnected, or on sync whatsapp_number_already_connected (a number already belongs to another connection)
  • 422 Meta refused the request (meta_<Meta error code>, or meta_http_<status>), or could not be reached (meta_unreachable, which says nothing about whether Meta acted on it)
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
GET /api/integrations/whatsapp/connections
curl "https://api.myleadsfactory.tech/api/integrations/whatsapp/connections" \
  -H "Authorization: Bearer $MLF_API_KEY"
Response 200
{
  "data": [
    {
      "id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "org_id": "org_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "name": "Front desk",
      "waba_id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "api_version": "string",
      "configured": true,
      "enabled": true,
      "webhook_path": "string",
      "numbers": [
        {
          "id": "pn_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
          "connection_id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
          "phone_number_id": "+14155550123",
          "display_phone_number": "+14155550123",
          "verified_name": "string",
          "assistant_id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
          "enabled": true,
          "mode": "live",
          "failed_replies": 1,
          "failed_turns": 1
        }
      ]
    }
  ]
}

Connect a WhatsApp Business account

POST/api/integrations/whatsapp/connections

Checks the credentials with Meta, stores them encrypted and imports the account's phone numbers, unassigned. Then subscribe the account to its callback and assign numbers to assistants. Needs an org-wide key.

Secret API key, not read-only, org-wide (not pinned to a project). How it works

Request body

  • namestringrequiredup to 100 characters

    Your label for the account.

  • waba_idstringrequired

    The WhatsApp Business Account id (digits).

  • api_versionstring

    Graph API version.

    Default "v25.0"

  • credentialsobjectrequired

    From your Meta app. Write-only: stored encrypted and never returned.

    3 attributes
    • access_tokenstringrequiredup to 8192 characterswrite-only, never returned

      A system user access token with WhatsApp permissions.

    • app_secretstringrequiredup to 256 characterswrite-only, never returned

      Verifies Meta's callback signatures.

    • verify_tokenstringrequired16 to 256 characterswrite-only, never returned

      Any string you choose; Meta echoes it when it verifies the callback.

Returns

201 Connected

Response attributes
  • dataWhatsAppConnectionrequired

    9 attributes
    • idstring

    • org_idstring

    • namestring

    • waba_idstring

      The WhatsApp Business Account id.

    • api_versionstring

    • configuredboolean

      Credentials are stored. False after a disconnect.

    • enabledboolean

      False while paused: messages are not answered.

    • webhook_pathstring

      The path of the callback URL to give Meta (on the API origin).

    • numbersarray of WhatsAppNumber

      10 attributes
      • idstring

      • connection_idstring

      • phone_number_idstring

      • display_phone_numberstring

      • verified_namestring | null

      • assistant_idstring | null

      • enabledboolean

      • modestring

        One of live test

      • failed_repliesinteger

        List only: replies that could not be sent.

      • failed_turnsinteger

        List only: incoming messages the assistant failed to answer.

  • 400 invalid_request: the body failed validation
  • 403 org_scope_required (needs an org-wide key; project keys get 403) or the role is too low
  • 404 not_found: no such connection or number in this organization
  • 409 whatsapp_already_connected, whatsapp_credentials_required, whatsapp_disconnected, or on sync whatsapp_number_already_connected (a number already belongs to another connection)
  • 422 Meta refused the request (meta_<Meta error code>, or meta_http_<status>), or could not be reached (meta_unreachable, which says nothing about whether Meta acted on it)
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
POST /api/integrations/whatsapp/connections
curl -X POST "https://api.myleadsfactory.tech/api/integrations/whatsapp/connections" \
  -H "Authorization: Bearer $MLF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Acme Travel WhatsApp",
  "waba_id": "102938475610293",
  "credentials": {
    "access_token": "EAAG...",
    "app_secret": "3f6c2a8e4b1d...",
    "verify_token": "acme-verify-7d2e9b14c6a04f3e"
  }
}'
Response 201
{
  "data": {
    "id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "org_id": "org_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "name": "Front desk",
    "waba_id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "api_version": "string",
    "configured": true,
    "enabled": true,
    "webhook_path": "string",
    "numbers": [
      {
        "id": "pn_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
        "connection_id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
        "phone_number_id": "+14155550123",
        "display_phone_number": "+14155550123",
        "verified_name": "string",
        "assistant_id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
        "enabled": true,
        "mode": "live",
        "failed_replies": 1,
        "failed_turns": 1
      }
    ]
  }
}

Update a WhatsApp connection

PATCH/api/integrations/whatsapp/connections/{id}

enabled: false pauses every number on the account; true resumes. New credentials are checked with Meta before they replace the stored ones. A disconnected account needs credentials to resume (409 whatsapp_credentials_required).

Secret API key, not read-only, org-wide (not pinned to a project). How it works

Path parameters

  • idstringrequired

    WhatsApp connection id.

Request body

  • namestringup to 100 characters

  • enabledboolean

  • credentialsobject

    From your Meta app. Write-only: stored encrypted and never returned.

    3 attributes
    • access_tokenstringrequiredup to 8192 characterswrite-only, never returned

      A system user access token with WhatsApp permissions.

    • app_secretstringrequiredup to 256 characterswrite-only, never returned

      Verifies Meta's callback signatures.

    • verify_tokenstringrequired16 to 256 characterswrite-only, never returned

      Any string you choose; Meta echoes it when it verifies the callback.

Returns

200 Updated

Response attributes
  • dataWhatsAppConnectionrequired

    9 attributes
    • idstring

    • org_idstring

    • namestring

    • waba_idstring

      The WhatsApp Business Account id.

    • api_versionstring

    • configuredboolean

      Credentials are stored. False after a disconnect.

    • enabledboolean

      False while paused: messages are not answered.

    • webhook_pathstring

      The path of the callback URL to give Meta (on the API origin).

    • numbersarray of WhatsAppNumber

      10 attributes
      • idstring

      • connection_idstring

      • phone_number_idstring

      • display_phone_numberstring

      • verified_namestring | null

      • assistant_idstring | null

      • enabledboolean

      • modestring

        One of live test

      • failed_repliesinteger

        List only: replies that could not be sent.

      • failed_turnsinteger

        List only: incoming messages the assistant failed to answer.

  • 400 Invalid body, or resuming would route a number to an assistant whose chat model cannot answer
  • 403 org_scope_required (needs an org-wide key; project keys get 403) or the role is too low
  • 404 not_found: no such connection or number in this organization
  • 409 whatsapp_already_connected, whatsapp_credentials_required, whatsapp_disconnected, or on sync whatsapp_number_already_connected (a number already belongs to another connection)
  • 422 Meta refused the request (meta_<Meta error code>, or meta_http_<status>), or could not be reached (meta_unreachable, which says nothing about whether Meta acted on it)
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
PATCH /api/integrations/whatsapp/connections/{id}
curl -X PATCH "https://api.myleadsfactory.tech/api/integrations/whatsapp/connections/CONNECTION_ID" \
  -H "Authorization: Bearer $MLF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Front desk",
  "enabled": true
}'
Response 200
{
  "data": {
    "id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "org_id": "org_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "name": "Front desk",
    "waba_id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "api_version": "string",
    "configured": true,
    "enabled": true,
    "webhook_path": "string",
    "numbers": [
      {
        "id": "pn_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
        "connection_id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
        "phone_number_id": "+14155550123",
        "display_phone_number": "+14155550123",
        "verified_name": "string",
        "assistant_id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
        "enabled": true,
        "mode": "live",
        "failed_replies": 1,
        "failed_turns": 1
      }
    ]
  }
}

Disconnect a WhatsApp account

DELETE/api/integrations/whatsapp/connections/{id}

Disconnects the account: messages stop being answered and the stored credentials are erased. Numbers, assignments and conversation history stay, so reconnecting with new credentials picks up where it left off.

Secret API key, not read-only, org-wide (not pinned to a project). How it works

Path parameters

  • idstringrequired

    WhatsApp connection id.

Returns

200 Disconnected

Response attributes
  • dataobjectrequired

    1 attribute
    • disconnectedbooleanrequired

      One of true

  • 400 invalid_request: the body failed validation
  • 403 org_scope_required (needs an org-wide key; project keys get 403) or the role is too low
  • 404 not_found: no such connection or number in this organization
  • 409 whatsapp_already_connected, whatsapp_credentials_required, whatsapp_disconnected, or on sync whatsapp_number_already_connected (a number already belongs to another connection)
  • 422 Meta refused the request (meta_<Meta error code>, or meta_http_<status>), or could not be reached (meta_unreachable, which says nothing about whether Meta acted on it)
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
DELETE /api/integrations/whatsapp/connections/{id}
curl -X DELETE "https://api.myleadsfactory.tech/api/integrations/whatsapp/connections/CONNECTION_ID" \
  -H "Authorization: Bearer $MLF_API_KEY"
Response 200
{
  "data": {
    "disconnected": true
  }
}

Assign a WhatsApp number to an assistant

PUT/api/integrations/whatsapp/connections/{id}/numbers/{numberId}

Routes the number's WhatsApp messages to an assistant (assistant_id: null unassigns it), optionally pausing just this number. The assistant answers with its web chat model, so that model must be one chat supports.

Secret API key, not read-only, org-wide (not pinned to a project). How it works

Path parameters

  • idstringrequired

    WhatsApp connection id.

  • numberIdstringrequired

    WhatsApp number id, from the connection's numbers.

Request body

  • assistant_idstring | nullrequirednot empty

    Assistant id, or null to unassign.

  • enabledboolean

    False pauses this number only.

  • modestring

    One of live test

Returns

200 Assigned

Response attributes
  • dataWhatsAppNumberrequired

    10 attributes
    • idstring

    • connection_idstring

    • phone_number_idstring

    • display_phone_numberstring

    • verified_namestring | null

    • assistant_idstring | null

    • enabledboolean

    • modestring

      One of live test

    • failed_repliesinteger

      List only: replies that could not be sent.

    • failed_turnsinteger

      List only: incoming messages the assistant failed to answer.

  • 400 Invalid body, or the assistant's chat model has no chat adapter
  • 403 org_scope_required (needs an org-wide key; project keys get 403) or the role is too low
  • 404 not_found: no such connection or number in this organization
  • 409 whatsapp_already_connected, whatsapp_credentials_required, whatsapp_disconnected, or on sync whatsapp_number_already_connected (a number already belongs to another connection)
  • 422 Meta refused the request (meta_<Meta error code>, or meta_http_<status>), or could not be reached (meta_unreachable, which says nothing about whether Meta acted on it)
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
PUT /api/integrations/whatsapp/connections/{id}/numbers/{numberId}
curl -X PUT "https://api.myleadsfactory.tech/api/integrations/whatsapp/connections/CONNECTION_ID/numbers/NUMBER_ID" \
  -H "Authorization: Bearer $MLF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "assistant_id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f"
}'
Response 200
{
  "data": {
    "id": "pn_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "connection_id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "phone_number_id": "+14155550123",
    "display_phone_number": "+14155550123",
    "verified_name": "string",
    "assistant_id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "enabled": true,
    "mode": "live",
    "failed_replies": 1,
    "failed_turns": 1
  }
}

Subscribe an account to its message callback

POST/api/integrations/whatsapp/connections/{id}/subscribe

Tells Meta to post this account's messages to its callback, then Meta verifies it with your verify_token. Use the public API origin with the connection's webhook_path (/public/whatsapp/webhooks/{id}); the older /whatsapp/webhooks/{id} path is also accepted. callback_url must be HTTPS with no query, fragment or credentials, at one of those paths (otherwise 400 whatsapp_public_https_webhook_required).

Secret API key, not read-only, org-wide (not pinned to a project). How it works

Path parameters

  • idstringrequired

    WhatsApp connection id.

Request body

  • callback_urlstringrequireduriup to 2048 characters

Returns

200 Subscribed

Response attributes
  • dataobjectrequired

    1 attribute
    • subscribedbooleanrequired

      One of true

  • 400 invalid_request: the body failed validation
  • 403 org_scope_required (needs an org-wide key; project keys get 403) or the role is too low
  • 404 not_found: no such connection or number in this organization
  • 409 whatsapp_already_connected, whatsapp_credentials_required, whatsapp_disconnected, or on sync whatsapp_number_already_connected (a number already belongs to another connection)
  • 422 Meta refused the request (meta_<Meta error code>, or meta_http_<status>), or could not be reached (meta_unreachable, which says nothing about whether Meta acted on it)
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
POST /api/integrations/whatsapp/connections/{id}/subscribe
curl -X POST "https://api.myleadsfactory.tech/api/integrations/whatsapp/connections/CONNECTION_ID/subscribe" \
  -H "Authorization: Bearer $MLF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "callback_url": "https://example.com/hook"
}'
Response 200
{
  "data": {
    "subscribed": true
  }
}

Sync an account's phone numbers

POST/api/integrations/whatsapp/connections/{id}/sync

Fetches the account's current phone numbers from Meta. New numbers arrive unassigned; existing ones keep their assistant.

Secret API key, not read-only, org-wide (not pinned to a project). How it works

Path parameters

  • idstringrequired

    WhatsApp connection id.

Returns

200 The account's numbers

Response attributes
  • dataarray of WhatsAppNumberrequired

    10 attributes
    • idstring

    • connection_idstring

    • phone_number_idstring

    • display_phone_numberstring

    • verified_namestring | null

    • assistant_idstring | null

    • enabledboolean

    • modestring

      One of live test

    • failed_repliesinteger

      List only: replies that could not be sent.

    • failed_turnsinteger

      List only: incoming messages the assistant failed to answer.

  • 400 invalid_request: the body failed validation
  • 403 org_scope_required (needs an org-wide key; project keys get 403) or the role is too low
  • 404 not_found: no such connection or number in this organization
  • 409 whatsapp_already_connected, whatsapp_credentials_required, whatsapp_disconnected, or on sync whatsapp_number_already_connected (a number already belongs to another connection)
  • 422 Meta refused the request (meta_<Meta error code>, or meta_http_<status>), or could not be reached (meta_unreachable, which says nothing about whether Meta acted on it)
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
POST /api/integrations/whatsapp/connections/{id}/sync
curl -X POST "https://api.myleadsfactory.tech/api/integrations/whatsapp/connections/CONNECTION_ID/sync" \
  -H "Authorization: Bearer $MLF_API_KEY"
Response 200
{
  "data": [
    {
      "id": "pn_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "connection_id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "phone_number_id": "+14155550123",
      "display_phone_number": "+14155550123",
      "verified_name": "string",
      "assistant_id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "enabled": true,
      "mode": "live",
      "failed_replies": 1,
      "failed_turns": 1
    }
  ]
}