Sign in

RouteKit vs WhatsApp Business Cloud API

What changes when you replace whatsapp-web.js and pywa with a single RouteKit integration.

The WhatsApp way

WhatsApp does not have an official SDK the way Slack or Discord do. Instead you work directly with the WhatsApp Business Cloud API over HTTP, or use community libraries like whatsapp-web.js and pywa. Either way, the setup is heavy.

  • Set up a Meta Business account, create a WhatsApp Business app, and register a phone number.
  • Host a webhook endpoint and implement Meta's verification handshake (hub.mode, hub.verify_token, hub.challenge).
  • Parse deeply nested webhook payloads to extract the actual message text.
  • Send replies via HTTP POST to the Cloud API with a permanent access token.
  • Handle message templates (required for outbound messages outside the 24-hour window) and get them approved by Meta.
whatsapp-agent.tsTypeScript
import express from "express";

const server = express();
const TOKEN = process.env.WHATSAPP_TOKEN;
const VERIFY_TOKEN = process.env.WHATSAPP_VERIFY_TOKEN;

// Webhook verification
server.get("/webhook", (req, res) => {
  if (req.query["hub.verify_token"] === VERIFY_TOKEN) {
    res.send(req.query["hub.challenge"]);
  } else {
    res.sendStatus(403);
  }
});

// Receive messages
server.post("/webhook", async (req, res) => {
  const entry = req.body.entry?.[0];
  const change = entry?.changes?.[0]?.value;
  const message = change?.messages?.[0];

  if (message?.type === "text") {
    const reply = await yourAgent(message.text.body);
    await fetch(
      `https://graph.facebook.com/v21.0/${change.metadata.phone_number_id}/messages`,
      {
        method: "POST",
        headers: {
          Authorization: `Bearer ${TOKEN}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          messaging_product: "whatsapp",
          to: message.from,
          text: { body: reply },
        }),
      }
    );
  }
  res.sendStatus(200);
});

server.listen(3000);

The RouteKit way

Configure WhatsApp as a channel in the RouteKit dashboard. Your agent code is the same whether messages come from WhatsApp or any other channel.

agent.tsTypeScript
import { RouteKit } from "routekit";

const routeKit = new RouteKit();

routeKit.on("message", async (msg) => {
  const reply = await yourAgent(msg.text);
  await msg.reply(reply);
});

What you skip

No whatsapp-web.js or pywa dependency. No WhatsApp-specific auth flow or message parsing. If you later add other channels, your code does not change.

Try it out

RouteKit is currently in beta. Join the waitlist to connect your agent to WhatsApp and every other messaging channel with one integration. Or read more about why RouteKit.