Lead gen systems · Guide 03 of 07
Direct bookings for B&Bs
Three systems for small guest houses: answer the phone when the owner cannot, take the booking without a middleman, and show the rooms properly. Everything here works anywhere in the world and every prompt is written out in full.
13 min read8 steps6 promptsfreeWhat this is, and how it works
A guest house with eight rooms hands roughly a sixth of its revenue to a booking site, and the reason is not laziness. It is that the alternative has never been built for them.
The owner cooks the breakfast, changes the beds and answers the phone. When the phone rings at nine in the morning it goes unanswered, because they are carrying plates. That call was a booking, and it went to whoever answered next.
Meanwhile every booking that does arrive comes through a platform that takes a commission on it, forever, including from the guest who found them, liked them and came back. The guest thinks they booked the guest house. The guest house pays as though they were a stranger.
All three systems in this guide attack the same wound: the gap between a person wanting to stay and the small business being able to take the booking themselves.
The eight steps, same as every guide
- 1Find guest houses in one town.
- 2Qualify on a visible, checkable flaw.
- 3Capture their own real photos and details.
- 4Work out the honest numbers.
- 5Build the thing they are missing.
- 6Put it on one page.
- 7Look at it yourself and approve it.
- 8Send it.
The qualifier is the easiest in the whole series
No website. That is it. One field in the Google Places response, websiteUri, comes back missing or points at a booking platform rather than at them. A guest house with a strong rating and no site of its own is paying commission on every single booking it takes, with no way not to.
You can read that off a search of an entire seaside town in one API call, for nothing, in about four seconds.
The example, and it is real
Prospect House, 23 Prospect Hill, Whitby YO21 1QD. Found with the search on the next page. 4.7 stars from 59 reviews, five photos on the listing, and no website at all. Every booking it takes arrives through a platform or a phone call. The room photograph used later in this guide is its own.
The honest framing, which also happens to sell better
You are not going to get them off the booking platforms, and you should not pretend otherwise. The platforms bring genuinely new guests and that is worth paying for. What you are doing is stopping them paying a finder's fee on guests who were never found by anyone: repeat visitors, personal recommendations, and the people who look them up by name after seeing them on a platform. Say exactly that. An owner who has been sold "ditch the OTAs" three times will trust the person who does not say it.
What you need, and how to find them
This guide needs one more account than the others, because system 3.1 answers a telephone and that needs a phone number and a voice model.
| Account | What it is for | Free tier | Card |
|---|---|---|---|
Google Cloud console.cloud.google.com | Finding the guest houses and reading which ones have no website. Places API (New) only. | 10,000 calls a month per tier | Yes |
Twilio twilio.com | A phone number for the voice agent to answer on, and call forwarding from their existing line | Trial credit, then per number per month and per minute | Yes |
A realtime voice model openai.com or elevenlabs.io | The voice itself. You need one that does speech to speech with interruption, not text to speech. | None. Billed per minute of conversation. | Yes |
| An image model | Rebuilding the room photographs for 3.2 and 3.3 | Per image | Yes |
| Vercel + Supabase | Hosting the booking page and holding the bookings | Generous, see guide 1 | Later |
Step 1Find every guest house with no website, in one call
curl -X POST 'https://places.googleapis.com/v1/places:searchText' \ -H 'Content-Type: application/json' -H "X-Goog-Api-Key: YOUR_KEY" \ -H 'X-Goog-FieldMask: places.id,places.displayName,\places.formattedAddress,places.rating,places.userRatingCount,\places.websiteUri,places.nationalPhoneNumber,places.photos' \ -d '{"textQuery":"family run bed and breakfast in Whitby England", "pageSize":20}'
The real result, and the one prospect in it
This is the actual output of that search, unedited. Nineteen of the twenty had a website. One did not.
Guest house Rating Reviews Website Riviera Guesthouse 4.7 599 Yes The Belfry Whitby 4.9 200 Yes Corra Lynn B&B 4.8 107 Yes Prospect House 4.7 59 None One prospect from one town, and it is a good one: a well liked guest house with nowhere to send anybody. Run the same search across the six seaside towns nearest you and you will have a fortnight of work.
The qualifier, in full
Keep it if: rating 4.4 or higher, at least 25 reviews, and
websiteUriis either missing or points at a booking platform domain rather than their own.Drop it if: the name contains Hotel and the review count is over about 400, because that is a chain or a large property with a revenue manager and a contract. You want the eight room places where the owner answers the phone.
System 3.1The voice agent
The phone rings at nine in the morning while the owner is carrying plates. That call was a booking.
The problem, precisely. A small guest house misses a large share of its calls, and it misses them at exactly the times it can least afford to: breakfast service, changeover, and evenings. The caller does not leave a voicemail. They ring the next place on the list.
What you build. A voice agent on a new phone number, which the guest house forwards to only when they do not pick up. It never replaces the owner. It catches the calls that were going to be lost anyway, which is why it is an easy yes: there is no downside case where it costs them something they had.
What it must do, in order: answer within two rings, say the name of the guest house, find out the dates and the number of people, say honestly whether it can check availability or not, take a name and a number, and promise a callback in a stated window. That is all.
What it must never do is confirm a booking, quote a price it has not been given, or pretend to be a person. All three create a problem the owner has to clean up, and the third one is the fastest way to lose the client and deserve it.
Say it is an assistant, in the first sentence
Not because a rule says so, though in a growing number of places one does. Because a caller who works it out halfway through feels tricked, and they take that feeling to the guest house. An agent that says what it is up front gets a friendlier call and a better capture rate. This is one of the rare cases where the honest version simply performs better.

How it is actually wired
- Buy a number from Twilio in their area code.
- The guest house sets conditional call forwarding on their existing line, which every phone and mobile network supports, so unanswered calls after four rings go to your number. Their number stays theirs and nothing changes for callers.
- Twilio streams the call audio to a realtime voice model over a websocket, with the system prompt on the next page.
- At the end of the call the agent writes name, number, dates, party size and any note into one row, and texts the owner a summary. The text message is the product. The owner does not want a dashboard, they want a message that says who to ring back.
System 3.1The voice agent system prompt
A realtime speech to speech model
You are answering the telephone for {{PROPERTY_NAME}}, a small family run guest house in {{TOWN}}. You are answering only because the owner could not pick up.Your entire job is to take a message well. You cannot see a calendar, you cannot confirm a booking, and you must never behave as though you can.Open with exactly this, warmly and unhurried:"Hello, {{PROPERTY_NAME}}. I'm the answering assistant, {{OWNER_FIRST_NAME}} is away from the phone just now. I can take your details and get them to ring you straight back."Say you are the assistant in that first sentence, every time, even if the caller sounds like they are in a hurry. Never claim or imply that you are a person. If you are asked directly whether you are a human, say plainly that you are an automated assistant.Then find out, in this order, one question at a time, and never more than one question at a time:1. Which nights they are looking for. Get arrival date and number of nights.2. How many people, and how many rooms.3. Their name.4. The best number to call back on. Read it back to them digit by digit and confirm it.Then close with: "Thank you. {{OWNER_FIRST_NAME}} will ring you back {{CALLBACK_WINDOW}}."Rules, all of them absolute:- Never confirm availability. If asked, say "I can't see the diary from here, but I'll get that checked and rung back to you."- Never quote a price. If asked, say "I'd rather not guess at that, {{OWNER_FIRST_NAME}} will confirm it when they ring you."- Never take a card number, a deposit, or any payment detail. If offered one, decline and say the owner will handle it.- If the caller wants to cancel or change an existing booking, take the details and say it will be passed on. Do not tell them it is done.- If the caller is distressed, angry, or reporting a problem at the property, stop collecting details, tell them you will pass it on immediately as urgent, and end the call politely.- If the caller asks something factual you were given below, answer it plainly. If you were not given it, say you do not know rather than guessing. Never invent a fact about this property.- Keep every reply under about twenty words. This is a phone call, not an essay.- Speak the way someone in {{TOWN}} would. No corporate phrasing, no "absolutely", no "perfect", no "I'd be more than happy to".- Let them interrupt you. Stop talking the moment they start.Things you do know about the property, and may state:{{KNOWN_FACTS}}At the end of the call, output a JSON object and nothing else:{ "caller_name": string|null, "callback_number": string|null, "arrival_date": string|null, "nights": number|null, "guests": number|null, "rooms": number|null, "enquiry_type": "new_booking"|"existing_booking"|"question"|"other", "urgent": boolean, "note": string|null, "captured": boolean }Set captured to true only if you have both a name and a callback number. If the caller hung up before that, set it to false and put what you did get in note.
System 3.2 · 3.3The direct booking page, and room tour films
Somewhere to send the people who already know the name of the place.
3.2The direct booking page
One page. Not a website, not a brochure, not an about section. A page whose only job is to turn somebody who already wants to stay into a booking, without a commission attached.
Who it is for. The guest who was recommended the place, the one who stayed last year, and the one who found them on a platform and then searched the name to see if booking direct was cheaper. That last group is large and it is entirely lost revenue today.
What goes on it, in this order, and nothing else: one wide photograph of the best room, the name and the town, three lines on what the place is, the rooms with a price each, a date picker, and one button. Then the address, a map link and a phone number at the bottom.
What does not go on it: a carousel, a hero video, an about us page, a blog, a newsletter signup, social icons, a chat bubble, or the words "nestled in the heart of".
How the booking is taken. Do not build a payment system or a channel manager. Take the request, hold nothing, and email both parties. The owner confirms by replying. That is how these places already work and it is the version they will actually use. Add payment later only if they ask.
The one number that closes this sale
Work out what one commission on one average booking costs them, and compare it to what the page costs. Do not present it as a percentage, present it as one booking. "This pays for itself the first time somebody who already knew your name books here instead of there." That sentence is the entire pitch and it is true.

3.3Room tour films
A guest house listing has four photographs, all taken on a phone, one of which is the outside of the building. A guest deciding between two places cannot tell what the room is actually like, and that uncertainty sends them to the bigger, blander option.
The film is a slow move through one room, fifteen to twenty seconds, no music, no captions, no drone. It exists to answer one question: is this room bigger or smaller than it looks. That is genuinely all a guest wants to know, and a still photograph is very bad at it.


The rule, and it is the same rule as every other guide
You may tidy, relight, straighten and reframe. You may make the bed, because a housekeeper would. You may not repaint the walls, replace the carpet, remove the beam, change the furniture or make the room bigger. A guest who books because of your picture and then opens the door has to recognise the room. Get that wrong and you have cost the owner a one star review and yourself a client.
The rest of the prompts
The voice agent system prompt is on its own page earlier, because it is the longest and the most important. These four are the rest.
Step 2Pick the guest houses worth approaching
Any cheap text model
You are screening small guest houses and B&Bs for a service that builds them a direct booking page, answers their overflow calls, and rebuilds their room photographs. You will be given one place record from the Google Places API.Apply these rules in order and stop at the first that fails:1. REJECT if rating is below 4.4. Reason: "the property itself is the problem".2. REJECT if userRatingCount is below 25. Reason: "too new or too quiet to judge".3. REJECT if userRatingCount is above 400 AND the name contains "Hotel". Reason: "large property, they will have a revenue manager and a contract".4. REJECT if the name suggests a chain, a group, or an inn attached to a national pub brand.If nothing rejects it, ACCEPT. Then set these flags:- no_website: true if websiteUri is missing entirely.- website_is_a_platform: true if websiteUri exists but its domain is a booking platform, a social network, or a link aggregator, rather than a domain belonging to the property itself.- thin_photos: true if the photos array has fewer than 8 entries.- has_phone: true if nationalPhoneNumber is present.Then choose what to lead with, in lead_with:- "booking_page" if no_website or website_is_a_platform is true. This is the strongest opening and should almost always win.- "voice_agent" if they have a phone but a website already.- "photos" only if they have both a real website and a phone, and thin_photos is true.Return ONLY this JSON and nothing else:{ "decision": "accept" | "reject", "reason": "one short lowercase sentence", "rating": number, "review_count": number, "photo_count": number, "no_website": boolean, "website_is_a_platform": boolean, "thin_photos": boolean, "has_phone": boolean, "lead_with": "booking_page" | "voice_agent" | "photos", "one_line_for_the_owner": "one plain lowercase sentence stating the single most useful fact about how they take bookings today. no adjectives, no pitch, no flattery."}Never invent a number or a fact. Everything must come from the record you were given.Here is the place:{{PLACE_JSON}}
Step 5Rebuild a room photograph
gemini-3-pro-image or gpt-image-2, with their real photo
Relight and reshoot this real photograph of a guest bedroom at {{PROPERTY_NAME}} so it looks like it was taken for a hotel listing, while keeping it unmistakably the same room.Keep the architecture and the contents exactly: the same walls, ceiling, windows, any beams or sloping ceilings, the bed in the same position, the same headboard, the same furniture, the same fittings and the same floor. Do not repaint, do not re-carpet, do not replace or move furniture, do not add artwork, plants, throws, cushions or props that are not already in the photograph, and do not make the room larger than it is.What you may change is only this:- Make the bed properly. Smooth the duvet square, plump and square the pillows. A housekeeper would do this before a guest arrived, so it is honest.- Remove personal clutter: used cups, clothing, toiletries, paperwork, shoes, and anything left on the bed or the bedside surfaces.- Turn the bedside and table lamps on.- Move to soft warm daylight from the window with a gentle falloff instead of flat overhead light.- Reframe to landscape, shot from a corner at chest height, with straight vertical lines.The result must be the same room on a well kept day. Someone who has slept in it must recognise it immediately. It must not look like a different, refurbished or computer generated room.No text, no logos, no watermarks, no borders.
Step 5The room tour film
Any image to video model. Use the rebuilt still as the first frame.
Animate this photograph of a guest bedroom into a slow, steady, continuous camera move, as though filmed on a gimbal by someone walking gently into the room.The move: start exactly on this framing, then drift forward and very slightly to the left over the full duration, as if stepping through the doorway into the room. Nothing else moves. The camera never pans away, never orbits, never tilts up to the ceiling and never cuts.Speed: slow and even. It should feel like a person walking at half pace, not a drone and not a whip pan. No easing in or out at the ends, no acceleration.The room, the furniture, the bed, the light and every object must stay exactly as they are in the photograph for the entire shot. Nothing may appear, disappear, change shape or drift. Fabric may settle very slightly and light may shift almost imperceptibly. Nothing else.No people, no doors opening, no curtains blowing, no lens flare, no vignette, no colour grading shift, no music cue, no text, no captions, no logos, no watermarks.Duration {{SECONDS}} seconds, {{ASPECT}}, held to the very last frame with no fade.
Why the film prompt is mostly a list of prohibitions
Video models want to be interesting. Left alone they will swing the camera, morph the furniture, open a window or invent a person. For a room tour every one of those is a defect, because the guest is trying to read the size and shape of a real room. The whole craft here is holding the model still. If a shot comes back with a flourish in it, throw it away rather than keeping it because it looks impressive.
And check it frame by frame
Scrub through the clip before it goes anywhere. The common failure is a piece of furniture quietly changing shape halfway through, which nobody notices at full speed and everybody notices once it is pointed out. One bad clip on a listing is worse than no clip.
Step 8Write the message
Any text model
Write the message that goes with something you have built for a small guest house without being asked. The thing you built does the selling. Your job is the few lines around it.Facts you may use, and nothing else:- property name: {{PROPERTY_NAME}}- town: {{TOWN}}- what you built: {{WHAT}}- their rating and review count: {{RATING}} from {{REVIEW_COUNT}}- how they currently take bookings: {{BOOKING_SITUATION}}- the channel: {{CHANNEL}}Rules:- Under 70 words.- All lowercase is fine and preferred. Plain words, the way one person writes to another.- No em dashes.- Open by saying what you made and that it is theirs, free, whether or not they reply.- State one true fact about how they take bookings today. Exactly one. Never editorialise about it, never use the word "losing", and never mention a percentage or a commission rate.- Do not offer a call, a demo, an audit, a partnership or a package.- Do not mention any booking platform by name.- End with one question that can be answered in one word.- Never use: unlock, maximise, boost, revenue, hospitality, seamless, elevate, drive direct, I hope this finds you well, quick question, just checking in.- Do not claim you have stayed there, and do not claim to be local unless you are.Return only the message text.
What that gives you for Prospect House:
made you a one page booking site over the weekend, link below, it is yours either way. noticed you have not got one of your own, so anyone who searches you by name after a recommendation has nowhere to land. your room photo is on it, reshot. want me to send the file over?The app, and making it run
This guide is the one where the app matters soonest, because a voice agent that takes a message needs somewhere to put it and somebody to be told about it. You cannot run 3.1 off a spreadsheet.
The three screens. /prospects is the list of guest houses, filtered to no website. /enquiries is every call the agent took, newest first, with the recording and the transcript. /bookings is every request the booking page produced.
The thing that actually matters is not any screen. It is the text message to the owner within a minute of the call ending, with the name, the number and the dates in the body. If that message is late or unclear, the system has failed no matter how good the transcript is.
The one thing to get right before you take a single live call
Call recording consent. The rules differ by country and in some places by region, and in several of them you must tell the caller at the start that the call is recorded. Put it in the greeting, not in a policy page nobody reads. And check whether you need consent from both parties where the guest house is, and where its callers are likely to be. This is the only part of this whole series where getting it wrong has a legal consequence rather than a commercial one.
Set up the database
Paste into Claude Code, Cursor, or any AI coding tool, in your project folder
Set up Supabase for this project using the Supabase CLI, and write the SQL migration for me.First, if it is not already set up: install the CLI, run `supabase init`, then `supabase link` to my project, and tell me exactly what to paste when it asks for my project ref and database password.Then create a migration with four tables. Use uuid primary keys with gen_random_uuid() as the default, and give every table a created_at that defaults to now().TABLE 1, properties. One row per guest house. - owner_id, text, not null. My Clerk user id. - place_id, text, unique, not null. name, text, not null. town, text. address, text. - rating, numeric. review_count, int. photo_count, int. - website, text, nullable. Null is the qualifier that matters most in this business. - phone, text. agent_number, text, nullable, the Twilio number I bought for them. - is_client, boolean, not null, default false. - raw, jsonb. status, text, not null, default 'new'.TABLE 2, enquiries. One row per call the voice agent answered. - property_id, references properties, delete on cascade. - caller_name, text. callback_number, text. - arrival_date, date. nights, int. guests, int. rooms, int. - enquiry_type, text. One of 'new_booking','existing_booking','question','other'. - urgent, boolean, not null, default false. - captured, boolean, not null, default false. False means the agent lost the caller, and this is the number I actually care about. - note, text. transcript, text. recording_url, text. - owner_notified_at, timestamptz, nullable. Null means the owner has not been told yet.TABLE 3, booking_requests. One row per submission from the direct booking page. - property_id, references properties, delete on cascade. - guest_name, text, not null. guest_email, text, not null. guest_phone, text. - arrival_date, date, not null. nights, int, not null. guests, int, not null. - room_type, text. message, text. - status, text, not null, default 'new'. One of 'new','confirmed','declined'.TABLE 4, assets. One row per rebuilt photograph or film. - property_id, references properties, delete on cascade. - kind, text. One of 'room_photo','room_film','booking_page'. - before_url, after_url, text. model, text. prompt, text. - status, text, not null, default 'pending'.Now the security. Turn on row level security on all four tables. properties has owner_id directly, so compare it against the Clerk user id, which Supabase exposes as auth.jwt() ->> 'sub'. The other three have no owner column, so their policies must join back up to properties.Add an index on enquiries for (property_id, created_at desc), and a partial index on enquiries where owner_notified_at is null, because a background job will poll exactly that to send the text message.Explain in plain English what each policy does before you write it, run the migration with `supabase db push`, then show me one test query proving a second user cannot read my rows.
Charging, going live, and the rest of the world

How to charge, and this one is different again
This is the best recurring revenue in the series, and the only guide where a monthly is the natural shape rather than a stretch. The voice agent has a real ongoing cost to you, per number and per minute, so a monthly is easy to justify and easy for the owner to understand.
The booking page is a build. One fee, they own it, and you host it. Resist making the page itself a subscription, because a page that switches off if they stop paying reads as a hostage and they will remember it.
The photographs and films are a job. Per room, done once, priced as a set.
Run it yourself, always. The voice agent needs someone watching the calls it lost and fixing the prompt, in the first month weekly. No guest house owner will ever do that, and if they could they would not need you.
The first client offer I would actually make
Build the booking page free, in full, before you speak to them. It takes an evening once you have the template and it is the only thing that gets a reply. Then charge for the voice agent monthly, once they have seen that you deliver. One free page buys you a client for the thing that actually recurs.
Before you take a single live call
- You have rung the agent yourself at least twenty times, including hanging up mid sentence, talking over it, and asking it a price
- It says it is an assistant in the first sentence, every single time
- It has never once confirmed a booking or quoted a price in testing
- The recording notice is in the greeting, and you have checked the rules where the property is
- The text to the owner arrives within a minute and contains the number
- Forwarding is conditional, so the owner picking up always wins
What breaks
The agent talks too much. The single most common failure. It explains, it confirms understanding, it summarises. Callers hang up. Keep every reply under twenty words and test by ringing it, not by reading the prompt.
Accents and bad lines. A caller on a mobile in a car with a strong regional accent is the real world case, and it is much harder than your test calls. Read the numbers back digit by digit, always.
The owner does not trust it. Expect them to want every recording for the first fortnight. Give them that willingly, it is how they come to trust it, and it costs you nothing.
What I have not tested
The Places search and the photo rebuild in here were run live against the real guest house named. I have not stood up a Twilio number, run a live call through a voice model, built the booking page, or made a room film. The voice prompt, the wiring and the film prompt are written from how these services work, not from a system I have run in production. Treat the first fortnight as testing and price it that way. Prospect House is a real business used as a public example and has no idea this guide exists.
Country notes
The booking page travels everywhere. Small accommodation exists in every country and platform commission is a universal complaint, so 3.2 works unchanged anywhere you can take an email.
The voice agent does not travel as easily, and you should know why before you sell it. Buying a local phone number is straightforward in North America and most of Europe, and considerably harder in parts of Asia, Africa and Latin America where regulators require local registration or a local address. Check that you can actually get a number in that country before you promise anything. Voice quality also drops sharply on poor mobile networks, which is exactly where many small guest houses are.
Where WhatsApp replaces the phone entirely
In most of Latin America, India, Indonesia, and much of Africa and the Middle East, a small guest house takes its bookings on WhatsApp, not on a phone call and not by email. In those markets, build system 3.1 as a WhatsApp agent instead of a voice one and it becomes easier, not harder: text is cheaper than voice, there is no accent problem, the conversation is already written down, and the owner can read the thread themselves. The system prompt on the earlier page works almost unchanged, minus the greeting and the digit read back.