Lead capture form

Lead capture form6 min read

Build a consultation request form for a service business

A consultation request form for accountants, lawyers, coaches and clinics that asks how and when to call, and leaves sensitive details for the call.

Preet SutharFounder, Ikiform

Ask for name, email, how to reach them and roughly when, plus a broad topic, and keep every detail of their situation for the call. Record their time zone from the browser so a requested morning means their morning. Enforce rules the form schema can't express, such as a phone number only when they chose a phone call, in your own code.

What's different about a consultation request

A consultation request comes from a person with a problem: a tax letter, a lease dispute, a business they want to start. They want to explain it, and the form invites them to. That is the trap. Whatever they type is stored with the submission, shown in notification emails and sent in webhooks to wherever you point them. Account numbers and case details don't belong in any of those.

So the form's job is narrower than it looks: who they are, how and when to reach them, and roughly what it's about. Everything else waits for the call, where you control what gets written down and where it is kept.

What a consultation form asks, and what waits for the callon the formon the callwhoname, emailhowemail, phone orvideowhenday, timewindow, timezoneabouta broad topictheirsituationin their wordsdocumentsthrough yourown channelnumbersaccounts, ids,recordsfit and feesyour answerWhat a consultation form asks, and what waits for the callon the formon the callwhoname, emailhowemail, phone or videowhenday, time window, time zoneabouta broad topictheir situationin their wordsdocumentsthrough your own channelnumbersaccounts, ids, recordsfit and feesyour answer
  1. The form asks who they are: name and email.
  2. It asks how to reach them: email, phone or video.
  3. It asks when: a preferred day, a time window and their time zone.
  4. It asks what it is about, as one broad topic.
  5. The call covers their situation in their own words.
  6. Documents go through a channel you choose, not the form.
  7. Account numbers, ids and records are never typed into the form.
  8. The call ends with your answer on fit and fees.
The top row is enough to book the call and prepare for it. The bottom row is what the call is for.

The fields

Preview

Runs Ikiform's validator in your browser. Nothing is sent.

How should we reach you?

Only if you chose a phone call.

Best time

A sentence or two. Please don't include account numbers or personal records.

Pick Phone call and leave the phone empty: the schema accepts it, because a field can't be required only sometimes. The code below closes that gap.
FieldWhy it's shaped this way
contact_methodA radio, so the first contact happens the way they asked
phoneOptional in the schema, required by your code when they pick a phone call
preferred_dateA date field stores YYYY-MM-DD. Its schema min is fixed, so the page sets tomorrow as min in the browser
timezoneFilled from the browser with Intl.DateTimeFormat().resolvedOptions().timeZone, such as Europe/Berlin
noteCapped at 500 characters. Notification emails show up to 500 characters per value, so the whole note fits

Conditional rules in your own code

Ikiform validates each field on its own. Rules that depend on another field, such as phone only for phone calls, run in your code. Server versions can enforce them for real; browser versions guide the visitor and send nothing they didn't need to.

The script sets required on the phone input when Phone call is picked, sets tomorrow as the earliest day in the visitor's own calendar, and fills the hidden time zone.

consultation.html
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="POST" id="consult">
  <label for="name">Name</label>
  <input id="name" name="name" autocomplete="name" required />
  <label for="email">Email</label>
  <input id="email" name="email" type="email" autocomplete="email" required />

  <fieldset>
    <legend>How should we reach you?</legend>
    <label><input type="radio" name="contact_method" value="email" checked /> Email</label>
    <label><input type="radio" name="contact_method" value="phone" /> Phone call</label>
    <label><input type="radio" name="contact_method" value="video" /> Video call</label>
  </fieldset>
  <label for="phone">Phone</label>
  <input id="phone" name="phone" type="tel" autocomplete="tel" />

  <label for="topic">What is it about?</label>
  <select id="topic" name="topic" required>
    <option value="new_business">Starting a business</option>
    <option value="tax">Tax and bookkeeping</option>
    <option value="other">Something else</option>
  </select>

  <label for="preferred_date">Preferred day</label>
  <input id="preferred_date" name="preferred_date" type="date" />
  <fieldset>
    <legend>Best time</legend>
    <label><input type="radio" name="time_window" value="morning" /> Morning</label>
    <label><input type="radio" name="time_window" value="afternoon" /> Afternoon</label>
    <label><input type="radio" name="time_window" value="evening" /> Evening</label>
  </fieldset>
  <input type="hidden" name="timezone" />

  <label for="note">Anything we should know first?</label>
  <textarea id="note" name="note" rows="3" maxlength="500"></textarea>
  <p>A sentence or two. Please don't include account numbers or personal records.</p>

  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
  <button>Request a consultation</button>
</form>

<script>
  const form = document.getElementById("consult");
  const phone = form.elements.phone;
  const tomorrow = new Date(Date.now() + 86400000);
  const local = new Date(tomorrow.getTime() - tomorrow.getTimezoneOffset() * 60000);

  form.elements.timezone.value = Intl.DateTimeFormat().resolvedOptions().timeZone;
  form.elements.preferred_date.min = local.toISOString().slice(0, 10);
  form.addEventListener("change", () => {
    phone.required = form.elements.contact_method.value === "phone";
  });
</script>

The server-side versions post with a secret key, so Ikiform skips Allowed domains and its human check. Every post then comes from your server's IP, and the Standard limit of 5 a minute per visitor counts all your visitors together. Choose the Relaxed or Custom rate limit for a form you post through a server, and keep IKIFORM_SECRET_KEY in server-only environment variables. The server versions forward the visitor's Origin header, because a server-side fetch sends none and Ikiform detects free localhost tests from it.

Keep sensitive details off the form

  • Say it in the help text, as the form above does. People follow a plain instruction more often than you'd expect.
  • Don't add fields for identity numbers, account numbers or medical details. If your profession has rules about client data, check them before collecting anything beyond contact details, and collect the rest through a channel that meets them.
  • Field names matter too. Ikiform holds the notification email for review when a field name looks like a credential, including names containing password, ssn, cvv or seed. A field called seed_round on a startup consultancy's form trips this. Name it funding_stage.
  • Point webhooks only where the whole team is allowed to read client names, such as a private channel, not a company-wide one.

The first reply

The notification email arrives with Reply pointed at the visitor, so the first reply can come straight from your inbox. Make it do one job: confirm a time. Two concrete slots inside their window are easier to say yes to than a question about when suits them.

  • Convert their window to your time before you write. A morning in Australia/Sydney is the previous evening in London.
  • Offer two slots in their time zone, and name the zone in the email, so nobody shows up an hour early.
  • Say how you'll call: the number they gave, or a video link you send with the invite.
  • If the topic is outside what you do, say so in the first reply and suggest someone who does. That reply is still worth sending.

Check it works

  1. Pick Phone call, leave the phone empty and submit. The browser or your server stops it with a message.
  2. Pick Email, submit, and open the submission. It has no phone value and has your time zone, such as America/Chicago.
  3. Try choosing today as the preferred day. The date picker doesn't offer it.
  4. Check the notification email. The note shows in full, and Reply writes to the visitor.
  5. List your field ids and check that none contains password, ssn, cvv or seed.

Gotchas

  • Date without time zone. preferred_date is a calendar day, not a moment. Read it together with timezone and time_window before you call.
  • Radios with nothing picked. An unchecked radio group sends nothing. That is fine for time_window, which is optional, and the reason contact_method starts with Email checked.
  • No booking confirmation. Ikiform doesn't email the person who fills in the form. Your first reply confirms the time. If you want people to pick a slot themselves, hand off to a scheduler as in Demo request form.
  • Phone format. The phone field accepts 6 to 15 digits as typed. Turn on e164 if you dial from a system that needs +14155550123, and numbers without a country code are then refused.

Questions

Stuck on a step, or want a guide for your situation? Email hello@ikiform.com.