How to Build a WhatsApp AI Agent with Claude Code

Register a WhatsApp Cloud API number, point its webhook at a small server, and forward each inbound message to a Claude Code agent that replies through the Graph API. Add a retrieval layer so repeated questions resolve from stored chunks, cutting per-message token cost 80 to 90 percent.

What you are building

A WhatsApp AI agent is three moving parts. First, the WhatsApp Cloud API delivers each inbound message to a webhook you host. Second, your server hands that message to a Claude Code agent that decides how to answer. Third, the agent sends a reply back through the Graph API messages endpoint.

The naive version calls the LLM on every single message. That works in a demo and bankrupts you in production, because support traffic is repetitive. The same twelve questions arrive thousands of times: hours, shipping, returns, order status, pricing. This guide wires the loop first, then puts a retrieval layer in front of the model so those repeats stop costing a full generation each.

Prerequisites and setup

You need a Meta developer account, a WhatsApp Business phone number, and a public HTTPS endpoint. During development, a tunnel to localhost is enough to receive live webhooks.

Get your WhatsApp credentials

In the Meta developer dashboard, add the WhatsApp product to an app. You get a test phone number ID and a temporary access token. Copy the phone number ID and token into environment variables. For production, generate a permanent system user token so it does not expire every 24 hours.

Expose a webhook URL

WhatsApp needs a public HTTPS URL to deliver messages. Run your server locally and open a tunnel, then paste the tunnel URL plus a path like /webhook into the app's webhook configuration. WhatsApp sends a one-time verification GET with a challenge token you must echo back.

Wire the webhook to a Claude Code agent

The receiver has two jobs. On GET, it answers the verification handshake by returning the hub.challenge value when hub.verify_token matches your secret. On POST, it parses the message payload, extracts the sender's number and text, and forwards the text to the agent.

Keep the handler thin. Acknowledge the webhook with a 200 immediately, then process the message asynchronously. WhatsApp retries deliveries that do not get a fast 200, and slow handlers cause duplicate messages. The agent produces a reply string, and you POST it back to /{phone-number-id}/messages with the recipient's number.

Message flow in plain terms

Inbound message arrives at the webhook. Server returns 200. Server reads the text and the sender ID. The retrieval layer is checked first. If it returns a confident chunk, the agent formats that into a reply. If not, the agent calls the model as a fallback. The final text goes out through the Graph API send call.

Handle status callbacks and the 24 hour window

WhatsApp posts delivery and read status events to the same webhook. Filter those out so you do not treat a delivered event as a user message. Remember the policy rule: outside the 24 hour customer service window you can only send pre-approved template messages, not free-form text.

Cut per-message cost with a retrieval layer

Support chat is the ideal case for retrieval because the question distribution has a fat head. Once you have answered "where is my order" well, you never need the model to compose that answer again.

Retrieval Development Kit (RDK) indexes your help docs, past resolved tickets, and policy pages as encrypted private chunks. When a message arrives, the agent searches those chunks before it touches the LLM. A confident match returns the stored answer, and you spend a small retrieval cost instead of a full generation. Across a real support queue this cuts per-message token spend 80 to 90 percent, because the model only runs on the genuinely novel questions.

Stacked retrieval for a support bot

With stacked retrieval, your private vault of docs and tickets answers 40 to 65 percent of queries directly. The public RDK network, where other teams publish common answers, adds another 15 to 20 percent. The LLM handles the remaining 5 to 10 percent as fallback for the questions nothing has seen yet. Each layer is cheaper than the one below it.

Concrete examples: FAQ and order status

An FAQ question like "do you ship internationally" matches a policy chunk and returns verbatim, no generation needed. An order-status question is a hybrid: the agent retrieves the response template and tone from a chunk, then fills in the live tracking number from your order API. The model is not asked to write prose it has already written a thousand times.

Ship it to production

Swap the temporary token for a permanent one, move the webhook off the tunnel onto a hosted endpoint, and add basic idempotency so retried webhooks do not double-reply. Log every inbound message, whether it was answered from a chunk or the model, and the resolution. That log becomes your next batch of chunks to index.

As your chunk library grows, the share of messages answered without an LLM call climbs, and your cost per conversation keeps falling. If you publish your best answers as public chunks, other agents retrieve them and you earn USDC per retrieval through the CryptoCadet rail on Base.

Frequently asked questions

How long does it really take to build a WhatsApp AI agent?
The core loop, a verified webhook, an agent call, and a Graph API reply, takes about 30 minutes if your Meta account and phone number are already set up. Adding the retrieval layer and indexing your first help docs is another short session, and it is what makes the bot affordable to run at volume.
Why put retrieval in front of the model instead of just calling the LLM?
WhatsApp support traffic is highly repetitive, so calling the model on every message means paying to regenerate the same answers endlessly. Retrieval answers repeat questions from stored chunks for a fraction of the cost, cutting per-message token spend 80 to 90 percent and reserving the model for genuinely new questions.
Can a retrieval-backed agent still handle order status lookups?
Yes. Order status is a hybrid query. The agent retrieves the response template and tone from an indexed chunk, then calls your order API for the live tracking data and fills it in. You avoid paying the model to write boilerplate prose while still returning real-time, account-specific information.
What are the WhatsApp policy limits I should know about?
Outside the 24 hour customer service window that opens when a user messages you, you can only send pre-approved template messages, not free-form replies. Your webhook also receives delivery and read status callbacks, which you must filter out so they are not mistaken for user messages.