WhatsApp + PostgreSQL bookings, captured and confirmed
Bookings coming in through WhatsApp feels convenient… until you’re scrolling chat history, copying details into a spreadsheet, and realizing two people picked the same time.
Front-desk teams get hit first, but studio owners and agency ops leads feel it too. This WhatsApp booking automation captures the date, time, name, and phone number with guided prompts, then stores it cleanly in PostgreSQL so you stop guessing and start confirming.
This workflow turns messy messages into structured reservations, confirmation replies, and a searchable record you can trust. Here’s what it’s doing under the hood and what you’ll need to run it.
How This Automation Works
See how this solves the problem:
n8n Workflow Template: WhatsApp + PostgreSQL bookings, captured and confirmed
flowchart LR
subgraph sg0["WhatsApp Flow"]
direction LR
n0["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Update Name"]
n1["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Update Hour"]
n2["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Get Work Hours"]
n3["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Get Work Days"]
n4["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Update bot status on START"]
n5@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Is Date correct?", pos: "b", h: 48 }
n6@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Commands", pos: "b", h: 48 }
n7["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/whatsapp.svg' width='40' height='40' /></div><br/>Starts"]
n8["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Get Bot Status"]
n9["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Upsert Bot Status on START"]
n10["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/whatsapp.svg' width='40' height='40' /></div><br/>WhatsApp Trigger"]
n11@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Define Flow", pos: "b", h: 48 }
n12@{ icon: "mdi:swap-vertical", form: "rounded", label: "Initialization", pos: "b", h: 48 }
n13["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Get book"]
n14["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/whatsapp.svg' width='40' height='40' /></div><br/>Main Menu"]
n15["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/whatsapp.svg' width='40' height='40' /></div><br/>Request Date"]
n16@{ icon: "mdi:swap-vertical", form: "rounded", label: "Union Number with Question", pos: "b", h: 48 }
n17@{ icon: "mdi:cog", form: "rounded", label: "Union list", pos: "b", h: 48 }
n18["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Update bot status on BOOKING"]
n19@{ icon: "mdi:swap-horizontal", form: "rounded", label: "First Question?", pos: "b", h: 48 }
n20["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Get Work Days "]
n21["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Add Book"]
n22["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/merge.svg' width='40' height='40' /></div><br/>Merge1"]
n23@{ icon: "mdi:swap-vertical", form: "rounded", label: "Union Number with Question1", pos: "b", h: 48 }
n24@{ icon: "mdi:cog", form: "rounded", label: "Union list1", pos: "b", h: 48 }
n25["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/merge.svg' width='40' height='40' /></div><br/>Merge"]
n26@{ icon: "mdi:swap-vertical", form: "rounded", label: "Edit Fields", pos: "b", h: 48 }
n27@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Switch", pos: "b", h: 48 }
n28["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Update Date AND Status"]
n29@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Phone validation1", pos: "b", h: 48 }
n30["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/whatsapp.svg' width='40' height='40' /></div><br/>Request Phone"]
n31["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/whatsapp.svg' width='40' height='40' /></div><br/>Request Name"]
n32["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/whatsapp.svg' width='40' height='40' /></div><br/>Phone Error"]
n33["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/whatsapp.svg' width='40' height='40' /></div><br/>page booking success"]
n34["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Update status on BOOKED"]
n35["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Update Phone"]
n36["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/whatsapp.svg' width='40' height='40' /></div><br/>Payments"]
n37["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Update bot status on PAYMENTS"]
n38["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/whatsapp.svg' width='40' height='40' /></div><br/>Request Time"]
n25 --> n19
n22 --> n28
n7 --> n9
n27 --> n1
n27 --> n29
n27 --> n0
n21 --> n22
n6 --> n14
n6 --> n3
n13 --> n25
n36 --> n4
n14 --> n4
n17 --> n15
n11 --> n7
n11 --> n6
n11 --> n13
n11 --> n26
n11 --> n36
n26 --> n25
n24 --> n38
n1 --> n30
n0 --> n33
n15 --> n18
n35 --> n31
n3 --> n5
n8 --> n11
n20 --> n22
n2 --> n23
n12 --> n8
n19 --> n21
n19 --> n20
n19 --> n22
n19 --> n27
n5 --> n16
n10 --> n12
n29 --> n35
n29 --> n32
n33 --> n34
n28 --> n2
n34 --> n37
n16 --> n17
n23 --> n24
n37 --> n36
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n10 trigger
class n5,n6,n11,n19,n27,n29 decision
class n0,n1,n2,n3,n4,n8,n9,n13,n18,n20,n21,n28,n34,n35,n37 database
classDef customIcon fill:none,stroke:none
class n0,n1,n2,n3,n4,n7,n8,n9,n10,n13,n14,n15,n18,n20,n21,n22,n25,n28,n30,n31,n32,n33,n34,n35,n36,n37,n38 customIcon
The Challenge: Turning WhatsApp chats into real bookings
WhatsApp is great for getting customers to message you quickly. The problem starts right after that. A “Can I come Friday around 3?” turns into a mini investigation: you check your working hours, confirm the day is available, ask for a phone number, then paste everything somewhere else so it doesn’t vanish into the scroll. Miss one detail and you’re chasing the person again. Miss two and you’re apologizing because you double-booked. Honestly, the worst part is the mental load. You never feel fully “caught up.”
It adds up fast. Here’s where it breaks down in day-to-day booking management:
- You end up re-asking the same questions because the customer didn’t send date, time, and contact details in one neat message.
- Manual entry into a sheet or calendar invites typos, especially on phone numbers and time slots.
- Availability checking happens “in your head,” which means two staff members can confirm the same slot without realizing it.
- Searching old conversations for “that reservation from last week” is slow, and it gets worse as your chat volume grows.
The Fix: Guided WhatsApp prompts + PostgreSQL storage
This workflow listens for incoming WhatsApp messages and routes each person into a simple booking “conversation.” Instead of hoping customers volunteer the right details, it prompts them in the right order: choose a date, pick a time slot that matches your work hours, then provide phone number and name. In the background, it keeps a lightweight status for the chat (so it knows what question comes next), pulls available days/hours from PostgreSQL, and validates inputs before anything is saved. When the reservation is ready, it inserts the booking into a PostgreSQL table and sends a confirmation message back to the customer. It can also send follow-up payment details, which means your process stays consistent even when you’re busy.
The workflow starts with an incoming WhatsApp trigger, then checks the user’s current “step” in the booking flow. It generates valid options based on stored work days and hours, captures the customer’s fields, and writes the final booking record to Postgres. The chat ends with a success confirmation (and optionally a payment message) so nobody is left guessing.
What Changes: Before vs. After
| What This Eliminates | Impact You’ll See |
|---|---|
|
|
Real-World Impact
Say you handle 15 bookings a week through WhatsApp. Manually, you typically spend maybe 10 minutes per booking asking questions, checking hours, and entering the details somewhere reliable, so that’s about 2 to 3 hours weekly. With this workflow, the customer taps through date and time options, then submits phone and name, while Postgres stores everything automatically. You mostly just review edge cases. In practice, that often drops to about 30 minutes of oversight for the whole week.
Requirements
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- WhatsApp Business messaging provider to receive and send WhatsApp messages.
- PostgreSQL database to store bookings, work days, and hours.
- WhatsApp API credentials (get them from your WhatsApp provider dashboard).
Skill level: Intermediate. You’ll connect credentials and run a SQL script to create tables.
Need help implementing this? Talk to an automation expert (free 15-minute consultation).
The Workflow Flow
A customer sends a WhatsApp message. The workflow triggers on inbound WhatsApp, then initializes a little “context” so it can respond correctly even if the person types something unexpected.
The workflow checks what stage they’re in. It looks up the chat’s current status in PostgreSQL (main menu, booking, booked, payments) and uses switches/conditions to route the message to the right prompt.
Availability is generated from your stored schedule. It retrieves work days and work hours from Postgres, summarizes the valid options, and asks the customer to pick a date and then a time slot that fits your rules.
Customer details are captured and validated. Phone numbers get checked before they’re written, names get cleaned up, and the workflow updates the booking record as each field arrives.
The booking is saved and confirmed. The reservation is inserted into your PostgreSQL reservation table, then the workflow sends a success confirmation and can follow with payment details.
You can easily modify available days and time slots to match your actual business hours. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the WhatsApp Trigger
This workflow starts when a new WhatsApp message arrives, so the trigger must be connected and active.
- Add and open Incoming WhatsApp Trigger.
- Credential Required: Connect your WhatsApp credentials.
- Confirm the trigger is connected to the next node Initialize Context.
Step 2: Connect the Primary Database (Postgres)
This workflow relies heavily on Postgres nodes for booking status, work days, and user data. Connect credentials once and apply to all Postgres nodes.
- Open any Postgres node such as Fetch Bot Status.
- Credential Required: Connect your Postgres credentials.
- Apply the same credentials to all Postgres nodes (15 nodes total), including Retrieve Work Days, Update Date and Status, Insert Booking Entry, and Set Status to Payments.
Step 3: Initialize and Route the Conversation Flow
The opening sequence sets context, checks status, and routes the user to the correct branch of the booking flow.
- In Initialize Context, verify it feeds into Fetch Bot Status.
- Confirm Fetch Bot Status outputs to Determine Flow Path.
- In Determine Flow Path, validate that it routes to Start Message Response, Route User Commands, Retrieve Booking Info, and Send Payment Details based on user status.
- Ensure Start Message Response is connected to Upsert Status on Start.
Step 4: Configure Menu and Booking Selection Logic
This section handles menu routing, booking options, and the date/time selection process.
- Verify Route User Commands routes to Send Main Menu and Retrieve Work Days.
- Confirm Retrieve Work Days flows into Validate Date Entry, then Combine Number and Query, and then Summarize Options List before Prompt for Date.
- Ensure Summarize Options List outputs to Prompt for Date, which then updates Set Status to Booking.
- Check the second options path: Fetch Work Hours → Combine Number and Query A → Summarize Options A → Prompt for Time.
Step 5: Handle Parallel Branching and Merging
The workflow uses parallel execution after Check First Prompt to retrieve and update booking data simultaneously.
- Confirm Merge Streams outputs to Check First Prompt.
- Check First Prompt outputs to both Insert Booking Entry, Retrieve Work Days A, and Merge Streams A in parallel.
- Verify Insert Booking Entry and Retrieve Work Days A both feed into Merge Streams A.
- Ensure Merge Streams A flows into Update Date and Status and then Fetch Work Hours.
Step 6: Collect User Details and Validate Input
This section collects phone and name details, validates input, and confirms bookings.
- Check Route by Selection routes to Adjust Time Slot, Validate Phone Input, and Modify Client Name.
- Ensure Adjust Time Slot triggers Prompt for Phone.
- Verify Validate Phone Input sends valid entries to Update Phone Record and invalid entries to Send Phone Error.
- Confirm Update Phone Record leads to Prompt for Name, then Modify Client Name, and finally Send Booking Success.
Step 7: Configure Booking Status and Payment Messages
After a booking is confirmed, the workflow updates status fields and sends payment details.
- Verify Send Booking Success leads to Set Status to Booked.
- Confirm Set Status to Booked flows into Set Status to Payments.
- Ensure Set Status to Payments triggers Send Payment Details.
- Check that both Send Payment Details and Send Main Menu connect to Set Bot Status at Start.
Step 8: Connect WhatsApp Messaging Nodes
All messaging nodes must use the same WhatsApp credential to send responses during the flow.
- Open any WhatsApp node such as Send Main Menu or Prompt for Date.
- Credential Required: Connect your WhatsApp credentials.
- Apply the same credentials to all WhatsApp nodes (9 nodes total), including Start Message Response, Prompt for Time, Send Phone Error, and Send Booking Success.
Step 9: Test & Activate Your Workflow
Run a controlled test to ensure the full booking flow works from trigger to payment details.
- Click Execute Workflow and send a test message to the WhatsApp number connected to Incoming WhatsApp Trigger.
- Confirm the flow follows Initialize Context → Fetch Bot Status → Determine Flow Path and sends a response via Start Message Response or Send Main Menu.
- Complete a full booking path and verify database updates in Postgres nodes like Insert Booking Entry and Set Status to Payments.
- When satisfied, toggle the workflow to Active for production use.
Watch Out For
- WhatsApp credentials can expire or require specific permissions for sending templated messages. If things break, check your WhatsApp provider dashboard and the n8n credential status first.
- If you’re relying on generated option lists (days/hours) and a customer replies with free text, routing can land in the wrong place. Make sure your “validate date” and “validate phone” checks are strict enough to catch odd inputs.
- PostgreSQL schema mismatches cause silent frustration. If you added custom fields, confirm your SQL tables match what the workflow is inserting, and verify the correct schema name replaced “n8n” in the setup script.
Common Questions
About an hour if your WhatsApp and Postgres credentials are ready.
Yes, but someone needs to run the provided SQL to create the Postgres tables. After that, it’s mostly connecting accounts and editing business hours.
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need to factor in WhatsApp messaging fees from your provider and standard database hosting costs.
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
You can adjust the stored work days and work hours tables so the prompts match your real schedule. Many teams also add fields in the “Map Input Fields” step (for party size, service type, or notes) and then extend the Postgres insert/update queries to store them. If you want a different conversation style, change the menu routing in “Route User Commands” and the selection logic in “Route by Selection.”
Usually it’s invalid or expired credentials in your WhatsApp node. Re-check the provider token, confirm the sending number is approved, and look for blocked message types (some providers require templates for certain outbound replies). It can also fail if your workflow tries to respond too quickly and the previous step didn’t finish saving state in Postgres.
On a typical small VPS, handling a few hundred booking conversations a day is realistic as long as your database is sized correctly and your WhatsApp provider isn’t rate limiting you. If you use n8n Cloud, capacity depends on your plan execution limits, while self-hosting is mainly limited by your server resources.
Often, yes, because this flow needs state (what question comes next) and branching logic, and that gets awkward fast in simpler tools. n8n handles switches, merges, and conditional paths without turning your automation into a fragile chain. You also get the option to self-host, which matters when messages spike and you don’t want per-task pricing surprises. The tradeoff is setup: you will spend a bit more time on database tables and testing. Talk to an automation expert if you want a quick recommendation for your exact volume and tools.
Once this is live, every booking becomes a clean database record and a clear confirmation message. Less chasing. More control.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.