hospitality saas / conversational ai · live
updated
WhatsApp AI assistant on each restaurant's own landline.
Many guests would rather send a message than call. Restaurants connect their existing number to WhatsApp Business, and an AI assistant takes reservations and answers questions about the menu and the venue, at any hour and in the guest's language.
- Role
- Architecture and development
- Stack
- NestJS, Postgres, AWS Bedrock
- Models
- Claude Sonnet, Claude Haiku
- Channel
- WhatsApp Cloud API
- tools the agent can use, switched on per restaurant
- 37
- models, picked for each turn
- 2
- automated tests, including end-to-end conversations
- ~880
- Hi! Do you have a table for 4 tomorrow at 7 pm?
- Tomorrow at 7 pm for 4 people works. Shall I book it? Confirm Change
- Confirm
- Booked! See you tomorrow at 7 pm.
- Webhook The message arrives via the WhatsApp Cloud API. Signature checked, duplicates dropped.
- Queue Postgres queue with one lock per conversation. Messages sent in quick succession become one turn.
- Model router Rules pick the model for each turn. This one is about a booking: this message Claude Sonnet bookings and anything that continues one Claude Haiku simple questions, at about a third of the cost
- Agent · 37 tools One tool-calling loop. Here it checks availability and prepares the booking. Reservations · 11 Menu & allergens · 5 Info & FAQ · 4 Buttons & lists · 4 Guest memory Events Vouchers
- Confirmation The booking is only proposed. It runs once the guest taps Confirm.
- Reservation system The booking goes to the restaurant’s system, the reply back through the send queue.
The idea
A restaurant’s phone rings at the worst moment: during service. With this assistant, each restaurant connects the number its guests already know to WhatsApp Business. Guests write to it, and the assistant checks availability, takes reservations, and answers questions about the menu, allergens, opening hours and events. Voice notes work too: they are transcribed before the assistant reads them.
One agent, many tools
Under the hood it’s a single tool-calling agent in a NestJS backend. It can use 37 tools, grouped into reservations, menu, restaurant info, guest memory, events, vouchers, and interactive WhatsApp elements like buttons and lists. Each restaurant switches on the groups it needs and gets its own instructions, tone (formal or informal German) and cost limits. One deployment serves all restaurants.
Questions about a restaurant are answered from its own FAQ, found by vector search in Postgres and re-ranked before the model sees them. The assistant also remembers guests: dietary needs and preferences carry over to the next conversation.
The right model for each turn
Not every message needs the strongest model. A rule-based router picks one for each turn:
- Claude Sonnet handles bookings and anything that continues a booking. That’s the flow where a mistake costs a table, so it gets the stronger model, which makes fewer errors.
- Claude Haiku handles simple questions. It’s faster and costs about a third.
Both run on AWS Bedrock with EU inference profiles.
Guardrails for bookings
A language model shouldn’t be able to book a table on its own. Every reservation, change or cancellation is only proposed at first. It runs once the guest taps confirm or answers yes, which also limits what a prompt injection can do. On top of that: validated inputs (no bookings in the past, sensible party sizes), timeouts, a daily cost cap per guest, retries with a dead-letter queue, and a fixed fallback message if something fails.
Built to run in production
Messages arrive through the WhatsApp Cloud API webhook, are verified and de-duplicated, and go through a Postgres queue. A lock per conversation keeps replies in order, and messages sent in quick succession are answered as one. Tracing runs through Langfuse, error tracking through Sentry with personal data scrubbed. About 880 automated tests, including end-to-end conversations against the real models, run in CI.
Result
The assistant is live. Restaurants get a booking channel that works when nobody can pick up the phone, and guests get an answer at any hour, in their own language.
For the same provider I also built the reservation app and a white-label app generator.
- NestJS
- AWS Bedrock
- Claude
- AI agents
- Postgres