Docs
ChangelogالعربيةDashboard
DocumentationAPI reference
API referenceAssign an agent to a WhatsApp number
  • Introduction
  • Authentication
    • GETVerify API key
  • Agents
    • POSTCreate agent
    • GETList agents
    • GETGet agent
    • PUTUpdate agent
    • DELDelete agent
    • POSTLink analysis groups to an agent
    • GETList analysis groups for an agent
  • Tools
    • POSTCreate tool
    • GETList tools
    • GETGet tool
    • PUTUpdate tool
    • DELDelete tool
    • POSTLink a tool to an agent
    • DELUnlink a tool from an agent
    • GETList tools for an agent
    • GETList agents for a tool
  • Analysis groups
    • POSTCreate analysis group
    • GETList analysis groups
    • GETGet analysis group
    • PUTUpdate analysis group
    • DELDelete analysis group
    • POSTLink an agent to an analysis group
    • POSTLink agents to an analysis group
    • GETList agents for an analysis group
    • DELUnlink an analysis group from an agent
  • Knowledge bases
    • POSTCreate knowledge base
    • GETList knowledge bases
    • GETGet knowledge base
    • PATCHUpdate knowledge base
    • DELDelete knowledge base
  • Documents
    • POSTAdd PDF document
    • POSTAdd text document
    • POSTAdd URL document
    • GETList documents
    • GETGet document
    • DELDelete document
  • Calls
    • POSTCreate outbound call
    • GETGet call
    • POSTSearch calls
    • POSTGet call analytics
    • POSTExport calls
    • GETGet recording download URL
    • POSTCreate outbound call (legacy path)
  • Web calls
    • POSTCreate web call
    • POSTCreate web call (legacy path)
  • SIP inbound
    • POSTCreate SIP inbound trunk
    • GETList SIP inbound trunks
    • GETGet SIP inbound trunk
    • DELDelete SIP inbound trunk
  • SIP outbound
    • POSTCreate SIP outbound trunk
    • GETList SIP outbound trunks
    • GETGet SIP outbound trunk
    • DELDelete SIP outbound trunk
  • Agent inbound links
    • POSTLink an agent to an inbound trunk
    • GETList agent inbound links
    • DELDelete agent inbound link
  • Text to speech
    • POSTGenerate speech
    • GETList voices
    • GETGet voice
    • POSTClone a voice
    • DELDelete cloned voice
  • Speech to text
    • POSTTranscribe an audio file
    • GETGet transcription job
    • GETList transcription jobs
    • WSStream speech to text
  • Contacts
    • POSTCreate contact
    • GETList contacts
    • GETSearch contacts
    • GETGet contact
    • PATCHUpdate contact
    • GETList conversations for a contact
  • Conversations
    • GETList conversations
    • POSTFilter conversations
    • POSTList conversations by contact
    • GETGet conversation
    • GETList conversation messages
    • POSTSend a message
    • POSTSend a message with an attachment
    • GETList conversation attachments
    • POSTAssign conversation
    • POSTChange conversation status
    • POSTChange conversation priority
    • POSTMark conversation as seen
  • Tickets
    • POSTCreate ticket
    • GETList tickets
    • POSTFilter tickets
    • POSTList tickets by contact
    • GETGet ticket
    • GETList ticket messages
    • POSTAdd a ticket message
    • POSTAdd a ticket message with attachments
    • POSTAssign ticket
    • POSTChange ticket status
    • POSTChange ticket priority
    • POSTChange ticket type
    • POSTCreate ticket inbox
    • GETList ticket inboxes
    • PATCHUpdate ticket inbox
    • DELDelete ticket inbox
  • WhatsApp
    • POSTConnect a WhatsApp number
    • GETList WhatsApp inboxes
    • GETGet WhatsApp inbox
    • PATCHUpdate WhatsApp inbox
    • DELDelete WhatsApp inbox
    • POSTCreate WhatsApp conversation
    • GETList WhatsApp conversations
    • POSTFilter WhatsApp conversations
    • POSTList WhatsApp conversations by contact
    • POSTAssign an agent to a WhatsApp number
    • GETGet the agent on a WhatsApp number
    • DELRemove the agent from a WhatsApp number
    • POSTGet WhatsApp analytics
  • Instagram
    • GETList Instagram accounts
    • GETGet Instagram account
    • DELDelete Instagram account
    • GETList Instagram conversations
    • POSTFilter Instagram conversations
    • POSTList Instagram conversations by contact
    • POSTAssign an agent to an Instagram account
    • GETGet the agent on an Instagram account
    • DELRemove the agent from an Instagram account
  • TikTok
    • GETList TikTok accounts
    • GETGet TikTok account
    • DELDelete TikTok account
    • GETList TikTok conversations
    • POSTFilter TikTok conversations
    • POSTList TikTok conversations by contact
    • POSTAssign an agent to a TikTok account
    • GETGet the agent on a TikTok account
    • DELRemove the agent from a TikTok account

WhatsApp

Assign an agent to a WhatsApp number

Attach an AI agent to one of the project's WhatsApp numbers so it automatically replies to incoming WhatsApp messages on that number. You bind an existing agent (by agent_id) and configure, for this number, whether the bot may escalate to a human, who it hands over to, when idle conversations close, and where conversation events are sent. The response returns the bound agent's full configuration plus this number's text_chatbot_settings.

POST
https://api.nabrah.ai/api/ext/omni_v2/whatsapp/assign_chatbot
Assign an agent to a WhatsApp number
curl --request POST \
  --url 'https://api.nabrah.ai/api/ext/omni_v2/whatsapp/assign_chatbot' \
  --header 'X-API-Key: <your-api-key>' \
  --header 'Content-Type: application/json' \
  --data '{
  "agent_id": "00000000-0000-4000-8000-000000000000",
  "name": "WhatsApp Support Bot",
  "can_refer_to_human": true,
  "human_emails": [
    "support@example.com"
  ]
}'
{
  "agent": {
    "agent_id": "00000000-0000-4000-8000-000000000000",
    "project_id": "00000000-0000-4000-8000-000000000000",
    "created_by_email": "string",
    "created_at": "2026-01-15T12:00:00.000Z",
    "last_update": "2026-01-15T12:00:00.000Z",
    "name": "string",
    "start_first": false,
    "first_sentence": "string",
    "agent_type": "basic",
    "who_are_you": "string",
    "goal": "string",
    "steps": "string",
    "allow_interruptions": false,
    "voice": "dania",
    "support_data": "string",
    "languages": [
      "ar"
    ],
    "stack": "latest",
    "speech_speed": 0.7,
    "variables": [
      {
        "name": "string",
        "type": "string",
        "default_value": "string"
      }
    ],
    "pre_call_callback": {
      "url": "string",
      "parameters": [
        {
          "name": null,
          "location": null,
          "data_type": null,
          "value": null
        }
      ]
    },
    "post_call_callback": {
      "url": "string",
      "parameters": [
        {
          "name": null,
          "location": null,
          "data_type": null,
          "value": null
        }
      ]
    },
    "post_analysis_callback": {
      "url": "string",
      "parameters": [
        {
          "name": null,
          "location": null,
          "data_type": null,
          "value": null
        }
      ]
    },
    "tools": [
      {
        "id": "00000000-0000-4000-8000-000000000000",
        "name": "string"
      }
    ],
    "system_tools": [
      {
        "id": "00000000-0000-4000-8000-000000000000",
        "name": "string",
        "config": {},
        "created_at": "2026-01-15T12:00:00.000Z",
        "updated_at": "2026-01-15T12:00:00.000Z",
        "when_to_use": "string"
      }
    ],
    "analysis_groups": [
      {
        "id": "00000000-0000-4000-8000-000000000000",
        "name": "string"
      }
    ],
    "background_ambient": false,
    "background_ambient_volume": 0,
    "thinking_sound": false,
    "thinking_sound_volume": 0,
    "language_mode": "single"
  },
  "text_chatbot_settings": {
    "can_refer_to_human": false,
    "human_emails": [
      "string"
    ],
    "name": "string",
    "created_at": "2026-01-15T12:00:00.000Z",
    "auto_resolve_hours": 0,
    "webhook_url": "string",
    "has_webhook_hmac_secret": false,
    "inbox_ids": [
      "00000000-0000-4000-8000-000000000000"
    ]
  }
}

How auto-reply works

Once assigned, incoming WhatsApp messages on that number are handled by the chosen agent, which generates and sends replies automatically.

agent_id

The UUID of an existing text/basic agent in this project that should answer messages.

agent_id
name

The bot's display name. It is shared by every WhatsApp number this agent answers on.

name
Human handoff

Set can_refer_to_human to true to let the bot escalate a conversation, then describe who it reaches in human_emails (see below).

can_refer_to_humanhuman_emails

Use GET /api/ext/omni_v2/whatsapp/get_chatbot to inspect the current assignment and DELETE /api/ext/omni_v2/whatsapp/unassign_chatbot to remove it.

One agent, several numbers

Assigning adds this number to the agent. The agent keeps answering on its other numbers, and their settings stay as they are.

Per-number settings

These apply to the selected number only.

can_refer_to_humanhuman_emailsauto_resolve_hourswebhook_urlwebhook_hmac_secret
Settings left out

Leaving out can_refer_to_human turns handoff off, and leaving out human_emails sends an empty list, which hands over to a random project member who can see this number's conversations. Leaving out auto_resolve_hours, webhook_url or webhook_hmac_secret keeps this number's current value, also when the request replaces the number's agent. On a number with no agent, every setting left out is copied from the agent's first number when the agent already answers on another number, and starts empty otherwise.

can_refer_to_humanhuman_emailsauto_resolve_hourswebhook_urlwebhook_hmac_secret
Replacing an agent

A number has one agent at a time. Assigning a different agent to a number replaces the previous one there; ongoing conversations on that number continue with the new agent, which does not see the previous agent's replies. The number keeps its own settings, except those sent in the request and the handoff rule above.

inbox_ids

text_chatbot_settings.inbox_ids in the response lists every WhatsApp number the agent now answers on.

inbox_ids

Choosing who the bot hands over to

human_emails accepts three shapes. Working hours are optional on any destination; when they are set, only destinations inside their window are eligible and one of them is picked at random.

Anyone availablehuman_emails: []

An empty list refers the conversation to a random project member who can see this number's conversations. Working hours are ignored on this path.

human_emails
Specific peoplehuman_emails: ["a@example.com", { "email": "b@example.com", "hours": { ... } }]

A list of addresses. Each item is either a bare string (always available) or an object with an optional hours window.

human_emails
By departmenthuman_emails: { "IT": { "desc": "...", "emails": [ ... ] } }

A category map. desc is required and is the only text the assistant sees when deciding which department fits, so make it specific. The assistant must pass a category on every call; if none of the descriptions match, nobody is contacted.

human_emails
hours{ "days": [1,2,3,4,5], "start": "09:00", "end": "17:00", "timezone": "Asia/Riyadh" }

days are ISO weekdays, 1 = Monday through 7 = Sunday; an empty list means every day. start and end are zero-padded 24-hour times, and a window whose start is later than its end wraps past midnight. timezone is an IANA zone and defaults to Asia/Riyadh.

human_emails

Addresses that do not belong to a project member who can see this number's conversations still open the conversation, but it is left unassigned.

Choosing the WhatsApp number

A project can connect more than one WhatsApp number. inbox_id selects the number this call works on.

One number

inbox_id is optional; the project's only WhatsApp number is used.

More than one number

inbox_id is required and the call returns 400 without it. An id that is not one of the project's WhatsApp numbers returns 404.

inbox_id

List the numbers and their ids with GET /api/ext/omni_v2/whatsapp/inboxes.

Errors

409 Conflict

Another change to the same number's agent, or to the same agent on another number, is still being saved. Wait a moment, then try again; GET /api/ext/omni_v2/whatsapp/get_chatbot shows the result once it is saved.

Event webhooks

Set webhook_url to receive a POST for each chatbot event on this number. Leave the field out to keep the current value, or send null to turn webhooks off.

Events

message.received: every incoming customer message on the number, including chats a person has taken over. message.replied: a reply sent by the bot. message.sent: a reply sent by a person or through the API. conversation.status_changed: a handoff to a person, the bot ending the chat, or a manual status change. conversation.auto_resolved: the chat was closed after the auto-resolve window.

webhook_url
Payload{ "event", "occurred_at", "project_id", "agent_id", "conversation_id", "data" }

For message events, data has conversation_id, content, content_type, created_at, message_type (0 = incoming, 1 = outgoing) and attachments (each with file_type and data_url). For status events, data has conversation_id, status, previous_status (can be null) and reason (refer_to_human, end_chat, auto_resolve or manual).

SignatureX-Nabrah-Signature: sha256=<hex digest>

When webhook_hmac_secret is set, each request has X-Nabrah-Timestamp (Unix seconds) and X-Nabrah-Signature: sha256= followed by the hex HMAC-SHA256 of <timestamp>.<raw request body>, keyed with your secret. Verify it against the raw body, compare in constant time, and reject old timestamps. Every request also has X-Nabrah-Event with the event name.

webhook_hmac_secret
Delivery

Each event is sent once with a 5-second timeout. Failed or non-2xx deliveries are not retried, and events have no event ID. One status change can arrive as two events, for example conversation.auto_resolved and then conversation.status_changed. Keep your handler idempotent, and use GET /api/ext/omni_v2/conversation/conversation/{id}/messages to fill any gaps.

Events are only sent while a chatbot is assigned to the number. GET /api/ext/omni_v2/whatsapp/get_chatbot returns webhook_url and has_webhook_hmac_secret; the secret itself is never returned.

Authorization

X-API-Keystringheaderrequired

Your workspace API key. Create one in the dashboard under API keys.

Query parameters

inbox_idstring

The id of the WhatsApp number to use, from GET /api/ext/omni_v2/whatsapp/inboxes.

Use inboxes[].id (a UUID), not the numeric inboxes[].inbox_id. Optional while the project has one WhatsApp number; required once it has more than one.

Body

application/json

A flat list of addresses, always available.

Specific people
{
  "agent_id": "00000000-0000-4000-8000-000000000000",
  "name": "WhatsApp Support Bot",
  "can_refer_to_human": true,
  "human_emails": [
    "support@example.com"
  ]
}

Response

200

Successful Response

application/json

422

Validation Error

application/json

PreviousList WhatsApp conversations by contactNextGet the agent on a WhatsApp number
© 2026 Nabrah. All rights reserved.
ChangelogPrivacy PolicyTerms of Service