DEV Community

Waqas Ahmed Waseer
Waqas Ahmed Waseer

Posted on

Self-host your own WhatsApp API with WaSphere and Docker

Paying per message for the WhatsApp Business API gets expensive fast, and the approval process is slow. If you want a WhatsApp API you fully own — your server, your data, no per-message fees — self-hosting is the answer.

WaSphere is an open-source (MIT), self-hosted WhatsApp API and developer platform I built for exactly this. It gives you multi-session WhatsApp, a REST API, HMAC-signed webhooks, 14 message types, and a realtime team inbox — all deployed with one docker compose up -d.

In this tutorial I'll take you from zero to sending your first WhatsApp message through your own API in about 10 minutes.

What you get

  • Multi-session — run many WhatsApp numbers from one deployment, each with its own API key scope and webhook endpoint. QR-based pairing in seconds.
  • REST API — send across 14 message types: text, image, video, audio/voice notes, documents, stickers, GIFs, view-once media, buttons, lists, polls, reactions, locations, and contact cards.
  • HMAC-signed webhooks — every delivery is signed (X-WaSphere-Signature: v1,sha256=<hmac> over {timestamp}.{rawBody}), with per-webhook secrets, retries, and SSRF-guarded delivery.
  • Realtime team inbox — a two-pane inbox in the dashboard with roles, a contact book CRM, tags/notes, and CSV import/export.
  • Security-first — scoped API keys (12 permission scopes), Argon2id-hashed keys, AES-256-GCM encrypted secrets, and a full audit log.
  • Anti-ban controls — per-session send delays, typing simulation, and rate limits.

The architecture is two cleanly separated services: a Next.js dashboard with a NestJS API, and a WA Server (NestJS + Baileys) that isolates the WhatsApp engine.

Prerequisites

  • Docker Engine 24+ and Docker Compose v2
  • A server or your local machine (for a public deployment, bring your own reverse proxy for TLS)

Step 1 — Deploy

git clone https://github.com/wasphere/wasphere.git
cd wasphere
cp .env.example .env
# Set the secrets in .env — generate each with: openssl rand -hex 32
docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Open http://localhost:3004, register the first (admin) account, then go to Settings → WA Server and set the URL to http://wa-server:3001 plus your WA_TOKEN.

Step 2 — Connect a number

In the dashboard, create a session and scan the QR code with WhatsApp. The session goes active instantly — no approval process, no waiting.

Step 3 — Send your first message

Create a scoped API key in the dashboard, then:

curl -X POST https://wa.your-domain.com/api/messages/send \
  -H "Authorization: Bearer wsk_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "session": "my-business",
    "to": "15551234567",
    "text": "Hello from my own WhatsApp API!"
  }'
Enter fullscreen mode Exit fullscreen mode

Response: 200 OK with a messageId. That's it — you're sending WhatsApp messages from your own infrastructure.

Step 4 — Receive webhooks

Register a webhook:

curl -X POST https://api.your-domain.com/workspaces/{workspaceId}/webhooks \
  -H "Authorization: Bearer wsk_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "name": "my-app", "url": "https://my-app.com/webhook/wa", "events": ["message.received"] }'
Enter fullscreen mode Exit fullscreen mode

Verify the signature in your receiver (Node.js):

const crypto = require("crypto");

function verify(req, secret) {
  const signature = req.headers["x-wasphere-signature"]; // v1,sha256=<hmac>
  const timestamp = req.headers["x-wasphere-timestamp"];
  const expected = "v1,sha256=" + crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${req.rawBody}`)
    .digest("hex");
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}
Enter fullscreen mode Exit fullscreen mode

This pattern works great for automation — I use it with n8n workflows for order notifications and support routing.

Why self-host instead of the Business API?

  • Cost — no per-message fees; you pay for your server.
  • Control — your sessions and contacts never leave your infrastructure.
  • No approval queues — connect a number and start building.
  • Hackable — it's MIT licensed. Fork it, extend it, ship it.

The full source is on GitHub: github.com/wasphere/wasphere. There's a seeded live demo at demo.wasphere.com, and full docs on wasphere.com.

If you self-host your messaging stack, give the repo a star — and let me know what you build with it.

Top comments (0)