Skip to main content

WhatsApp Bot

Run an AI agent on your WhatsApp Business number: connect a WABA, auto-reply to inbound messages, and send, template, campaign and call through one API.

CallMissed connects your WhatsApp Business Account (WABA) to an AI agent. Inbound messages land on a webhook, get stored as a conversation, and are answered by your bot's system prompt plus knowledge base. Everything the agent can do by itself you can also do programmatically over the REST API: send any WhatsApp message type, manage approved templates, run bulk template campaigns, place voice calls on WhatsApp, and read delivery analytics.

What you get

CapabilityWhere
AI auto-reply to inbound WhatsApp messagesAutomatic once a bot is linked to a number
Send text, template, media, interactive, flow, location, reaction, contact cardsSending Messages
Create, list, delete and sync message templates, including carousel, limited-time offer and coupon formatsMessage Templates
Bulk template sends with per-recipient variablesCampaigns
Take UPI payments in the chat with order details and order status messagesPayments
Build, publish and send WhatsApp Flows (in-chat forms)Flows
Catalog settings and product, product list and catalog messagesCatalog & Orders
Voice calls over WhatsApp, answered by the same agentCalling
Connected accounts, numbers, ice breakers and commands, delivery funnel, costWhatsApp API
Number health, registration, two-step PIN, business profile, blocked users, QR codesNumber Management

Two ways in

Dashboard. Connect a number under Settings → Integrations → WhatsApp, create a bot, link the two, and the agent starts replying. Nothing to build.

API. Everything the dashboard does is an endpoint under https://api.callmissed.com/api/v1/whatsapp, authenticated with a cm_ API key. Use it to embed WhatsApp into your own product, run campaigns from your backend, or ship a custom inbox.

The two share one data model. A number connected in the dashboard is immediately sendable from the API, and a message sent over the API appears in the dashboard conversation thread.

Message flow

Meta posts every inbound event to a single CallMissed endpoint. You never configure that endpoint yourself: connecting a number subscribes the CallMissed app to your WABA's webhooks.

  1. 1

    Customer

    Sends a WhatsApp message to your business number

  2. 2

    Meta

    Delivers the event to CallMissed, signed by Meta

  3. 3

    CallMissed

    Verifies the signature and acknowledges immediately

  4. 4

    Agent

    Routes the number to its linked bot, stores the message, marks it read, and runs the LLM with the conversation history plus knowledge base

  5. 5

    Customer

    Receives the reply through the WhatsApp Cloud API

The acknowledgement is sent before the LLM runs, so a slow model never causes Meta to retry the event.

When the bot replies

An inbound message is always stored. The agent only answers when all of these hold:

  1. The number is explicitly linked to a bot (POST /phone_numbers/{phone_id}/link-bot). An unlinked number stores messages and stays silent.
  2. The bot has a non-empty system_prompt.
  3. AI auto-reply is on for the number (ai_autoreply_enabled, togglable per number).
  4. AI auto-reply is on for that conversation (an agent can take over a single thread from the inbox without pausing the whole number).
  5. The message is text, or an image when the bot's model supports vision. Audio, stickers, reactions, interactive replies and other types are stored but not auto-answered.

Quickstart

Send your first message and get an AI reply in five calls. You need an API key with the whatsapp:read, whatsapp:write and whatsapp:send scopes, plus a connected number (Business Setup).

Create the bot

curl -X POST https://api.callmissed.com/api/v1/bots \
  -H "Authorization: Bearer cm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Support",
    "type": "whatsapp",
    "system_prompt": "You are the support agent for Acme, an Indian D2C coffee brand. Answer in under 60 words. If asked about an order, ask for the order id first. Never invent a delivery date."
  }'

The response carries the bot id. Keep it.

{
  "id": "0a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
  "tenant_id": "7f2e1d0c-9b8a-4756-b3c2-1a0f9e8d7c6b",
  "name": "Acme Support",
  "type": "whatsapp",
  "system_prompt": "You are the support agent for Acme...",
  "is_active": true
}

Find your connected number

curl https://api.callmissed.com/api/v1/whatsapp/phone_numbers \
  -H "Authorization: Bearer cm_your_api_key"

Take id (CallMissed's phone_id) and phone_number_id (Meta's id) from the number you want to use.

Without this the bot never auto-replies.

curl -X POST https://api.callmissed.com/api/v1/whatsapp/phone_numbers/9c2b7e30-1d8a-4c5f-9b3d-2f4a6e8b1c2d/link-bot \
  -H "Authorization: Bearer cm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "bot_id": "0a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d" }'

Subscribe to inbound messages

Register your own HTTPS endpoint so every customer message is pushed to you.

curl -X POST https://api.callmissed.com/api/v1/webhooks \
  -H "Authorization: Bearer cm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.example.com/hooks/callmissed",
    "events": ["message.received"]
  }'

See Inbound events for the exact payload and the signature header.

Send a message

Free-form sends need an open 24-hour window (the customer messaged you within the last 24 hours). Outside it, send a template instead.

curl -X POST https://api.callmissed.com/api/v1/whatsapp/messages \
  -H "Authorization: Bearer cm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number_id": "1234567890",
    "to": "+919000000000",
    "text": "Thanks for reaching out. How can we help?"
  }'
{
  "wamid": "wamid.HBgMOTE5MDAwMDAwMDAwFQIAERgSMkE5N0Y4RDcxMkYzQTJEMQA=",
  "contacts": [{ "input": "+919000000000", "wa_id": "919000000000" }]
}

Now message your business number from a personal WhatsApp account. The message appears in the dashboard conversation, hits your webhook, and the agent answers.

The 24-hour window

WhatsApp only allows free-form messages (text, media, interactive, location) inside the 24-hour customer service window that opens each time the user messages you. Outside it you must send an approved template.

A closed-window send returns 422 with an actionable message:

{
  "detail": "The 24-hour customer service window is closed. Send a template message instead, or wait for the user to message you."
}

Templates are never window-limited, which is why order updates, reminders and one-time codes are all template sends. See Message Templates.

Bot configuration

A bot is channel-agnostic. What makes it a WhatsApp agent is the link-bot binding to a connected number, not its config. Credentials live on the connected number (encrypted at rest), so a linked bot needs no WhatsApp keys of its own.

{
  "name": "Acme Support",
  "type": "whatsapp",
  "system_prompt": "You are the support agent for Acme Coffee.",
  "config": {
    "model": "kimi-k2.5",
    "language": "en"
  }
}

Add product facts, FAQs and policies as knowledge base entries. The agent calls a search_knowledge_base tool on demand and grounds its answer in what it retrieves.

Where to next