Skip to content

Request forms · 8 fields

Booking request form template

A request, not a calendar. Visitors pick a preferred date, a time of day and an alternative, and you confirm the slot by email or phone. It suits businesses that fit appointments around other work.

Get the code

Booking request

Live demo: try the fields. Submitting sends nothing.

Why these fields

  • Name

    text · required

    Required for the booking.

  • Email

    email · required

    Required. It is where the confirmation goes.

  • Phone

    tel · optional

    Optional. Keep it if you confirm or remind by phone, and say so.

  • What would you like to book?

    text · required

    Required, so you know how long to block.

  • Preferred date

    date · required

    Required. The browser's date picker avoids ambiguous formats such as 03/04.

  • Preferred time of day

    select · required

    Bands are easier to fit than an exact time and save a round of messages about minutes.

  • Alternative date

    date · optional

    Optional, but it often turns a refusal into a booking.

  • Anything we should know in advance?

    textarea · optional

    Optional. For a clinic or a therapist, ask only what you need to prepare, and nothing about health unless you must.

When to use it

Use it for consultations, repairs, studio sessions and viewings, where someone checks the diary before saying yes. If customers should pick and confirm a live slot themselves, you need a booking system; this form does not check availability.

Say on the page that the booking is confirmed only when you reply, and how soon you usually do.

Privacy and GDPR

  • Booking details are needed to arrange what the person asked for, so no consent box is needed for that.
  • Some bookings say more than a time. An appointment at a clinic or a counsellor reveals something about health, so keep those forms short and the retention brief.
  • Delete requests that never became appointments after a short period.

Choose your stack. Copy your form.

Replace the example endpoint with your Formward endpoint, then adapt the fields to your needs.

<form action="https://forms.formward.eu/f/your-form-id" method="POST">
  <label for="name">Name</label>
  <input type="text" name="name" id="name" required />
  <label for="email">Email</label>
  <input type="email" name="email" id="email" required />
  <label for="phone">Phone</label>
  <input type="tel" name="phone" id="phone" />
  <label for="service">What would you like to book?</label>
  <input type="text" name="service" id="service" required />
  <label for="preferred_date">Preferred date</label>
  <input type="date" name="preferred_date" id="preferred_date" required />
  <label for="preferred_time">Preferred time of day</label>
  <select name="preferred_time" id="preferred_time" required>
    <option value="Morning">Morning</option>
    <option value="Afternoon">Afternoon</option>
    <option value="Evening">Evening</option>
    <option value="Any time">Any time</option>
  </select>
  <label for="alternative_date">Alternative date</label>
  <input type="date" name="alternative_date" id="alternative_date" />
  <label for="notes">Anything we should know in advance?</label>
  <textarea name="notes" id="notes"></textarea>
  <input type="text" name="_gotcha" tabindex="-1" autocomplete="off" style="position:absolute;left:-9999px" aria-hidden="true" />
  <button type="submit">Send</button>
</form>

Accessible by default, and how to keep it that way

  • Every field in the code has a visible label tied to it with for and id, so screen readers announce what to enter and a click on the label focuses the field.
  • Required fields carry the required attribute, so the browser explains a missing answer before anything is sent. Say “required” in words as well; an asterisk or a colour alone is easy to miss.
  • The spam trap field (_gotcha) is hidden from screen readers with aria-hidden and skipped by the Tab key, so people never meet it.
  • In the JavaScript versions, show the confirmation or error in an element with role="status" so the result is announced, and keep the entered answers when sending fails.

Changed the fields? Paste your version into the HTML form tester to see exactly what it sends, or run it through the GDPR form checker.

How the code talks to Formward

Each form you create gets its own endpoint in the form https://forms.formward.eu/f/your-form-id. The HTML version posts to it directly and the browser is redirected to a thank-you page, so it works without JavaScript.

The Next.js version below sends the same fields with fetch and an Accept: application/json header. Formward then answers with { ok: true, id }, or an error body with 402 when the plan limit is reached and 429 when the rate limit kicks in. See responses and status codes.

Next.js client component

"use client";

import { useState } from "react";

export function BookingRequestForm() {
  const [sent, setSent] = useState(false);

  async function onSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    const form = e.currentTarget;
    const res = await fetch("https://forms.formward.eu/f/your-form-id", {
      method: "POST",
      headers: { Accept: "application/json" },
      body: new FormData(form),
    });
    if (res.ok) {
      setSent(true);
      form.reset();
    }
  }

  if (sent) return <p>Thanks! Your message has been sent.</p>;

  return (
    <form onSubmit={onSubmit}>
      <label htmlFor="name">Name</label>
      <input type="text" name="name" id="name" required />
      <label htmlFor="email">Email</label>
      <input type="email" name="email" id="email" required />
      <label htmlFor="phone">Phone</label>
      <input type="tel" name="phone" id="phone" />
      <label htmlFor="service">What would you like to book?</label>
      <input type="text" name="service" id="service" required />
      <label htmlFor="preferred_date">Preferred date</label>
      <input type="date" name="preferred_date" id="preferred_date" required />
      <label htmlFor="preferred_time">Preferred time of day</label>
      <select name="preferred_time" id="preferred_time" required>
        <option value="Morning">Morning</option>
        <option value="Afternoon">Afternoon</option>
        <option value="Evening">Evening</option>
        <option value="Any time">Any time</option>
      </select>
      <label htmlFor="alternative_date">Alternative date</label>
      <input type="date" name="alternative_date" id="alternative_date" />
      <label htmlFor="notes">Anything we should know in advance?</label>
      <textarea name="notes" id="notes" />
      <input
        type="text"
        name="_gotcha"
        tabIndex={-1}
        autoComplete="off"
        style={{ position: "absolute", left: "-9999px" }}
        aria-hidden="true"
      />
      <button type="submit">Send</button>
    </form>
  );
}

Spam protection

  • The generated code already includes the hidden _gotcha honeypot. Leave it in: a bot that fills it gets a normal success response, the submission is filed as spam and no email is sent.
  • Every form has a per-IP rate limit, and you can restrict it to your own domains with the allowed-origins list in the form settings.
  • Cloudflare Turnstile is optional and works on every plan, including Free. Turn it on in the form settings, add the widget to your markup and Formward checks the token server-side.
  • The form settings can also reject disposable email addresses, which is worth turning on when a fake address would waste your time.

What happens after submit

  • Each request is emailed to you and stored in the EU on every plan. Formward does not hold a calendar or block slots, so add confirmed bookings to your own diary.
  • From Professional, the autoresponder can acknowledge the request and say it is not yet confirmed. From Professional, a webhook can pass requests to a scheduling tool.

Questions

Does this form check availability?
No. It collects a preferred time and you confirm it. That keeps it simple and works with any diary, but two people can ask for the same slot, so answer in the order requests arrive.
Can I stop requests when I am fully booked?
Yes. The form's response settings take a submission limit and a closing date. Once either is reached, the form stops accepting requests and shows your closed message.

Customize before publishing

  • Remove fields you do not need and mark only essential answers as required.
  • Replace placeholder wording with terms your audience already understands.
  • Add your privacy notice, retention details and expected response time.
  • Test keyboard focus, validation errors and the confirmation state on mobile.

Use this template

Create a free account and the form is set up from this template. Copy your endpoint and replace https://forms.formward.eu/f/your-form-id in the code above.

Use this template →

No website? Use a hosted form