1. Docs
  2. Integrations
  3. WhatsApp

Build a WhatsApp astrology bot with RoxyAPI

Reply to "HOROSCOPE ARIES" with the daily reading, or to "KUNDLI" with a Vedic chart, on WhatsApp using the official Cloud API. One Meta access token, one Roxy API key, one webhook handler.

The WhatsApp Cloud API is the hosted, no-infrastructure way Meta lets you send and receive WhatsApp messages from a server. Unlike Telegram, WhatsApp is a webhook-only platform: messages arrive as POST requests, replies are POST requests back to a Meta endpoint. RoxyAPI provides the spiritual data layer behind your bot: 130+ astrology, Vedic astrology, tarot, and numerology endpoints behind one key, plus a remote MCP server per domain when you want an LLM to route the call on its own.

TL;DR

  • You will ship a WhatsApp bot that replies to keywords like HOROSCOPE ARIES and TAROT with live RoxyAPI data
  • You need a Meta Developer account (free), a WhatsApp Cloud API test number (free during development), and a RoxyAPI key (plans start at $39 a month, free test key on request via contact)
  • Working code in three languages, ready to deploy to any HTTPS host. About 30 minutes start to finish, most of it Meta onboarding

WhatsApp Cloud API has stricter onboarding than Telegram. The free test number can message up to 5 verified recipients during development. Production needs a real phone number tied to a Meta Business account, business verification, and approved message templates for any outbound message sent outside the 24-hour customer-service window. Plan for that before you scale.

What you can build on WhatsApp

  • A keyword-triggered horoscope bot that replies to HOROSCOPE LEO with the daily reading
  • A KUNDLI flow that asks for birth date, time, and city, then replies with a Vedic chart
  • A daily tarot card pushed to opted-in subscribers via approved message templates
  • A multi-language wellness bot that picks language from the WhatsApp user locale and calls Roxy with ?lang=hi, ?lang=es, or ?lang=tr
  • A panchang assistant for Hindu calendar lookups (PANCHANG TODAY MUMBAI)
  • A numerology onboarding flow that returns Life Path, Expression, and Soul Urge from a name and birth date
  • An AI agent bot where the LLM picks between horoscope, kundli, and tarot endpoints based on the message text

What you need

  1. A Meta for Developers account. Free.
  2. A WhatsApp app set up in Meta Developer Console, with a test phone number and access token. Follow the Cloud API getting-started guide. Free during development.
  3. A RoxyAPI key. Plans start at $39 a month on the pricing page; a free test key for evaluation is available on request via contact.
  4. A public HTTPS endpoint for the webhook. ngrok works for local testing. Vercel, Fly.io, Railway, Render, or any host with TLS works for production.
  5. About 30 minutes, most of it Meta onboarding.

Run the quickstart curl in a terminal first. A 200 response confirms the Roxy key is good before Meta tries to POST anything to your handler.

Step 1, register the webhook with Meta

Meta verifies your webhook endpoint with a one-time GET handshake before subscribing it to message events. Your handler needs two routes on the same path: a GET that echoes the verify challenge, and a POST that processes incoming messages.

Meta sends a one-time GET with three query params: hub.mode=subscribe, hub.verify_token=YOUR_SECRET, and hub.challenge=RANDOM_STRING. Your handler checks the token matches a value you set in the Developer Console, and echoes the challenge as plain text.

# Meta will fire something like this against your endpoint
curl "https://your-app.example.com/webhook?hub.mode=subscribe&hub.verify_token=my_secret&hub.challenge=12345"

If the response is 12345 with status 200, the webhook is verified. The token never appears again. From this point on Meta only sends POSTs.

Step 2, ship the keyword reply handler

The example below handles a one-shot HOROSCOPE <SIGN> keyword and replies with the daily reading. Run the curl smoke test first to confirm Roxy is responding, then drop the handler behind your webhook URL.

curl "https://roxyapi.com/api/v2/astrology/horoscope/aries/daily" \
  -H "X-API-Key: $ROXY_API_KEY"

You should get back JSON with sign, date, overview, love, career, luckyNumber, moonSign, moonPhase, and energyRating. Pick the fields you want in the bot reply.

Send HOROSCOPE ARIES from a verified test recipient to your WhatsApp test number. The bot replies within a second.

Bonus, send the daily tarot card as a media message

The tarot/daily response carries card.imageUrl, a public CDN URL. WhatsApp accepts a remote image URL in the image payload, so you can return the card image with no extra hosting.

Drop this block inside the /webhook POST handler from above; it reuses the same roxy, msg, GRAPH, and ACCESS_TOKEN variables.

const { data } = await roxy.tarot.getDailyCard({ body: { seed: msg.from } });
await fetch(GRAPH, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${ACCESS_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    messaging_product: 'whatsapp',
    to: msg.from,
    type: 'image',
    image: {
      link: data.card.imageUrl,
      caption: `${data.card.name}${data.card.reversed ? ' (reversed)' : ''}\n\n${data.dailyMessage}`,
    },
  }),
});

Seeding by msg.from (the user phone number) makes the daily card deterministic per user per day. Same recipient asks ten times before midnight, gets the same card every time. Works the same way in Python via roxy.tarot.get_daily_card(seed=msg['from']).

Step 3, scale to the full surface

Adding a new keyword is the same shape as HOROSCOPE. Pick the endpoint, build the parameters, format the reply.

Any chart, panchang, dasha, dosha, navamsa, KP, synastry, or compatibility endpoint needs latitude, longitude, and timezone. Always call roxy.location.searchCities (TS) or roxy.location.search_cities (Py) first. Pass the IANA timezone straight through; the server resolves DST for the chart date.

Add an MCP-powered AI agent (optional)

A keyword bot is rigid. For free-text questions ("what does my chart say about marriage?"), point an LLM at the Roxy MCP server and let it pick the endpoint.

The remote MCP server runs at https://roxyapi.com/mcp/{domain} over Streamable HTTP. No stdio, no Docker, no local setup. Point Claude Code, Cursor, OpenAI Agents SDK, or any other MCP-aware client at the URL with your X-API-Key header. The agent inspects tools/list, picks the right tool, builds parameters, and calls Roxy.

Inside your WhatsApp handler, forward msg.text.body to the agent, await the answer, send it back. tools/list is free. Every tools/call bills the same as the equivalent REST call. See /docs/mcp for the full setup.

Frequently asked questions

Why does Meta only let me message 5 numbers in development?

The free test number is sandboxed. Add up to 5 phone numbers as verified recipients in the WhatsApp app settings. To message anyone outside the list, you need a real phone number, Meta Business verification, and approved message templates.

What is the 24-hour customer-service window?

Once a user messages your bot, you have 24 hours to reply with any free-form text or media. Outside that window, every outbound message must use a pre-approved template. This is a Meta policy, not a Roxy limit. Plan keyword and reply flows around inbound triggers.

How do I keep the bot from burning quota on group spam?

WhatsApp Cloud API does not deliver group messages to bots. You only see direct messages to your business number, so group spam is not a vector. Standard rate limits still apply: cache daily content (horoscopes, panchang) per recipient with a short-lived KV so repeat senders pay for one Roxy call.

Can the bot reply in Hindi, Spanish, or Turkish?

Yes. Most Roxy domains accept a lang query parameter (en, tr, de, es, fr, hi, pt, ru). In the SDK, pass query: { lang: 'hi' } (TS) or lang='hi' (Py). Meta also passes contacts[0].profile.locale in some payloads if you want to detect language from the user.

Should I verify the X-Hub-Signature-256 header?

Yes for production. Meta signs every webhook POST with HMAC SHA256 using your app secret. Compare the X-Hub-Signature-256 header against sha256=<hmac-of-raw-body>. Reject mismatches. The exact recipe is in the Meta webhook security guide.

What happens if I reply 500 to Meta?

Meta retries delivery for up to 7 days. Always send a 200 first, then process the message asynchronously. The example handlers above ack inside the route and process the Roxy call after.

Gotchas

  • Backend-only key. The Roxy key and Meta access token both live in your handler. Never echo either to a WhatsApp user, never check them into git.
  • Webhook URL must be HTTPS with a valid cert. Self-signed certs do not work. Use ngrok for local dev.
  • Meta deeply nests the message. Always destructure defensively (body?.entry?.[0]?.changes?.[0]?.value?.messages?.[0]) and skip non-text messages instead of crashing on the parse.
  • type: 'text' is one of many. Image, audio, video, location, contacts, and interactive replies all arrive in the same messages[] array. Filter on msg.type before parsing.
  • Outbound rate limits are tier-based (250 to 100K conversations per 24 hours depending on your messaging tier). New numbers start at the lowest tier and graduate based on quality score.
  • Templates need approval. A "Your daily horoscope is ready" push needs an approved Marketing template. Reactive replies inside the 24-hour window do not.
  • Timezone IANA wins. Prefer "Asia/Kolkata" to 5.5. The server resolves DST per chart date, so a January 1990 New York birth gets EST and a July birth gets EDT automatically.
  • MCP tools/call is billable, tools/list is free. When debugging an agent, the discovery call does not count, the actual answer does.

What to build next