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
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!"
}'
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"] }'
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));
}
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)