Use casesCRM
Use case 01 · CRM
A clinic group built its own CRM, with appointments booked automatically.
Built by a clinic group · 3 locations · 2 programmes
Enquiries arrive from Google and Meta ads through forms and WhatsApp. Before, they were assigned from a spreadsheet the next morning and many never got a first call. Now a stateful automation offers slots, confirms the booking and hands the lead to a consultant, inside rules the group set once.
The situation
- Leads landed in a form, a WhatsApp number and two ad platforms. Nobody owned the join.
- Assignment happened once a day, by hand. Replies after 6 PM waited until morning.
- A CRM meant a heavy tool nobody updated. The phone number was the real system of record.
What they built, layer by layer
01Data & integrations
The ad platforms’ lead forms, the WhatsApp Business number, the website form and each clinic’s calendar.
02Semantic layer
Lead, enquiry, consultant, clinic, programme and appointment defined once. “Consult booked” means the same thing in every report.
03Context layer
One timeline per person, from the ad click to the appointment. Plus the group’s own rules: how leads are assigned, when the clinics work, how fast a follow-up is due.
04Stateful workflows
One automation, declared once, that handles booking. It knows which leads it has already replied to, which slots it offered, and what is still waiting.
05AI agents & actions
A short list of registered actions: propose slots, create an appointment, notify an owner, schedule a reminder, queue a follow-up. Nothing outside the list can write.
06Governance & traceability
Bookings inside the rules run on their own. Changing a confirmed appointment asks a person. Every booking has a run record with its evidence.
How a booking happens
- EventA lead replies on WhatsApp with a time preference. The automation wakes on the event, not on a schedule.
- StateIt reads the lead’s timeline, the nearest clinic’s open slots, who is on shift and the working-hours rule. All from the context layer, nothing re-derived.
- PlanIt drafts a reply with the next open slots at the nearest clinic. The action is low risk and reversible, so it runs without approval.
- ConfirmOn a confirmation it creates the appointment, notifies the consultant and schedules a reminder.
- No replyAfter a set wait it queues a follow-up for the owner. Nothing is dropped.
- TraceThe run record holds the message, the slots offered, the rule that allowed it and the calendar read-back.
The automation, in outline
{
"automation": "appointment-booking",
"trigger": { "event": "lead.replied", "channel": "whatsapp" },
"condition": { … },
"context": ["lead.timeline", "clinic.capacity", "owner.on_shift", …],
"plan": ["calendar.slot.propose", "appointment.create", "notify.owner", "reminder.schedule"],
"policy": { "risk": "low", "requires_approval": ["appointment.reschedule"] }
}A stateful automation is a typed contract: a trigger, a condition, the context it may read, the registered actions in its plan, and its policy. The model fills fields. Code validates, resolves and binds. A person approves what the policy says needs approval. The full contract carries more than is shown here.
Governance
- Consultants see their own queue. Managers see every queue. Patient details are visible by role, not by default.
- Messages to a lead are drafted from the plan and sent through a registered action, never composed freely by the model.
- A confirmed appointment is a protected entity: changing it stages a plan for a person to approve.
Build the next one on the same six layers.
Connect a system, define a metric, declare an automation. The first run is traceable from the start.