WABridges
← All guides
Guide

One webhook.
Many tenants. Never crossed.

A single endpoint can serve every bridge in your fleet. The trick is customer_ref: every inbound message arrives tagged with the tenant it belongs to, so you route to the right bot — and guarantee one tenant can never read or reply on another's number.

In a multi-tenant system, the scariest bug isn't downtime — it's a message from one customer's bridge landing in another customer's inbox. Tenant isolation is the property you can't afford to get wrong, and in a shared WhatsApp webhook it comes down to one discipline: trust the customer_ref, and key everything off it.

WA Bridges tags every inbound event with the customer_ref you set when you provisioned the bridge. That single field is your routing key. One endpoint receives the whole fleet's traffic; you look up the tenant by customer_ref, run only that tenant's logic, and send replies only on that tenant's bridge. Get the lookup and the scoping right and the streams physically cannot cross — even though every message flows through the same handler.

How it works

1
Point every bridge at one webhook
When you provision each bridge, set the same webhook_url for all of them. One endpoint serves the entire fleet — there's no per-tenant routing infrastructure to stand up.
2
Read customer_ref as the routing key
Every inbound payload includes the customer_ref you assigned at provisioning time. That's the tenant the message belongs to. Treat it as the first thing you read and the only thing you route on.
3
Scope every query and reply to that tenant
Look up the tenant by customer_ref, then load context, run bot logic, and write data scoped to that tenant id. When you reply, send on that tenant's bridge only — never a bridge id from anywhere but the resolved tenant.
4
Reject anything you can't resolve
If a customer_ref doesn't map to a known active tenant, drop the message and log it — don't fall back to a default. An unrecognized ref is a signal something's wrong, not an edge case to paper over.

What you can build

🚦
The routing key
  • customer_ref on every inbound event
  • Set once at provisioning time
  • First field you read, only field you route on
  • Maps 1:1 to a tenant id
🧱
Strict isolation
  • Scope every query by tenant id
  • Reply only on the resolved bridge
  • No shared mutable state across tenants
  • Never a default fallback tenant
🔍
Fail loud
  • Unknown customer_ref → drop + log
  • Alert on refs with no tenant
  • Reject inactive or suspended tenants
  • Treat surprises as bugs, not noise
🧪
Prove it
  • Test cross-tenant leakage explicitly
  • Assert replies go to the right bridge
  • Fuzz with unknown refs
  • One handler, many bridges, zero crossover

Paste into Claude, ChatGPT, or any AI assistant

Copy this prompt → paste into any AI assistant → get working code in your language.
I run many WhatsApp bridges on WA Bridges, all pointed at one shared
webhook. Every inbound event carries a customer_ref that identifies which
tenant the message belongs to. I need bulletproof tenant isolation.

My stack: [Node.js / Express + Postgres — update this to yours]
My setup:
- WA_API_KEY: my WA Bridges API key
- A "tenants" table keyed by the same id I use as customer_ref
- Each tenant row stores its own bridge id

I need a single POST /webhook handler that:

1. Reads customer_ref from the payload and looks up the tenant. If there's
   no active tenant for that ref, drop the message, log a warning, and
   return 200 — never fall back to a default tenant.

2. Runs runBot(tenant, message) scoped entirely to that tenant — every DB
   query filtered by the tenant id, no shared mutable state between
   requests.

3. Sends any reply ONLY on that tenant's bridge id (the one from the
   resolved tenant row), never a bridge id taken from the request.

Please read the WA Bridges API docs before writing any code:
https://wabridges.com/docs.txt

Make isolation the central concern. Add comments where a careless change
could cross tenants, and include a couple of unit tests that prove a
message tagged for tenant A can never trigger a send on tenant B's bridge.

Why WA Bridges