cookbook/05_agent_os/interfaces/whatsapp/README.md
Examples for connecting Agno agents, teams, and workflows to WhatsApp using the
Whatsapp interface in AgentOS. Supports text, images, video, audio, documents,
and interactive messages (buttons, lists, location pins).
Requirements: httpx (included with agno).
Unverified accounts can still send messages to test numbers but are limited to 250 business-initiated conversations per 24 hours.
This creates your WhatsApp Business Account (WABA) and connects it to your app.
For detailed steps, see Meta's Get Started with the WhatsApp Cloud API.
You can also use the test phone number Meta provides for development. See Add a Phone Number.
System User tokens never expire and are the recommended approach for production.
whatsapp_business_messagingwhatsapp_business_managementThis is the most commonly missed step: you must assign both the App and the WABA as assets to the System User before generating the token. See System User Access Tokens.
export WHATSAPP_ACCESS_TOKEN="EAAW..." # System User token (step 4A) or temporary token (step 4B)
export WHATSAPP_PHONE_NUMBER_ID="123456789" # Phone Number ID from step 3
export WHATSAPP_APP_SECRET="..." # App Secret from step 5
export WHATSAPP_VERIFY_TOKEN="my-verify-token" # Any string you choose (must match webhook config)
export OPENAI_API_KEY="sk-..." # Or whichever model provider you use
/whatsapp/webhook:
https://your-domain.com/whatsapp/webhook
WHATSAPP_VERIFY_TOKEN env var.See Set Up Webhooks for details on the verification handshake and payload format.
.venvs/demo/bin/python cookbook/05_agent_os/interfaces/whatsapp/basic.py
Send a message to your business number from WhatsApp to test.
For quick local testing without a full production setup:
ngrok http 7777
# or: cloudflared tunnel --url http://localhost:7777
WHATSAPP_SKIP_SIGNATURE_VALIDATION=true in your
environment. Without this (or WHATSAPP_APP_SECRET), the server returns 500 on every
webhook. Never set the skip flag in production.export SSL_CERT_FILE=$(python3 -c "import certifi; print(certifi.where())")
basic.py — Minimal agent that responds to messages with session history.agent_with_user_memory.py — Agent with MemoryManager that learns about users across conversations.agent_with_media.py — Agent that receives and processes images, video, audio, and documents.image_generation_model.py — Image generation using a model with native image output.image_generation_tools.py — Image generation using DALL-E via tools.video_generation.py — Video generation agent.tourist_guide.py — Tourist guide with reply buttons, location pins, and list messages.interactive_concierge.py — Full interactive features: buttons, lists, location, reactions.reasoning_agent.py — Agent with step-by-step reasoning display.deep_research.py — Deep research agent with multiple toolkits.support_team.py — Support team routing between specialized agents.multimodal_team.py — Team combining vision input with image generation.multimodal_workflow.py — Multi-step workflow with parallel research and synthesis.multiple_instances.py — Multiple agents on one server with separate webhook prefixes.The WhatsApp interface validates all incoming webhooks:
X-Hub-Signature-256 header checked against WHATSAPP_APP_SECRET
using HMAC-SHA256. If the secret is not set, the server returns 500 (fail-closed).WHATSAPP_SKIP_SIGNATURE_VALIDATION=true to disable signature checks
for local development. Never set this in production.WhatsApp supports limited formatting compared to Slack or web:
| Supported | Not Supported |
|---|---|
*bold* | Tables |
_italic_ | Headers |
~strikethrough~ | Clickable links |
```monospace``` | Numbered lists |
> quote | Images in text |
Messages are automatically chunked at 4,096 characters. Image captions are limited to 1,024 characters.
| Symptom | Cause | Fix |
|---|---|---|
| Bot doesn't respond | Webhook not configured or server not running | Check webhook shows "Verified" in Meta portal |
| 401 Unauthorized | Token expired | Use a System User token (never expires) or regenerate temporary token |
| SSL certificate errors (macOS) | Missing cert bundle | export SSL_CERT_FILE=$(python3 -c "import certifi; print(certifi.where())") |
| Webhook verification fails | Verify token mismatch | WHATSAPP_VERIFY_TOKEN must match Meta webhook config exactly |
| 500 on every webhook | WHATSAPP_APP_SECRET not set | Set the secret, or set WHATSAPP_SKIP_SIGNATURE_VALIDATION=true for dev |
| Signature validation fails | Wrong app secret | WHATSAPP_APP_SECRET must match App > Settings > Basic |
| Messages not arriving | Not subscribed to events | Subscribe to messages field in webhook config |
| Non-PDF documents fail | API limitation | Only PDF documents are currently supported for document input |
| Can only message test numbers | Not in production mode | Complete business verification and request production access |