What context-aware means
Your application attaches structured data to an outbound alert — an order reference, an ETA, a carrier, whatever the conversation is actually about. ChatRail keeps it with the message. When the recipient replies, the reply is linked back to that alert and the stored data is what the model answers from. The alternative most tools offer is a chatbot that knows your FAQ and nothing about this customer’s order.
Replies are linked by rule, not by guesswork
A reply is matched to the alert it answers through an ordered chain of explicit rules: WhatsApp’s own reply-to when the customer used it, exactly one alert awaiting an answer, an optional model choice when several alerts are open (described below), or the most recent candidate with confidence decaying by age. Every link records which rule fired and how confident it is.
When no rule applies, ChatRail reports no link rather than attaching the reply to whatever was nearby. A wrong match feeds the wrong data to a model and shows you a relationship that is not real, which is worse than an honest gap.
Choosing between several open alerts
When a customer replies without quoting and more than one alert is waiting, the newest alert is not always the one they mean. “When will it arrive?” is about the order, not the viewing booked five minutes later. An optional step puts the reply and the open alerts to a decision model, TypeSafe’s Jev, as one typed choice: one of the alerts, or none. It returns a pick and a probability, never text.
- Off by default. It is switched on with the
CORRELATION_MODEL_ENABLEDsetting and needs ChatRail’s managed AI key. - Only where AI is already on. It runs only for connections with an enabled AI policy on the managed key. A workspace without AI, or using its own key, never has its messages sent to this model.
- What it sees. The text of the open alerts (up to five, from the last 24 hours) and the customer’s message, which is passed as data, not as an instruction. Context attached to a message is never sent to it, whatever its sensitivity.
- Falls back to the rule. A pick below 80% probability, a failed call or a timeout of two seconds is ignored, and the link is made by the most-recent rule and reported as a guess. A model outage never stops a message being received.
- Visible in the result. A link made this way reports
method: model_choiceand the model’s probability asconfidence. If the model judges the reply is about none of the alerts, the method isnoneand there is no link.
Draft first, automatic only if you choose
Draft mode is the default: a reply is proposed and waits for a human. Auto mode sends without review and is opted into per connection. ChatRail records what you then did with each proposal — sent as written, edited before sending, or declined — so whether the feature is earning its place is a number you can read rather than a feeling.
Each proposal fires an ai.reply_generated webhook carrying the draft, so a review queue can live in your own tooling rather than requiring somebody to watch a dashboard. When a rule you set stops a run instead — restricted context, or a spent monthly ceiling — ai.reply_blocked says which.
AI is optional
Messaging, delivery tracking and webhooks require no AI at all. Enable it per connection, only where automated follow-up answers are useful, and leave it off everywhere else.
Model choice
Use a supported model or point ChatRail at any OpenAI-compatible endpoint. Credentials are encrypted at rest, scoped to one workspace and never returned through the API. Each policy carries its own output-token ceiling and monthly cost limit.
What reaches the model
The context you attached and the message being answered. Recent conversation history is sent only if you switch it on for that connection; it is off by default. Context you marked restricted is never sent to a model at all — the run is blocked rather than quietly proceeding without it.
Context is bounded before it is sent, so an unexpectedly large object cannot inflate a prompt. Nested objects are flattened to dotted keys (property.address), up to four levels; arrays are left out and listed in omitted_keys. To keep a field from the model, mark the context restricted rather than nesting it. In a long thread, each AI reply carries its listing forward, so a follow-up that quotes nothing — or arrives days later — is still answered about the same property. When someone on your team answers a lead by hand, automatic replies pause in that conversation for human_takeover_minutes (a day by default; send with pause_ai to decide explicitly). And a lead who types in bursts gets one reply to the whole burst: runs wait reply_delay_seconds (5 by default) for the rest of it. In a WhatsApp group, the AI answers only a message that @-mentions your number or quotes one of your messages (group_replies: "addressed", the default); set "all" or "off" to change that. To correct something the AI answers from — a new gate, a new time — send context with the edit (PATCH /v1/messages/{id}); editing the text alone leaves the context as it was. Every run stores a hash of the prompt and the list of context keys that went into it, which is what makes an answer auditable after the fact.
Privacy control
Messages and context have separate retention windows, and context can never outlive the message it belongs to. Sensitivity is set per send: normal, sensitive or restricted. Attach what the conversation needs and nothing more — payment details, internal risk scores and unrelated history do not belong in an alert context.