What you need
- A Meta developer account and a Business app with the WhatsApp product.
- A public HTTPS URL that answers GET (verification) and POST (messages).
- A System User access token: the temporary token from the dashboard expires.
Steps
- Download the Node.js template or the Python/FastAPI template.
- Deploy it: on Railway connect the repo, add WHATSAPP_TOKEN, APP_SECRET, VERIFY_TOKEN and PORT=8080, and generate a domain. On a Vultr VPS put Caddy or nginx with TLS in front of port 8080.
- In the App Dashboard set the callback URL to
https://<domain>/webhookwith the same VERIFY_TOKEN and subscribe to themessagesfield. - Send a message from your test number and watch the logs. The templates acknowledge with 200 first and reply afterwards, and reject requests with an invalid X-Hub-Signature-256.
Hosting options
| Host | Entry price | Billing model | Server admin effort |
|---|---|---|---|
| Railway | Hobby $5/mo incl. $5 of usage; Free plan $1/mo of usage | Usage (RAM, CPU, egress) | Low |
| Vultr | $5/mo (1 GB); $3.50/mo (0.5 GB) | Fixed monthly | High |
| DigitalOcean | $4/mo (512 MiB); $6/mo (1 GiB) | Fixed monthly | High |
Prices verified on 2026-10-19 on the providers' official pricing pages. They change: check before you buy. A sleeping free tier is a poor fit: Meta retries failed deliveries and slow cold starts cause duplicates.
Messaging costs
Meta charges for some template messages by category and country; hosting is a separate cost. We do not copy Meta's rates here because they change by market: estimate your volume with the WhatsApp API cost calculator using the rates from Meta's official pricing page.
Related guides and tools
- WhatsApp API cost calculator
- Railway vs Vultr for bots
- Bot security guide
- Starter templates
- Webhook vs polling: hosting impact
Frequently asked questions
Can I use a personal WhatsApp number?
The Cloud API uses a business phone number registered in your Meta app. Unofficial libraries that automate the personal app can break WhatsApp's terms and get the number banned.
Why is my webhook not verified?
The GET must return hub.challenge exactly when hub.verify_token matches; check the URL path, HTTPS and the VERIFY_TOKEN value.
Do I need a server running 24/7?
You need an endpoint that answers quickly whenever Meta calls; an always-on small service is the most reliable choice.