splitforms.com
BOOKINGS · CONTACT FORM TEMPLATE

Hotel Booking Inquiry Form (B&B, Vacation Rental)

Every direct booking inquiry is 15-25% commission you don't pay Booking.com. This form captures dates, party size, and room preference so you can confirm availability and take the reservation yourself.

500/mo free·no card·works on any host
form.htmlhtml31 lines
01<form action="https://splitforms.com/api/submit" method="POST">
02 <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY">
03 <input type="hidden" name="subject" value="New booking request">
04
05 <label for="name">Full name *</label>
06 <input id="name" type="text" name="name" placeholder="Jane Builder" required>
07 <label for="email">Email *</label>
08 <input id="email" type="email" name="email" placeholder="jane@example.com" required>
09 <label for="phone">Phone *</label>
10 <input id="phone" type="tel" name="phone" placeholder="+1 555 555 5555" required>
11 <label for="service">Service *</label>
12 <select id="service" name="service" required>
13 <option value="">Choose…</option>
14 <option>Consultation</option>
15 <option>Standard appointment</option>
16 <option>Premium / extended</option>
17 </select>
18 <label for="preferred_date">Preferred date *</label>
19 <input id="preferred_date" type="date" name="preferred_date" required>
20 <label for="notes">Notes</label>
21 <textarea id="notes" name="notes" placeholder="Anything we should know in advance?"></textarea>
22
23 <!-- honeypot — bots fill every field -->
24 <input type="checkbox" name="botcheck" style="display:none" tabindex="-1" autocomplete="off">
25
26 <button type="submit">Send</button>
27</form>
28
29<p style="margin-top:12px;font-size:11px;color:#888;text-align:right">
30 Powered by <a href="https://splitforms.com" style="color:#888;text-decoration:none" target="_blank" rel="noopener">splitforms</a>
31</p>
500
submissions / mo, free
6
fields, ready to ship
5
code outputs
60s
from copy to inbox
§ 01Why it mattersthe qualifying-fields argument

OTAs take 15-25% of every booking, and small properties — B&Bs, inns, boutique hotels, vacation rentals — feel it hardest. A booking inquiry form on your own site is the cheapest direct-booking channel that exists: the guest found you, they're asking you, and no middleman is in the email thread. The form needs check-in/check-out dates, party size, and room preference so your reply can be a confirmation with a payment link, not a round of twenty questions.

Every direct booking saves 15-25% OTA commission — the form pays for itself on day one. (It's also free.)
✦ at a glance
  • Booking / appointment · 6 fields
  • HTML, JS, React, PHP, cURL outputs
  • One POST endpoint, no SDK
  • Honeypot + classifier, no CAPTCHA
§ 02Live previewinteractive · sandboxed · no key required

See exactly what your visitors see — and you’ll receive.

Left: the rendered form, fully interactive in a sandboxed iframe. Right: the email and dashboard view that lands the moment a visitor submits.

preview · hotel-booking-formlocalhost:3000
✦ what you’ll see in your inbox

Every submission becomes an email plus a dashboard row. The fields below are the exact payload your form will send. Reply-to is wired to the visitor’s email so hitting reply goes back to them.

dashboard · new submission14ms · 200 OK
SUBJECT · New booking request
Full name
Maya Iyer
Email
maya@studio71.co
Phone
+1 415 555 0142
Service
Consultation
Preferred date
2026-05-15
Notes
Loved your last open house in Hayes — looking for similar with parking. Pre-approved through Wells Fargo.

Iframe is sandboxed — submit doesn’t actually fire. Get your access key to wire it up live.

§ 03Three steps3 steps · ~60 seconds

Generate, embed, receive.

Three actions stand between you and your first lead. None of them require a backend, a database, or a CAPTCHA library.

STEP 01GENERATE

Capture the dates first

Check-in date, check-out date, adults, children, room or unit preference. Those five fields let you answer with availability and a price in one email — the whole game is reply speed.

Create your form
key=sk_live_••••••••
STEP 02EMBED

Ask what matters to the stay

An optional 'special requests' textarea catches anniversaries, accessibility needs, early check-ins, and pets. Small properties win on exactly these touches — capture them at inquiry time.

snippethtml
<form action="https://splitforms.com/api/submit" method="POST">
  …
</form>
STEP 03RECEIVE

Reply with a payment link

Webhook the inquiry to your phone or front-desk inbox, confirm availability, and reply with a Stripe / Square payment link or your booking-engine URL. Inquiry-to-confirmation under an hour beats any OTA experience.

inbox · 1 newjust now
FROM contact@yoursite.com
New booking request
Maya Iyer maya@studio71.co
Loved your last open house in Hayes — looking for similar with parking. Pre-approved through Wells Fargo.
§ 04Copy & ship5 languages · same endpoint

Five outputs. One backend.

HTML by default. Click open the language you ship in — every variant POSTs to the same /api/submit endpoint.

01HTMLform.html31 lines
<form action="https://splitforms.com/api/submit" method="POST">
  <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY">
  <input type="hidden" name="subject" value="New booking request">

  <label for="name">Full name *</label>
  <input id="name" type="text" name="name" placeholder="Jane Builder" required>
  <label for="email">Email *</label>
  <input id="email" type="email" name="email" placeholder="jane@example.com" required>
  <label for="phone">Phone *</label>
  <input id="phone" type="tel" name="phone" placeholder="+1 555 555 5555" required>
  <label for="service">Service *</label>
  <select id="service" name="service" required>
    <option value="">Choose…</option>
    <option>Consultation</option>
    <option>Standard appointment</option>
    <option>Premium / extended</option>
  </select>
  <label for="preferred_date">Preferred date *</label>
  <input id="preferred_date" type="date" name="preferred_date" required>
  <label for="notes">Notes</label>
  <textarea id="notes" name="notes" placeholder="Anything we should know in advance?"></textarea>

  <!-- honeypot — bots fill every field -->
  <input type="checkbox" name="botcheck" style="display:none" tabindex="-1" autocomplete="off">

  <button type="submit">Send</button>
</form>

<p style="margin-top:12px;font-size:11px;color:#888;text-align:right">
  Powered by <a href="https://splitforms.com" style="color:#888;text-decoration:none" target="_blank" rel="noopener">splitforms</a>
</p>
02JavaScriptform.js47 lines
<form id="lf-form">
  <label for="name">Full name *</label>
  <input id="name" type="text" name="name" placeholder="Jane Builder" required>
  <label for="email">Email *</label>
  <input id="email" type="email" name="email" placeholder="jane@example.com" required>
  <label for="phone">Phone *</label>
  <input id="phone" type="tel" name="phone" placeholder="+1 555 555 5555" required>
  <label for="service">Service *</label>
  <select id="service" name="service" required>
    <option value="">Choose…</option>
    <option>Consultation</option>
    <option>Standard appointment</option>
    <option>Premium / extended</option>
  </select>
  <label for="preferred_date">Preferred date *</label>
  <input id="preferred_date" type="date" name="preferred_date" required>
  <label for="notes">Notes</label>
  <textarea id="notes" name="notes" placeholder="Anything we should know in advance?"></textarea>
  <button type="submit">Send</button>
</form>

<p style="margin-top:12px;font-size:11px;color:#888;text-align:right">
  Powered by <a href="https://splitforms.com" style="color:#888;text-decoration:none" target="_blank" rel="noopener">splitforms</a>
</p>

<script>
  document.getElementById('lf-form').addEventListener('submit', async (e) => {
    e.preventDefault();
    const data = new FormData(e.target);
    data.set('access_key', 'YOUR_ACCESS_KEY');
    data.set('subject', 'New booking request');

    const res = await fetch('https://splitforms.com/api/submit', {
      method: 'POST',
      body: data,
      headers: { Accept: 'application/json' },
    });

    const json = await res.json();
    if (json.success) {
      e.target.reset();
      alert('Sent!');
    } else {
      alert('Error: ' + (json.message || 'Try again'));
    }
  });
</script>
03React / Next.jsForm.tsx62 lines
'use client';

import { useState, type FormEvent } from 'react';

export default function BookingForm() {
  const [status, setStatus] = useState<'idle' | 'sending' | 'sent' | 'error'>('idle');

  async function onSubmit(e: FormEvent<HTMLFormElement>) {
    e.preventDefault();
    setStatus('sending');

    const data = new FormData(e.currentTarget);
    data.set('access_key', 'YOUR_ACCESS_KEY');
    data.set('subject', 'New booking request');

    const res = await fetch('https://splitforms.com/api/submit', {
      method: 'POST',
      body: data,
      headers: { Accept: 'application/json' },
    });

    const json = await res.json();
    setStatus(json.success ? 'sent' : 'error');
    if (json.success) e.currentTarget.reset();
  }

  if (status === 'sent') return <p>Thanks — we&rsquo;ll be in touch.</p>;

  return (
    <>
    <form onSubmit={onSubmit}>
      <label htmlFor="name">Full name *</label>
      <input id="name" type="text" name="name" placeholder="Jane Builder" required />
      <label htmlFor="email">Email *</label>
      <input id="email" type="email" name="email" placeholder="jane@example.com" required />
      <label htmlFor="phone">Phone *</label>
      <input id="phone" type="tel" name="phone" placeholder="+1 555 555 5555" required />
      <label htmlFor="service">Service *</label>
      <select id="service" name="service" required>
        <option value="">Choose…</option>
        <option>Consultation</option>
        <option>Standard appointment</option>
        <option>Premium / extended</option>
      </select>
      <label htmlFor="preferred_date">Preferred date *</label>
      <input id="preferred_date" type="date" name="preferred_date" required />
      <label htmlFor="notes">Notes</label>
      <textarea id="notes" name="notes" placeholder="Anything we should know in advance?" />

      <button type="submit" disabled={status === 'sending'}>
        {status === 'sending' ? 'Sending…' : 'Send'}
      </button>

      {status === 'error' && <p>Something went wrong. Try again.</p>}
    </form>

      <p style={{ marginTop: 12, fontSize: 11, color: '#888', textAlign: 'right' }}>
        Powered by <a href="https://splitforms.com" target="_blank" rel="noopener" style={{ color: '#888', textDecoration: 'none' }}>splitforms</a>
      </p>
    </>
  );
}
04PHPsubmit.php28 lines
<?php
// Drop into a PHP page. Receives a form POST and proxies it to splitforms.com.
// Useful when you want to add server-side validation or rate limiting.

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $allowed = ['name', 'email', 'phone', 'service', 'preferred_date', 'notes'];
    $payload = ['access_key' => 'YOUR_ACCESS_KEY'];
    $payload['subject'] = 'New booking request';

    foreach ($allowed as $f) {
        if (isset($_POST[$f])) $payload[$f] = $_POST[$f];
    }

    $ch = curl_init('https://splitforms.com/api/submit');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($payload));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Accept: application/json']);
    $response = curl_exec($ch);
    $status   = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    header('Content-Type: application/json');
    http_response_code($status);
    echo $response;
    exit;
}
?>
05cURLtest.sh10 lines
curl -X POST https://splitforms.com/api/submit \
  -H "Accept: application/json" \
  -d "access_key=YOUR_ACCESS_KEY" \
  -d "subject=New booking request" \
  -d "name=Jane Builder" \
  -d "email=jane@example.com" \
  -d "phone=+15555555555" \
  -d "service=Consultation" \
  -d "preferred_date=2026-05-15" \
  -d "notes=Hello from cURL" 

Replace YOUR_ACCESS_KEY with the key from your dashboard. That’s the only edit.

§ 04bUse this template with…25 frameworks · same backend

One template. Every framework.

The same field set works on every framework splitforms supports. HTML, React, Next.js, Vue, Astro, Hugo, WordPress — same POST, same backend.

Booking / appointment for HTML/forms/html/bookingBooking / appointment for Next.js/forms/nextjs/bookingBooking / appointment for React/forms/react/bookingBooking / appointment for Vue/forms/vue/bookingBooking / appointment for Astro/forms/astro/bookingBooking / appointment for Svelte/forms/svelte/bookingBooking / appointment for Webflow/forms/webflow/bookingBooking / appointment for Carrd/forms/carrd/bookingBooking / appointment for WordPress/forms/wordpress/bookingBooking / appointment for Tailwind CSS/forms/tailwind/bookingBooking / appointment for AJAX (vanilla JS)/forms/ajax/bookingBooking / appointment for Hugo/forms/hugo/bookingBooking / appointment for Gatsby/forms/gatsby/bookingBooking / appointment for Eleventy/forms/eleventy/bookingBooking / appointment for SvelteKit/forms/sveltekit/bookingBooking / appointment for Framer/forms/framer/bookingBooking / appointment for Nuxt/forms/nuxt/bookingBooking / appointment for Alpine.js/forms/alpinejs/bookingBooking / appointment for Bootstrap/forms/bootstrap/bookingBooking / appointment for Jekyll/forms/jekyll/bookingBooking / appointment for Vite/forms/vite/bookingBooking / appointment for JavaScript/forms/javascript/bookingBooking / appointment for Cloudflare Pages/forms/cloudflare/bookingBooking / appointment for Netlify/forms/netlify/bookingBooking / appointment for Vercel/forms/vercel/booking
§ 06FAQ5 answered

Things people ask before they ship.

Direct answers, no marketing fluff. Missing one? Email hello@splitforms.com.

01Is this a real-time booking engine?
No — it's an inquiry form, which is exactly what most small properties want. You stay in control of availability and pricing, reply personally, and take payment however you like. If you outgrow it, the form still earns its keep as the overflow channel for special requests and groups.
02How do I avoid double-bookings against Airbnb / Booking.com?
Reply to inquiries only after checking your channel manager or calendar. Many hosts webhook inquiries into the same Slack channel as their OTA notifications so one glance shows the whole picture before confirming.
03Can I add a date picker that blocks unavailable dates?
The template uses native date inputs, which work everywhere with zero JS. Wiring a calendar widget (Flatpickr, etc.) that greys out booked dates is possible client-side — the POST to splitforms is unchanged. We have a recipe in the docs.
04Does this work on my existing website builder?
Yes — paste the HTML into Squarespace, Wix, WordPress, Webflow, or a hand-built site. No booking-engine subscription, no plugin. Inquiries arrive by email and webhook within seconds.
05Can I collect a deposit through the form?
Not directly — the form doesn't process payments. Standard flow: inquiry arrives, you confirm availability, then send a payment link for the deposit. Keeping payment out of the form also keeps you out of PCI scope.
✻ ✻ ✻

Ship your hotel booking inquiry form (b&b, vacation rental) in 60 seconds.

500 free submissions per month. No credit card. Copy the snippet, paste your access key, watch leads land in your dashboard.

Get free access key →Browse all 75 templates →
founders pricing locked in · early access open