📦rmyndharis / OpenWA
← 返回首页
Free, Open Source, Self-Hosted WhatsApp API Gateway
⚖️ MIT#api#gateway#whatsapp#self-hosted#whatsapp-api🌐 www.open-wa.org📅 创建于 2026-02-02🔄 更新于 2026-10-29
🔗 GitHub TypeScript

📄 仓库 README

在 GitHub 查看 ↗
来自 GitHub 仓库自述文件 · 版权归原作者所有

OpenWA Logo

OpenWA

Open Source WhatsApp API Gateway

Features • Quick Start • Docs • API • Contributing

CI Version License Node NestJS Docker TypeScript Buy Me a Coffee


✨ Why OpenWA?

OpenWA is a free, open-source WhatsApp API Gateway designed for developers who need full control over their messaging infrastructure—without vendor lock-in or hidden paywalls.

Built on a pluggable architecture, OpenWA lets you select database engines (SQLite/PostgreSQL), media storage backends (Local/S3), and an optional Redis (queue, rate limits, WebSocket fan-out) through configuration rather than application-code changes. The storage backend is the live store for status media and, when chat-media archiving is enabled, archived chat media; other message media is returned inline to API and webhook consumers. Of the media, scripts/backup.sh archives only the local media directory, so an S3 bucket needs a backup of its own.

🔓 100% Open Source No licensing fees, no feature locks, full source code access
🏗️ Pluggable Architecture Swap adapters for database and storage via config
🖥️ Full Dashboard Modern React UI for session, webhook, and API key management
🔹 Multi-Session Ready Run multiple WhatsApp sessions concurrently on one instance
🐳 Docker Native Production-ready with zero configuration
🧩 Official Plugins Chatwoot, Typebot & more as sandboxed plugins on the Integration Fabric — OpenWA-plugins
🔗 n8n Integration Community nodes for workflow automation
🧩 Community Adapters Third-party integrations (e.g. ioBroker) — see docs
🔐 Session-scoped keys Operator and viewer (reader) tokens can be limited to chosen sessions — or all sessions if none are selected
🔒 Chat-scoped keys Those same tokens can also be limited to chosen chats — a few groups and contacts — so an agent on a shared account sees only its own

Session-scoped operator & viewer tokens

When you create or edit an operator or viewer API key in the dashboard, you can tick the WhatsApp sessions that key may use.

  • No sessions selected — the key can access every session, including ones created later.
  • One or more sessions selected — the key can only list, read, and (for operator) manage those sessions. A request naming any other session returns 403 ("API key not authorized for this session"); session-filtered lists (sessions, audit, webhook delivery failures) return that key's rows rather than an error; and the key-management routes and the queue dashboard, which name no session at all, return 403.

Admin keys stay unscoped in the dashboard so they can keep managing other API keys. The HTTP API still accepts allowedSessions on any role if you need that from a client.

Chat-scoped operator & viewer tokens

A session-scoped key still reaches every chat on the sessions it may use. A key can be narrowed further, to chats (a chosen set of groups and individual contacts), with allowedChats on POST /auth/api-keys or PUT /auth/api-keys/{id}. The dashboard sets it on operator and viewer keys (one chat id or phone number per line) and shows each key's chat count in the list.

  • No chats selected — the key can reach every chat on its sessions.
  • One or more selected — the key reaches only those chats. Every authenticated REST route not explicitly marked as safe for a chat-scoped key refuses it with 403 (a request naming a session outside allowedSessions is refused first, with 403 "API key not authorized for this session"), including routes added in later releases: the refusal is the default. Inside its chats an operator key can do what the marked routes allow, which is more than reading and sending: it can also delete or clear a chat, leave or rename a group, and block the contact. It cannot change who belongs to a group: adding, removing, promoting or demoting participants, answering join requests and reading or resetting the invite link all stay closed.
  • The two scopes are independent — a key may be limited to sessions, to chats, to both, or to neither.

This lets you point an AI agent or third-party integration at a shared account without handing it every chat. Give the agent a key scoped to the few groups (or DMs) it is meant to handle: it can send and reply there, but it cannot list your other chats, read any other DM, message a contact outside its set, or reach the queue dashboard. It reads its chats' stored messages on either engine through GET /sessions/{sessionId}/messages?chatId=, where chatId is required for such a key, and live history through GET /sessions/{sessionId}/messages/{chatId}/history on whatsapp-web.js only. It can subscribe to the /events WebSocket, which delivers only events for its chats. It can still read the session's own status (GET /sessions/{sessionId}) so an integration can tell whether it is connected.

Identity is matched through the lid mapping table: a contact allowlisted by phone number also matches the same person's @lid privacy id once the table maps the two, and an unmapped @lid is refused rather than guessed. A lid's digits are never mistaken for a phone number, so 555000111@lid does not admit 555000111@c.us.

The default covers REST routes only. Surfaces that authenticate outside the REST guard do not inherit it, so each one that can return chat data applies the fence with its own check: the /events WebSocket delivers only events inside the key's chats, the MCP mount authorizes each tool call against them, and the Bull Board queue dashboard refuses the key. Five list routes are usable, each filtered to the key's chats before paging: GET /sessions/{sessionId}/chats, GET /sessions/{sessionId}/groups (id, name and community parent id only), GET /sessions/{sessionId}/contacts, GET /sessions/{sessionId}/labels/{labelId}/chats and GET /api/search (the built-in provider; a search plugin answers 403).

The API also accepts allowedChats on an admin key, but no admin-only route is open to a chat-scoped key, and the last usable admin key cannot be scoped this way.

None of this changes the ban-risk guidance below. It limits what a key can reach, not what WhatsApp makes of the account.


⚠️ Before you connect a number — please read

OpenWA is an unofficial, community-maintained gateway. It connects to WhatsApp through reverse-engineered clients (the whatsapp-web.js project and @whiskeysockets/baileys), not through Meta's official Cloud API. This has real consequences you should understand before you link a phone number.

What this means in practice

  • There is always a non-zero risk of account restriction or ban. WhatsApp's anti-abuse systems actively look for unofficial automation. No amount of code quality on our side can make that risk zero.
  • Pick the right number. Never connect your primary personal or business number to an automated gateway. Use a dedicated number you can afford to lose. If you're running this for paying clients, pass that guidance on to them.
  • The two engines trade off differently:
Engine Ban-risk profile Resource cost
whatsapp-web.js Lower — drives a real headless Chromium that looks like genuine WhatsApp Web traffic. High RAM (~300–500 MB / session).
baileys Higher — speaks the multi-device WebSocket protocol directly and is easier for WhatsApp to fingerprint. Low RAM (~30–80 MB / session).

If account safety is your top priority and you can afford the memory, prefer whatsapp-web.js. If you need density and accept the trade-off, use baileys.

Safe-sending guidelines

These are practical guardrails, not guarantees — but they materially reduce the chance of WhatsApp flagging the account:

  1. Warm up fresh numbers. For the first several days, behave like a normal human user: scan the QR, exchange a handful of messages with saved contacts, join a group or two, set a profile photo. Don't blast on

📈 近 7 天 Star 趋势

每日新增 Star(柱)与累计 Star(线)· 数据来自 GitHub

🏆 排名变化趋势

在各榜单中的排名历史(数字越小越靠前)

📋 历史上榜记录

每次快照的详细数据
日期 榜单 排名 周期新增 总 STAR