Skip to content

Guide 02

How to build a WhatsApp AI agent for your business, step by step.

These are the four steps we follow to build an AI agent on WhatsApp, with what Meta's platform asks for at each one. It's written for the person who decides whether to build one, with enough detail for the engineer who will.

Edwin Barrera · Founder and software architect

· 4 min read

Before you start

A WhatsApp agent runs on Meta's WhatsApp Business Platform through the Cloud API, not on the WhatsApp app on someone's phone. To use it you need:

  • A Meta business account, and a WhatsApp Business Account inside it.
  • A phone number for the agent: the one your customers already know, moved to the platform, or a new one.
  • Someone at your company who can approve the setup in Meta's tools. The accounts stay in your name.

Meta's getting started guide walks through the setup. When we build the agent, we do it with you in the first milestone.

1. Map the job

Start from real conversations, not from what the agent could do. Export a few weeks of chats, read them, and write down three lists: what it handles, what it never does, and when it hands off to a person.

An example for a store that sells over WhatsApp
It handlesIt never doesIt hands off when
Questions about products, prices and stock, from the catalog.Promise a refund, a discount or a delivery date it can't check.The customer complains or asks for a person.
Order status, from the order system.Ask for card numbers in the chat.A payment failed or an order is missing.
Store hours and locations.Answer questions outside the store's business.It can't find the answer in your data.

These lists become the agent's instructions and, later, its test cases. Keep the first version to one job. A second one can come once the first passes its evals.

2. Wire it to your data

An agent answers well when it looks things up instead of remembering them. It gets two kinds of access:

  • Tools: small actions on your systems, such as check_stock, find_order or book_slot. Each does one thing, and the agent can't do anything its tools don't allow.
  • Retrieval: search over your documents and help pages, so each answer comes with the passage it came from.

Messages reach the agent through a webhook: Meta sends each new message to an address on your server, and the agent replies through the Cloud API. This is the skeleton in Python with FastAPI, the stack we use:

Receive messages: verify the webhook, check Meta's signature, answer outside the request
import hashlib
import hmac
import os

from fastapi import BackgroundTasks, FastAPI, HTTPException, Request
from fastapi.responses import PlainTextResponse

app = FastAPI()
VERIFY_TOKEN = os.environ["WHATSAPP_VERIFY_TOKEN"]
APP_SECRET = os.environ["META_APP_SECRET"].encode()


@app.get("/webhooks/whatsapp")
def verify(request: Request) -> PlainTextResponse:
    # Meta calls this once, when you register the webhook.
    query = request.query_params
    if query.get("hub.mode") == "subscribe" and query.get("hub.verify_token") == VERIFY_TOKEN:
        return PlainTextResponse(query.get("hub.challenge", ""))
    raise HTTPException(403)


@app.post("/webhooks/whatsapp")
async def receive(request: Request, tasks: BackgroundTasks) -> dict[str, str]:
    body = await request.body()
    signature = "sha256=" + hmac.new(APP_SECRET, body, hashlib.sha256).hexdigest()
    if not hmac.compare_digest(signature, request.headers.get("X-Hub-Signature-256", "")):
        raise HTTPException(401)
    payload = await request.json()
    for entry in payload.get("entry", []):
        for change in entry.get("changes", []):
            for message in change["value"].get("messages", []):
                # Answer outside the request: Meta expects a quick 200.
                tasks.add_task(answer, message)
    return {"status": "received"}
Reply through the Cloud API
import httpx

GRAPH = "https://graph.facebook.com/v23.0"  # the Graph API version your app uses
PHONE_NUMBER_ID = os.environ["WHATSAPP_PHONE_NUMBER_ID"]
TOKEN = os.environ["WHATSAPP_TOKEN"]


async def answer(message: dict) -> None:
    ...  # the agent: look things up with its tools, decide, then send_text() or hand off


async def send_text(to: str, text: str) -> None:
    async with httpx.AsyncClient() as client:
        response = await client.post(
            f"{GRAPH}/{PHONE_NUMBER_ID}/messages",
            headers={"Authorization": f"Bearer {TOKEN}"},
            json={"messaging_product": "whatsapp", "to": to, "type": "text", "text": {"body": text}},
        )
        response.raise_for_status()
  • Meta signs each delivery with your app secret. Check the signature before you trust the payload.
  • Return 200 quickly and answer from a background job. Meta retries deliveries that fail, so the same message can arrive twice: keep the ids of the messages you've handled and skip repeats.
  • Keep tokens and secrets in a secret manager, never in the code.

3. Write the evals

Evals tell you the agent is ready before a customer finds out it isn't. Each one is a real message with the outcome it should get:

Three eval cases for the store above
{"message": "Do you have the black running shoes in size 42?", "expect": "answer", "must_use": "check_stock"}
{"message": "My order never arrived and I want my money back", "expect": "hand_off"}
{"message": "Can you give me a discount if I buy two?", "expect": "decline", "must_not": "offer a discount"}
  • Take the cases from your real chats, hard ones included: complaints, angry messages, questions it must not answer.
  • Agree on a pass threshold before the build, and keep the agent off until it meets it.
  • Run the whole set on every change, and again when the model or the prompt changes.
  • Add cases in each language your customers write in.

On this site

The AI that sorts the briefs we receive has 31 graded cases and stays off until it passes 90% of them. The agents we build follow the same rule, with a threshold agreed with you.

4. Pilot and watch

Open it to a small group of real customers first, with your team watching:

  • A console where your team reads conversations and takes over the ones the agent hands off, with the conversation so far.
  • A second AI provider that takes over if the first one fails, so an outage doesn't leave customers without an answer.
  • The cost of every conversation, so you know what the agent will cost at full volume.

Every conversation that goes wrong becomes a new eval case. When the agent passes the set again, the pilot grows.

WhatsApp's rules that shape the design

Meta's platform has rules a website chat doesn't. Three of them change how the agent is built:

  • Customers write first. The agent replies freely in the customer service window that opens when a customer writes. To start a conversation, or to write after that window closes, a business can only send message templates that Meta approves beforehand (how templates work).
  • Opt-in comes first. Before you message someone who hasn't written to you, they must have agreed to hear from you on WhatsApp, as Meta's Business Messaging Policy requires.
  • Templates are billed. Meta charges for them by category and country; its pricing page has the rates.

So we design for it from the first step: the agent answers inside the window, and the messages it has to start, like reminders and order updates, go out as approved templates.

What it costs

Building one with us is an AI Agent engagement, from $8,000, with a fixed price per milestone. Model usage and Meta's fees are billed to your own accounts. The details are in How much does an AI agent cost?, and the service is at WhatsApp AI agents.

Read next

Have something to build? Tell us about it.

A person reads every brief and replies with questions or a first plan.