AI Receptionist.
Answers every call. Books the real diary.
- Technical Operations Manager · AI Systems Engineer
- Aug 2026 — Present
- Salons & Beauty · Residential Heating & Energy Supply
- Live · 12–15 clients · Ireland & UK
CallHandlers.io gives small businesses an AI receptionist that answers the phone, checks the real diary and books, moves or cancels appointments. I own production: the ElevenLabs agents, the n8n orchestration layer on Railway, the multi-tenant Supabase Postgres, five booking-system integrations, and the DM agent that brings the same receptionist to Facebook Messenger, WhatsApp and Instagram.
Claims are cheap. Here is what a stranger can check: a real recorded call, one client’s month in numbers, and a sample of the register every production fix is proven against.
A real booking call
A caller rings a Cork salon and asks for an appointment. The agent checks the live diary, offers the nearest slots by stylist and confirms the booking. This is the clip CallHandlers publishes on its own site; it is an edited segment of a real call.
Source: callhandlers.io
- 315
- calls handled
- 98
- appointments booked directly
- 74
- calls answered outside salon hours
- 80
- callbacks captured for the team
- €10,950
- in bookings captured
One partnered salon, August 2026 — the figures CallHandlers publishes in its own product deck.
Every production defect gets an ID, a layer, a status and a named proof — a transcript line, a tool response, a database row. The register runs to 129 entries and is what turns one client’s bug into a rule for every client. Four entries, anonymised:
- Proven — names the artefact
- Applied, not yet demonstrated on an organic call
- Open
- Disproved on evidence — kept, never deleted
IT-111 → IT-122
Workflow
🟠 Fixed · 8/8 unit cases + live vendor read-back
Landline and UK callers could never be booked on one booking system. After the first fix, UK callers looped forever, asked for a mobile number they had already given.
The phone normaliser prefixed every number with the Irish country code and tested for Irish mobiles only. The vendor accepted UK mobiles all along; our normaliser was the constraint. A fix that is right for the numbers you tested can be worse than the bug for the numbers you did not.
Eight unit cases across Irish, UK and landline forms, then a live booking from a UK number read back from the vendor with the real number stored. Ghost booking cancelled, diary clean.
IT-144
Data · fleet standard
🟠 Applied + ghost-proven · 6/6 probes · 25 rows swept
Salons were told to ring the same customer twice: 37 duplicate callback clusters across 10 clients in 30 days.
A database trigger compared phone numbers as raw strings (0866… against +353866…) and demanded an exact service match, so the post-call safety net never collapsed onto the real callback beside it.
The obvious fix was tested against all 37 clusters and 60 days of history first, and rejected: it would have hidden the informative row and eaten genuinely distinct requests. The shipped rule was probed six times against the live trigger, rolled back, then applied with a full rollback in the repo.
IT-092
Workflow + config · fleet standard
🟠 Applied · live-call proof owed at the time
Two capable therapists, one facial room: the engine sold the same room twice because availability was computed per stylist, not per resource.
Availability was rota ∩ stylist-free ∩ caller-free, with no term for the salon’s equipment. Any service bound to a scarce resource could be double-sold whenever two staff were free.
The booking system already modelled rooms and machines. Three workflow nodes were patched to veto any slot with no free instance, verified against the live diary.
IT-097
Workflow + factory
🟠 Fixed · ghost-proven
Every reschedule on one cloned agent silently rewrote the appointment to 30 minutes.
The clone shipped with its donor’s service-duration map. None of the ids matched, so the duration fell back to the default and the update overwrote real durations.
A 45-minute ghost booking moved from Thursday to Friday read back as 10:00–10:45; the pre-fix arithmetic gives 10:00–10:30. Factory lesson: anything keyed on catalogue ids must be regenerated per client.
Findings accumulate into cross-cutting patterns, and the patterns are what upgrade the skeleton every new client is built from. A few of them:
- Every “keep trying” instruction needs a counter and a terminus.
- The tool schema is part of the prompt, and they must agree.
- Silence is a caller-facing failure, not a technical detail.
- A path that cannot fail cannot be proof.
- “The tool fired” is never “the tool worked”.
- A guard added to one flow does not exist in the flows that share the question.
- A finding whose layer you cannot open is a hypothesis, however confident the prose sounds.
- Fixes do not propagate on their own; only the register will catch it.
Where the workflow broke down.
Salon owners miss calls while their hands are busy, and every missed call is a booking that goes to the next salon. Off-the-shelf bots can talk, but they cannot see the real diary: five different booking systems, most without a public API, each with its own rules about deposits, colour services, stylist rosters and opening hours. When I joined, the platform had live clients but no monitoring, a database on the wrong continent, agents whose accents drifted mid-call, and no written record of what had already gone wrong.
Each pain point above mapped directly to a system response. Below, the field-observed challenge on the left and the shipped solution on the right.
- 01
Agents’ accents flipped mid-call, apparently at random, and the defect predated my hire.
The ElevenLabs expressive mode shipped eleven audio tags enabled while the system prompt banned those exact tags by name — two contradictory instructions in the same turn. I documented the collision and presented it to the founder as a decision rather than a unilateral fix.
- 02
Callers heard 20–30 seconds of dead air while the agent thought.
Traced it to the underlying model’s default reasoning latency, which could not be disabled on that family. Re-architected model selection and parameters with reasoning latency disabled, eliminating dead air and verifying the fix against historical conversations before rollout.
- 03
The production database sat in US-West while every caller and every service was in Europe.
Migrated Postgres to the EU with zero downtime, a rollback card with exact revert values and a 20-minute abort deadline. Internal queries fell from 2.82 s to 0.20 s and end-to-end response from ~6 s to under 1 s across 88/88 runs.
- 04
Reschedules on one booking system cancelled first and rebooked second — if the rebook failed, the caller was left with no appointment at all.
Rebuilt it as an in-place move, then built a ghost-probe replay harness that proves every fix against the live booking system before and after. Replaying real appointments through it caught a bug in my own fix before it shipped.
- 05
Business rules written into prompts, knowledge bases and client configs still failed in production.
Argued for and helped design the three-layer model — rules in workflow code, facts in retrieval, per-client values in config — using a live counter-example: a colour-booking restriction written in all three places that only held once it was enforced in node code.
- 06
No monitoring: the team learned an agent was down when a client said so.
Built the first observability stack from nothing — Better Stack, a status channel, deploy-freshness watchdogs — and an automated morning digest per client. The first live digest surfaced six previously unreported production defects.
- 01
Per-client voice agents
One ElevenLabs conversational agent per business, with a factory-compiled system prompt, a client knowledge base, a chosen voice and a fixed tool contract. The prompt carries tone and flow; the facts and rules live elsewhere, so a fix never has to be re-typed into twelve prompts.
- 02
Shared orchestration chassis
One self-hosted n8n workflow per booking system on Railway, serving every tenant on that system. The tenant is resolved at runtime from the agent id, every webhook is secret-authenticated, and opening hours, never-offer stylists and eligibility rules are enforced in node code — not in prose.
- 03
Five booking-system integrations
Phorest, Barespace, Floomly, Fresha and Salon IQ — several reverse-engineered from browser traffic into working adapters. Credentials and sessions that can silently expire get health checks, because a quiet failure is what actually loses a client’s trust.
- 04
Omnichannel DM agent
The same receptionist on Facebook Messenger, WhatsApp and Instagram, calling the same tools and obeying the same business rules as the phone line. The moment the owner starts typing in the thread, the AI stops — automatically. Built, live, and still being tuned from real conversations.
- 05
Client & agency dashboards
Calls, bookings and callbacks for each client, and an agency console for the founders: a fleet board, a live callback queue ordered oldest-waiting first, a phone-number asset pool and a credential registry that stores labels, never secrets.
- 06
Observability & morning digests
Better Stack uptime monitoring, a status channel, deploy-freshness watchdogs and volume alerts, plus an automated morning digest to every client channel with seven-day baselines. Before this, an outage was discovered when a client complained.
Two front doors, one brain.
The voice line and the messaging channels are separate agents with separate constraints, but they share one orchestration layer, one set of booking rules and one database. That is what makes a fix land everywhere at once.
A call reaches the salon’s own line, forwards to a Twilio number and lands on the client’s ElevenLabs agent. Every tool call goes to the n8n chassis on Railway — one shared workflow per booking system, tenant resolved by agent id, secret-authenticated webhooks — which talks to the booking-system adapter and writes the call record, booking or callback into Supabase Postgres. Messaging channels enter through the DM agent and reach the same tools. Behaviour lives in three layers: rules in workflow code, facts in retrieval, per-client values in runtime config. Edge functions front the operational database with row-level security; Better Stack and Slack carry the alerting.
- 12×
Faster database
Internal query time cut from 2.82 s to 0.20 s after the zero-downtime EU migration.
- <1s
Caller response
End-to-end response down from ~6 s, verified across 88 of 88 test runs post-cutover.
- 129
Findings documented
Production defects recorded with severity, root cause and proof — now the company’s primary institutional knowledge asset.
Want to see more work?