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.
Written by
Adrian Romo
Senior Backend Engineer building scalable Python APIs, AWS Lambda architectures, voice systems, and enterprise integrations.
Related
Keep reading
Assembled Primitives vs. a Platform
I built a voice agent out of cloud primitives, and it worked. It has since been replaced by a purpose-built voice platform, and I think that was the right call.
Six Posts a Day, and the Scheduler That Learned to Say When
A social pipeline that published one Reel a day and nothing else, because per-format quotas were ceilings and nothing was asking for the other formats.
A Planner That Will Not Onboard Anything
The tool that decides how to onboard a new service into my homelab has no ability to onboard a service. That separation is the design, not a limitation.
Keep going
Where to next?
Browse more technical writing, see the engineering case studies, or reach out directly.