What I Learned Designing Omnichannel Backend Integrations
Shared intent schema, eventually-consistent conversation state, and why the channel should be the last thing your backend knows about.
Part of Backend Craft
Omnichannel is a word that gets thrown around by people selling dashboards. What it actually means is: a customer starts on WhatsApp, continues on voice, finishes on web, and expects your system to keep up.
The backend should not know what channel it is
The single biggest win from any omnichannel project I've built is this rule:
Fulfillment code must not branch on channel. If it does, you're building N products.
Your bot logic, your LLM prompts, your CRM updates — none of that should care whether the input came from SMS, voice, web, or carrier pigeon. The channel adapter normalizes to a common envelope and hands it off. Everything downstream operates on intents and entities, not on "voice says this, WhatsApp says that."
Conversation state is eventually consistent
Callers don't wait for your replication lag. If the caller escalates from bot to agent across a channel switch, the agent needs state that might be 500ms behind the edge.
Two options that work:
- Single-writer conversation log keyed by customer + session. Every channel writes append-only events. Readers project.
- Idempotent "last-known" snapshot that any channel can overwrite, with a version stamp. Simpler, less safe.
I default to the log. Append-only is boring and correct.
Intent schema is the contract
If your voice team and your chat team define intents differently, you will merge them later under deadline pressure. Define a shared intent ontology on day one. Version it. Treat changes like API changes.
What I'd tell past me
- Build the channel adapter last. Get fulfillment right first.
- Measure channel-switch success as a first-class KPI. It's the only one that proves omnichannel works.
- Budget for observability that spans channels. A trace that dies when voice hands off to web is not a trace.
Related
Keep reading
Daily Note: TIL — Polly SSML <mark> tags
Polly's SSML <mark> tags emit timing events over the stream. Useful for synchronizing on-screen captions to voice playback.
Daily Note: Debugging a Production API Flow
Integration test green, staging green, prod failing for 1% of callers. The bug was in a place I would never have guessed.
Building Voice Integrations on Top of Async Chatbots
What breaks when you front an async chatbot with Amazon Connect + Lex, and how to keep latency, barge-in, and context handoff sane.
Keep going
Where to next?
Browse more technical writing, see the engineering case studies, or reach out directly.