Skip to main content

Documentation Index

Fetch the complete documentation index at: https://vaquill.ai/docs/llms.txt

Use this file to discover all available pages before exploring further.

A WhatsApp bot that bridges Twilio to the Vaquill /ask API. Users message a WhatsApp number, Twilio forwards to your FastAPI server, the bot calls Vaquill, and the answer (with cited sources) returns asynchronously to avoid Twilio’s 15-second timeout. Source code at github.com/Vaquill-AI/integrations/whatsapp-bot.

Features

  • Two research modes per user (standard and deep) switchable with /mode
  • Per-user conversation history with configurable session timeout
  • Rich slash commands: /help, /examples, /stats, /mode, /language, /clear, /feedback, /about, /settings
  • Per-user rate limits (per-minute, per-hour, per-day)
  • Phone-number allowlists and blocklists
  • Input validation (SQL/XSS/command injection detection, length limits)
  • Multi-language replies (en, es, fr, de, pt, ja, ko, zh, ar, hi)
  • Optional Redis-backed sessions and rate limits
  • Admin endpoints for per-user stats and broadcasts

Prerequisites

RequirementNotes
Python 3.10+3.12 recommended
Vaquill API keyFrom app.vaquill.ai/settings. Starts with vq_key_. See Authentication.
Twilio accountFree trial works for the sandbox - it includes $15 in credit
ngrok (local dev only)Free account at ngrok.com to tunnel webhooks
Redis (optional)Required only for multi-instance or persistent sessions

Platform setup

WhatsApp does not allow direct bot integrations - you connect through a Business Solution Provider. Twilio is the simplest path: minutes to set up vs weeks for direct WhatsApp Business API access.

Sandbox (free, for development)

1

Create a Twilio account

Sign up at twilio.com/try-twilio. Verify your email and phone. When asked for use case, pick Developer or WhatsApp.
2

Grab your credentials

From the Twilio Console dashboard, copy:
  • Account SID - starts with AC (e.g. ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)
  • Auth Token - click the eye icon to reveal
The Account SID must start with AC. Values starting with US are not Account SIDs and will return 401.
3

Activate the WhatsApp Sandbox

Console > Messaging > Try it out > Send a WhatsApp message. You will see a sandbox number (typically +1 (415) 523-8886) and a join code like join brave-tiger. From your personal WhatsApp, send that exact message to the sandbox number. You should receive “You are all set!”.The sandbox number becomes your TWILIO_WHATSAPP_NUMBER, formatted as whatsapp:+14155238886.
4

Configure the webhook

On the same page, under Sandbox Configuration > When a message comes in, paste your bot’s webhook URL:
  • Local dev: https://<ngrok-subdomain>.ngrok-free.app/webhook/whatsapp
  • Production: https://your-domain.com/webhook/whatsapp
Method: POST. Click Save.
Sandbox limitations: every user must send join <keyword> first; you can only reply within 24 hours of the user’s last message; the number is shared with other Twilio sandboxes; not suitable for real customers.

Production (paid WhatsApp Business sender)

For real customers you need a verified business sender:
  1. Upgrade to a paid Twilio account (trial accounts cannot register WhatsApp senders).
  2. Console > Messaging > Senders > WhatsApp Senders > Register a WhatsApp Sender.
  3. Register your business with Meta, submit your WhatsApp Business Profile, get a dedicated number, and submit message templates for approval (required for outbound messages outside the 24-hour window).
  4. Verification typically takes 2-5 business days.
  5. Once approved, set TWILIO_WHATSAPP_NUMBER to your new number.
SandboxProduction
CostFree~15/month+ 15/month + ~0.005/message
Phone numberTwilio’s shared numberYour own business number
User onboarding”join <keyword>” requiredDirect messaging
Message window24 hours after user message24 hours + approved templates
Setup time~5 minutes2-5 business days
The 24-hour customer-service window is a WhatsApp policy, not a Twilio limit. Outside that window you can only send approved template messages.

Quickstart

1

Clone and install

git clone https://github.com/Vaquill-AI/integrations.git
cd integrations/whatsapp-bot
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
2

Configure

cp .env.example .env
Fill in the required values:
VAQUILL_API_KEY=vq_key_your_key_here
VAQUILL_COUNTRY_CODE=US
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_WHATSAPP_NUMBER=whatsapp:+14155238886
3

Run the bot

DEBUG=true python bot.py
# or, production:
# uvicorn bot:app --host 0.0.0.0 --port 8000
4

Tunnel with ngrok (local dev)

In a second terminal:
ngrok config add-authtoken YOUR_NGROK_AUTH_TOKEN
ngrok http 8000
Copy the HTTPS forwarding URL and update the Twilio sandbox webhook to https://abc123.ngrok-free.app/webhook/whatsapp.
Free ngrok URLs change every restart - update Twilio each time. For a stable URL, use a paid ngrok plan or deploy to a cloud host.
5

Test

Send “Hi” to the sandbox number to get a welcome message, then ask:
What does FRCP Rule 12(b)(6) require for a motion to dismiss?

Configuration

The most-used env vars. Full list in the repo .env.example.
VariableRequiredDefaultDescription
VAQUILL_API_KEYYes-Vaquill API key (vq_key_...)
TWILIO_ACCOUNT_SIDYes-Twilio Account SID (starts with AC)
TWILIO_AUTH_TOKENYes-Twilio Auth Token
TWILIO_WHATSAPP_NUMBERYes-Sender number with whatsapp: prefix
VAQUILL_MODENostandardDefault research mode
VAQUILL_COUNTRY_CODENoINJurisdiction filter, e.g. US
RATE_LIMIT_DAILYNo100Per-user daily cap
RATE_LIMIT_HOURNo30Per-user hourly cap
RATE_LIMIT_MINUTENo5Per-user minute cap
REDIS_URLNo-Enables persistent sessions and rate limits
ALLOWED_NUMBERSNo-Comma-separated phone allowlist
SESSION_TIMEOUT_MINUTESNo30Conversation context expiry
PORTNo8000Server port

Commands

CommandDescription
/startWelcome message with example questions
/helpShow all commands
/examplesList example questions; /examples criminal for a category
/mode / /mode standard / /mode deepView or switch research mode
/statsToday / hour / total usage for this user
/language / /language enView or switch reply language
/clearClear conversation history
/feedback <message>Send feedback to operators
/aboutVaquill info
/settingsView current language, mode, and limits
Any non-slash message is treated as a legal question.

Deployment

Docker

docker build -t vaquill-whatsapp-bot .
docker run -p 8000:8000 --env-file .env vaquill-whatsapp-bot
With Compose + Redis:
services:
  bot:
    build: .
    ports:
      - "8000:8000"
    env_file: .env
    environment:
      - REDIS_URL=redis://redis:6379/0
    depends_on:
      - redis
    restart: unless-stopped
  redis:
    image: redis:7-alpine
    volumes:
      - redis-data:/data
    restart: unless-stopped
volumes:
  redis-data:

Cloud hosts

Render

New Web Service. Build: pip install -r requirements.txt. Start: python bot.py. Free tier cold-starts in 30-60s - keep warm with an uptime monitor.

Railway

Auto-detects Python. Add env vars under Variables, get a .up.railway.app URL.

Fly.io

fly launch, fly secrets set ..., fly deploy. Global low-latency regions.

VPS

Run uvicorn behind nginx + Let’s Encrypt for TLS.
After deploying, set the Twilio webhook to https://your-domain.com/webhook/whatsapp (POST).

Troubleshooting

SymptomFix
No response at allConfirm bot and ngrok are running. Confirm webhook URL ends with /webhook/whatsapp and method is POST.
Twilio 401Account SID must start with AC. Re-check TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN.
ngrok URL changedFree ngrok rotates URLs on restart. Update Twilio after each restart, or use a paid plan / cloud host.
Messages arrive but no replyCheck bot logs for insufficient_credits (top up at app.vaquill.ai/settings), 401 (invalid Vaquill key), or rate-limit hits.
”You are not authorized”ALLOWED_NUMBERS is set and excludes this caller, or the number is in BLOCKED_NUMBERS.
Sandbox session expiredResend join <keyword> to the sandbox number.
Slow repliesSwitch from deep to standard with /mode standard. Deep mode uses 35 retrieval techniques and is intentionally slower.
21608 Recipient not in sandboxUser must send the sandbox join code first.
Quick connectivity test:
curl http://localhost:8000/health

curl -X POST http://localhost:8000/webhook/whatsapp \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "From=whatsapp:+15551234567&Body=Hello&MessageSid=test123"

Telegram

No business-verification overhead.

Signal

Privacy-first messenger alternative.

Chatbots overview

Compare all six platforms.

Authentication

How Vaquill API keys work.