Guides/For developers

I already have my own AI, I just need the WhatsApp side

WACO becomes the official WhatsApp interface, the brain stays yours: messages in by webhook, replies out by API. 3 min read

People arrive with the same sentence: the AI assistant already works, I just need WhatsApp. That is one of the most straightforward ways to use WACO. Our built-in AI Operator does not need to be switched on, and there is no AI cost from us. You use the official number, the webhook, and the API.

Three pieces

  1. Incoming message is posted by WACO to your URL as message.received.
  2. Your AI thinks on your own infrastructure.
  3. The reply goes out through POST /api/v1/balas.

Set up once

A complete example, Node and Express

const express = require('express');
const crypto = require('crypto');
const app = express();

// The signature is computed over the RAW body, so do not use express.json() on this route.
app.post('/waco', express.raw({ type: '*/*' }), async (req, res) => {
  const expected = 'sha256=' + crypto.createHmac('sha256', process.env.WACO_WEBHOOK_SECRET)
    .update(req.body).digest('hex');
  const got = String(req.get('X-WACO-Signature') || '');
  if (got.length !== expected.length ||
      !crypto.timingSafeEqual(Buffer.from(got), Buffer.from(expected))) {
    return res.sendStatus(401);
  }

  // 1) Answer 200 FIRST. A slow AI must not hold the webhook.
  res.sendStatus(200);

  const ev = JSON.parse(req.body.toString('utf8'));
  if (ev.event !== 'message.received') return;      // ignore status and echo
  if (alreadySeen(ev.pesan.id)) return;             // deliveries can repeat

  // 2) Queue per number so one customer is handled in order
  queue(ev.dari, async () => {
    const answer = await yourAI(ev.dari, ev.pesan.teks);   // your own brain

    // 3) Send the reply back through WACO
    await fetch('https://waco.id/api/v1/balas', {
      method: 'POST',
      headers: {
        Authorization: 'Bearer ' + process.env.WACO_API_KEY,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ nomor: ev.dari, teks: answer }),
    });
  });
});

app.listen(3000);

Four things that surprise people

The team inbox can stay on. The same event goes to both places: your AI receives it by webhook, your team still sees the conversation and can take over at any time. Trouble on one side does not hold up the other.

If your AI is an agent

WACO also serves MCP at /mcp, so your agent can call WACO as a tool (prepare a confirmed blast, read history, send messages) without writing an HTTP integration.

Details in the API guide and the webhook guide. OpenClaw users have their own page.

Still stuck after following this guide? Contact us from the dashboard — attach a screenshot if you have one, it speeds everything up.