Build your product on top of WA Bridges. Provision one bridge per customer with a single API call, point each number at its own bot logic, and charge whatever you want on top. You own the customer — we run the WhatsApp layer.
Every SaaS eventually gets the same request: "Can my customers talk to this over WhatsApp?" Building that yourself means the WhatsApp Business API, template approvals, per-message fees, and a multi-tenant connection layer you have to operate forever.
WA Bridges is that layer, rented by the bridge. Provision one bridge per customer with a single API call, let each of them pair their own number, and route every inbound message — tagged with the customer it belongs to — into your own bot. You resell it under your brand at whatever price you like. We bill you a flat $3/month per active bridge; the markup is yours.
I'm building a multi-tenant SaaS where each of my customers gets their own WhatsApp bot, powered by WA Bridges. WA Bridges gives me a REST API to provision one bridge (one WhatsApp number) per customer. My stack: [Node.js / Express + Postgres — update this to yours] My setup: - WA_API_KEY: my WA Bridges API key (one key for my whole account) - Each of my customers has an id in my "tenants" table I need three pieces: 1. provisionBridge(tenantId): calls POST /api/instances with customer_ref set to my tenant id and webhook_url pointing at my backend. Store the returned bridge id on the tenant record. 2. A POST /webhook endpoint that receives inbound WhatsApp messages. The payload includes the customer_ref so I know which tenant the message belongs to. Look up that tenant, run their bot logic (for now, a placeholder runBot(tenant, message) function), and reply via the send API on that tenant's bridge. 3. deprovisionBridge(tenantId): deletes the bridge when a tenant cancels, so I stop being billed for it. Please read the WA Bridges API docs before writing any code: https://wabridges.com/docs.txt Keep tenant isolation strict — one tenant must never receive or send on another tenant's bridge. Show runBot() as a clearly separated stub I can later swap for an LLM call.