AI replies for business messaging
Answers your customers from your own data.
Connect the platforms your customers already message you on, load your product catalogue and knowledge base, and the engine answers from that data alone. It sends when it is confident, and hands the conversation to a person when it is not.
WhatsApp and Telegram today. Every reply grounded, scored and checked before it sends.
The problem
The answers already exist. The person who has them does not.
The questions that arrive are overwhelmingly the same handful, and the answers are in the catalogue, the returns policy, or the owner's head. The problem is never knowledge. It is availability.
The owner is serving a customer, driving, or asleep
Messages sit unanswered for hours.
A question arrives at 11pm on a Saturday
Answered Monday, if at all.
Three platforms, three inboxes, no shared history
The same customer is re-asked what they already said.
Volume spikes during a sale
Exactly when a slow reply costs the most.
Response time is the conversion.
A customer who waits six hours has usually bought elsewhere, and the business rarely finds out it lost the sale.
Why the obvious fixes do not work
Rule-based chatbots answer only what someone anticipated. Real questions are phrased in ways no keyword tree predicts, and every gap in the tree is a dead end.
A general-purpose LLM in an inbox answers fluently and invents facts — a price that changed last month, a delivery promise the business does not offer. One hallucinated commitment costs more than a week of slow replies.
Set up once
Three steps, then it runs on its own.
Connect the account, load what the business already knows, and set the boundaries it must answer inside. There is nothing to train and no rules to write.
- 01
Connect an account
Link a WhatsApp number or a Telegram bot. The response gives you a webhook URL to register with the provider.
Credentials are encrypted at rest and nothing is retrievable.
- 02
Load what the business knows
Push products through the API — name, price, stock, attributes — and write free-form knowledge documents for the returns policy, shipping and FAQs.
Both are chunked and embedded automatically.
- 03
Set the boundaries
An agent profile holds the persona and tone, the confidence threshold, and the guardrails: may it quote prices, may it make commitments, which topics always go to a person.
New tenants start conservative — drafts held for review, no stock claims, no commitments.
Then a message arrives, and it is already handled.
The engine answers from the data you loaded, scores its own confidence, checks the reply against your guardrails in code, and hands the conversation to a person the moment it should not answer at all.
How it works
Eight steps between a customer's message and a reply.
The same path runs for every message on every platform. Three of the eight steps exist only to decide whether to answer at all.
- 01
Receive
Verify the provider's signature, store the raw event, and acknowledge in under 50ms.
A redelivery of the same event is a no-op.
- 02
Understand who
Resolve the sender to a contact, find or open their conversation, and normalise the message into a platform-neutral shape.
A first-time sender becomes a contact here.
- 03
Should we reply?
Automation off, conversation closed, or a human already stepped in — stop here, with the reason recorded.
- 04
Find the facts
Hybrid search over this tenant's catalogue and knowledge base: embeddings for meaning, trigrams for SKUs and order numbers.
- 05
Draft
The model gets the persona, the guardrails, the retrieved facts and the recent conversation, and returns a reply, a confidence score, an intent and citations.
- 06
Check
Deterministic guardrails run in code: banned phrases, forbidden price quotes, forbidden commitments, disclaimers, length.
A confident answer citing nothing is treated as a hallucination and blocked.
- 07
Decide
Five outcomes, evaluated in order of veto strength.
- Model asked for a humanescalate
- Complaint or refundescalate
- Below the confidence barescalate
- Channel set to review modehold as a draft
- Otherwisesend
- 08
Deliver
Respect the provider's rate limit and reply window, send, and record every attempt with its latency and result.
Steps 02 to 08 run on durable queues. Providers disable webhook subscriptions that respond slowly, so the HTTP tier does nothing but verify, store and acknowledge. Everything expensive happens behind the queue, where it can be retried, rate limited and observed.
Worked example
The same customer, two questions, two different answers.
One of these is answered in seconds. The other is never automated, whatever the model thinks of itself.
do the trailhead boots come in a UK 11?
Yes — the Trailhead Mid GTX goes up to a UK 13, so an 11 is in the range.
0.91 clears the 0.75 bar the business set, the intent is not high-risk, and the channel is in auto mode. Jamie has an answer before midnight.
What the engine recorded
- matched
- Trailhead Mid GTX
- grounded in
- 1 citation
- intent
- AVAILABILITY
- confidence
- 0.91
- threshold
- 0.75
- price quoted
- no
- commitment made
- no
- decision
- sent
can I get a refund on boots I've already worn?
Let me get a colleague to confirm that for you.
Complaints and refunds route to a person regardless of how confident the model is. A human sees it first thing Monday, with the full context already in the thread.
What the engine recorded
- intent
- REFUND
- rule
- refunds never auto-send
- confidence
- not the deciding factor
- threshold
- not consulted
- commitment made
- no
- decision
- escalated to a human
Control
It will not say something you did not authorise.
The interesting question is not whether AI can answer a customer. It is what happens when it should not. Seven answers, all of them enforced rather than requested.
01
You set the confidence bar
The model returns a score, not a vibe. Auto-send is gated on a threshold the business chooses; below it, a person takes the message.
02
Four modes, per channel
Off, draft-for-approval, auto-above-threshold, full auto. Start by reviewing every draft and loosen the reins as trust is earned.
03
Guardrails run in code, after generation
Banned topics, forbidden price quotes, forbidden commitments and required disclaimers are enforced deterministically. “The model was told not to” is not a control.
04
Complaints and refunds always escalate
Whatever the confidence score says. A confidently wrong refund promise costs more than a short wait.
05
A human is never talked over
The moment an agent replies, automation stands down for that conversation.
06
One customer, one history
Someone who wrote on WhatsApp last week and Telegram today is one contact, with one thread of context.
07
Every decision is explainable
“Why didn’t it reply?” and “why did it say that?” both have stored answers, including the knowledge chunks the reply was grounded in.
Channels
Two platforms today, and the seam to add the next one.
Adding a messaging platform is one class and one line of wiring — no schema migration, no pipeline change. New channels land fast because nothing else has to move.
WhatsApp Cloud API
Batched deliveries, signed payloads, a 24-hour reply window the engine tracks per conversation.
Telegram
LiveTelegram Bot API
A different identifier scheme, a different signature scheme, no reply window. One pipeline serves both.
No connector yet
Described in the architecture and modelled in the data, but not implemented. It is not a live integration.
WhatsApp and Telegram ship as reference implementations because they disagree about nearly everything at the wire level — batching, identifier types, signature schemes, reply windows. That is what makes them a real test of the abstraction rather than a flattering one.
For developers
A documented REST API, and one file per messaging platform.
NestJS on Node, PostgreSQL with pgvector, BullMQ on Redis, Claude Opus 5 through the Anthropic SDK. Dependencies point inwards, and ESLint fails the build when they do not.
A REST API that cannot drift from its docs
Interactive OpenAPI 3.1 docs at /docs, the raw contract at /docs-json and /docs-yaml. The schemas are generated from the Zod validators that serve the requests, not written alongside them, so a documented endpoint cannot disagree with the code.
A Postman collection that runs top to bottom
Every operation, in the order you would actually do them: create an operator, provision a tenant, connect a channel, load a product, preview retrieval, fake an inbound message, approve the draft. Each request captures what the next one needs.
Two credential types, one verification path
Session tokens for a person signed in, API keys for a machine. Both are opaque handles the server resolves on every request, which is what makes them revocable now rather than at expiry.
Two deployment shapes, one image
APP_ROLE selects the runtime: api for the HTTP tier, worker for the queue consumers, or all for local development. Scaling them together would mean over-provisioning one to serve the other.
Adding a messaging platform is one file
One class implementing ChannelConnectorPort, one line in connectors.module.ts. No schema migration, no pipeline change, no new routes, no change to any other connector.
# A business signs itself up.
# The only unauthenticated write in the API.
curl -X POST localhost:3000/organizations \
-H 'content-type: application/json' \
-d '{"name":"Copper Kettle Cafe",
"owner":{"email":"manager@copperkettle.test"}}'
# -> the organization, a default agent profile, the owner
# login and the first API key, in one transaction.
# The password and the key are shown once.
# See exactly what the AI would read for a question -
# the answer to "why did it say that?" before it has
# said anything.
curl -X POST localhost:3000/knowledge/preview \
-H "Authorization: Bearer $API_KEY" \
-H 'content-type: application/json' \
-d '{"query":"waterproof boots"}'Both requests are from the engage-ai README
Security and isolation
Other people's customer conversations.
That is what the system holds, so the defaults are the conservative ones.
- Credentials encrypted at rest
- AES-256-GCM envelope encryption with a key id per row, so rotation is a background job rather than a maintenance window.
- Nothing is retrievable
- Passwords are scrypt hashes; keys and session tokens are peppered HMACs. No code path reverses any of it. Support reissues, never retrieves.
- Per-tenant isolation
- Every business table carries an organization id, and the tenant is resolved from the credential, never from a request parameter.
- Webhooks verified per connection
- Each connection's own signing secret is checked before anything is stored or enqueued.
- Sessions are revocable
- Opaque server-side handles, not JWTs. Disabling an account or changing a password ends every session on the next request.
- The audit trail names a person
- Accounts are disabled, never deleted, so “who reset this customer's password?” keeps resolving to a name.