We taught our workflow builder to read English — InboxWa
By Mohit · · 7 min read
Most WhatsApp automation tools make you drag 40 boxes to send one welcome message. Trigger node, message node, delay node, condition node, another message node. Connect them. Configure each one. Rename them so you remember what they do next month. Then call a developer to hook it up to your website.
We shipped something different today. You type what you want in plain English, and the AI builds the workflow. Then you type what to change, and it changes it. No drag-and-drop required — though you can still drag if you want to.
The 🍃 button
There is a leaf icon in the workflow canvas toolbar. Click it, and a chat panel slides out on the right side. This is not a template picker. It is a conversation with an AI that understands every node type the engine supports.
Type: "Build me a lead qualification flow that asks name, email, and budget, then tags hot leads and routes them to sales."
A complete workflow appears on the canvas. Trigger, messages with input capture, a condition node that checks the budget answer, a tag node for hot leads, and a handoff node that routes to a human agent. All connections wired. All configs populated. Ready to publish.
The AI behind this is Gemini 2.5 Flash, called through OpenRouter. It operates in JSON response mode against a ~10k token system prompt that encodes every node type, every config schema, and every constraint the engine enforces. WhatsApp limits interactive messages to 3 buttons with 20-character labels — the AI knows this and auto-truncates. If the generated flow fails validation, it retries with the error context. You get a working flow on the first attempt.
28 node types
The builder isn't limited to simple send-a-message flows. It has access to the full node library:
- Triggers — Keyword, Webhook Event, Schedule, Contact Tag, New Contact
- Messages — Send Text, Send Image/Video/Document, Send Template, Interactive Buttons, Interactive List, Input (capture a reply)
- Logic — Condition (branch on field values), Router (multi-way split), A/B Split
- CRM — Add Tag, Remove Tag, Set Field, Create Deal, Update Contact, Assign Agent
- Integrations — HTTP Request, Webhook Out, Google Sheets, Email Notification
- Time — Delay (minutes/hours/days), Wait for Reply (with timeout branch), Business Hours check
- Utility — Note (internal annotation), Go To (jump to another node), End Flow
The AI can compose any combination of these. Ask for "an abandoned cart flow with a 2-hour delay, a discount offer, and escalation if no reply" and it produces a multi-branch workflow with timeout handling.
Multi-turn refinement
Generation is step one. The real value is iteration. After the AI builds a flow, the conversation stays open. You can:
- Modify — "Add a 2-hour delay before the tag step"
- Explain — "What does this flow do?" and the AI walks through each node
- Extend — "Now add a follow-up message if they don't reply in 24 hours"
- Reconfigure — "Change the tag from 'hot' to 'qualified'"
- Replace — "Swap the buttons for a list message with 5 options"
Each refinement operates on the current flow state. The AI reads the canvas, applies the change, and pushes the updated flow back. No starting over. The conversation history persists for the session, so context builds up naturally.
Secure webhook integration
Workflows that only trigger from keywords are limited. The real power is external events: a customer books an appointment on your website, your backend fires a webhook, and InboxWA sends a WhatsApp confirmation in 2-3 seconds.
The webhook endpoint is POST /api/webhook/inbound/{org}/{event}. Every call passes through seven security layers before it reaches the workflow engine:
- HMAC-SHA256 — The sender signs the request body with a shared secret. We verify with timing-safe comparison. Wrong signature = 401.
- Replay protection — Requests include an
X-Webhook-Timestampheader. Anything older than 5 minutes is rejected. - Idempotency — Every request carries an
X-Webhook-Event-ID. Duplicate IDs within a window are ignored. Safe to retry. - Rate limiting — 60 requests per minute per org. Burst protection without blocking legitimate traffic.
- E.164 validation — Phone numbers in the payload must be valid international format. Malformed numbers are rejected before they hit the flow engine.
- Input sanitization — Org slug and event name are cleaned and validated against registered values.
- Forensic logging — Every call, accepted or rejected, is logged with IP, headers, and outcome. Debug without guessing.
Secrets are generated in the UI, shown once, and never readable again. Rotating a secret invalidates the previous one immediately.
Integration Builder
Webhook security is table stakes. The hard part is getting a non-technical user to send a correctly signed HTTP request from their website. The Integration Builder is a 4-step wizard that eliminates this friction:
- Pick a use case — Appointment Booking, New Signup, Order Placed, Lead Captured, Payment Received, Support Ticket, or Custom. The selection pre-checks relevant fields.
- Select fields — Choose from 40+ fields organized by category: contact (name, phone, email, city, state, country, PIN code), appointment, e-commerce, lead, payment, and support fields.
- Choose your language — cURL, Node.js, Python, PHP, Ruby, Go, or C#.
- Copy the code — A complete, runnable code sample with HMAC-SHA256 signing, timestamp headers, and your actual webhook URL baked in.
Here is what the generated Node.js sample looks like:
const crypto = require("crypto");
const WEBHOOK_SECRET = "your-secret-here";
const WEBHOOK_URL =
"https://inboxwa.online/api/webhook/inbound/acme/appointment_booked";
async function sendWebhook(data) {
const timestamp = Math.floor(Date.now() / 1000).toString();
const body = JSON.stringify(data);
const signature = crypto
.createHmac("sha256", WEBHOOK_SECRET)
.update(timestamp + "." + body)
.digest("hex");
const res = await fetch(WEBHOOK_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Webhook-Signature": signature,
"X-Webhook-Timestamp": timestamp,
"X-Webhook-Event-ID": crypto.randomUUID(),
},
body,
});
return res.json();
}
sendWebhook({
phone: "+919876543210",
name: "Priya Sharma",
appointment_date: "2026-05-12",
appointment_time: "10:30",
service: "Yoga — Morning Batch",
});
The user copies this, drops it into their backend, and the integration is done. No SDK to install. No OAuth dance. One function call.
The technical stack
A quick look at what runs behind this:
- AI — Gemini 2.5 Flash via OpenRouter. JSON response mode. ~10k token system prompt with full node schema, validation rules, and industry patterns.
- Builder canvas — Vanilla HTML5 canvas, ~7,700 lines. Exposes a global JS API (
addNode,importFlow,exportFlow) that the AI panel calls to push flows onto the canvas. - Engine — Node.js Express + PostgreSQL. 28 node handlers, a flow validator, an event router that matches incoming webhooks to published workflows, and a scheduler for delayed nodes.
- Frontend — React + TypeScript + Tailwind + Radix UI. OKLCH-based design tokens. The canvas is embedded via iframe with a message-passing bridge.
- Security — HMAC-SHA256 everywhere, parameterized SQL throughout, rate limiting per org, replay protection on all webhook endpoints.
What's next
Three things on the short list:
- React canvas conversion — The visual builder is currently a standalone HTML canvas embedded via iframe. We are converting it to a native React component with direct state binding. No more message-passing bridge.
- AI node configuration — Click any node on the canvas and the AI suggests the best config based on the flow context. Instead of filling out a form, you describe what the node should do.
- Webhook analytics — Success rates, latency percentiles, error drill-down by event type. Currently we log everything but the dashboard to surface it is not built yet.
We built this in one sprint because the canvas already had an API surface and the engine already had typed node schemas. The AI layer is thin — it translates intent to structure. The hard work was the 28 node handlers and the webhook security stack. The AI just made them accessible to people who don't want to drag boxes.