OpenWA gateway
How the platform reaches WhatsApp through a self-hosted OpenWA gateway, and how it differs from the Cloud API.
The platform sends and receives WhatsApp messages through OpenWA, a self-hosted gateway pinned to v0.29.0 (ghcr.io/rmyndharis/openwa:0.29.0). OpenWA drives a real WhatsApp Web client, so each workspace links an ordinary WhatsApp or WhatsApp Business app account instead of registering a number with Meta.
Unofficial integration
OpenWA is not affiliated with Meta. Automating a WhatsApp account can violate WhatsApp's terms and get the number restricted or banned. Use a dedicated number, keep volume low, and message only customers who opted in. See Ban-risk practices.
Shape of the integration
- One gateway, many tenants. A single container (
docker compose up -d openwa) hosts every workspace. Each workspace is one OpenWA session, which is one linked WhatsApp account. - REST under
/api. The engine calls the gateway with anX-API-Keyheader. The key is generated on first boot:docker compose exec openwa cat /app/data/.api-key. - Webhooks back to the engine. The engine registers a signed webhook per session that delivers to
/webhooks/openwa. See Webhooks and events. - Engine type
whatsapp-web.js. Headless Chromium, chosen as the lowest-ban-risk engine OpenWA offers. It costs roughly 300 to 500 MB of RAM per linked account. The Baileys engine uses 30 to 80 MB but is easier to fingerprint.
Endpoints the engine uses
All paths are relative to <OPENWA_URL>/api. Nothing outside this list is used.
| Area | Calls |
|---|---|
| Sessions | POST /sessions, GET /sessions/{id}, POST /sessions/{id}/start, /stop, /logout, DELETE /sessions/{id}, GET /sessions/{id}/qr, POST /sessions/{id}/pairing-code |
| Webhooks | GET, POST and DELETE on /sessions/{id}/webhooks |
| Messages | POST /sessions/{id}/messages/send-text, send-audio, send-image, send-video, send-document, react |
| Media | Download of stored media for a message |
| Chat state | Typing and recording indicators, mark as read |
| Groups | List, info, create, invite link, add and remove participants, leave |
Errors come back as { statusCode, message, error }. The engine treats 409 (session not ready), 429 and 503 as retryable because nothing was sent. Other 5xx responses are ambiguous and mark the outbox row unknown. 401 and 403 mean the API key is wrong.
Identifiers
WhatsApp ids are neutral strings: users are <digits>@c.us or, for privacy-protected accounts, <id>@lid. Groups are <id>@g.us. The phone number is only present when the id is an @c.us id.
Differences from the Cloud API
| Topic | Cloud API | OpenWA |
|---|---|---|
| Account | Meta business portfolio, WABA, registered number | Any WhatsApp or WhatsApp Business app account, linked as a device |
| Onboarding | Embedded Signup | Scan a QR code or enter a pairing code |
| 24-hour window and templates | Required outside the window | None. Free-form text any time, but the platform only replies |
| Interactive buttons | Reply buttons and lists | Not available. Quick replies are a short "• option" text list, omitted in groups |
| User ids | Business-scoped user ids (BSUID) | <digits>@c.us or <id>@lid |
| Pricing | Per-message pricing categories | None from WhatsApp. You pay for hosting |
| Groups | Official Business Account, 8 members, invite link | Normal WhatsApp groups, no such limits |
| Calls | Calling API | Not supported |
| Support and terms | Official and supported | Unofficial, ban risk |