Skip to main content

Website Form Capture

When enabled, the widget watches every form on your site and forwards email / phone / name / company-name fields to the Identity Graph as soon as a visitor submits one. This identifies the visitor instantly, builds out their Person Profile, and (because it's a first-party form) directly verifies the session for cross-session AI context.

What gets captured

Across native HTML forms, single-page-app submit buttons, Enter-key submissions, and embedded third-party form iframes, the script extracts:

  • Email<input type="email">, fields with name/id/label containing "email", or any field whose value matches an email pattern.
  • Phone<input type="tel">, fields with name/id/label containing "phone" / "tel" / "mobile" / "cell".
  • Name — fields named name, full_name, first_name, last_name, etc. First + last are joined into one display name.
  • Company / business name — fields named company, company_name, business, organization, employer, workplace.

That's it. No password fields. No hidden fields. No credit-card / CVV / SSN / routing-number fields. No file uploads. No fields outside the visible form.

What gets sent

A small JSON payload with the captured fields, your user_session_id, and your company_id. No raw form HTML. No DOM screenshots. No third-party services — the request goes to your Knock Knock backend over the existing widget connection.

To make sure ad-blockers, privacy extensions, and CORS configurations don't drop the submission, the script tries three transports in order:

  1. The widget's existing socket connection — invisible to ad-blockers because it's the chat product's own channel.
  2. navigator.sendBeacon — survives page navigation immediately after submit.
  3. fetch with keepalive: true — final fallback.

All three send as text/plain (a CORS-safelisted content type), so no preflight is needed and there's nothing for blockers to filter on path or content-type.

Supported third-party form providers

When you embed a form from one of these providers as an iframe, the script also captures submissions from the iframe via the postMessage channel:

ProviderDetected originNotes
HubSpot Formshsforms.net, hubspot.comListens for hsFormCallback / onFormSubmit events.
Calendlycalendly.comListens for calendly.event_scheduled (a booking is itself a verified identification trigger).
GoHighLevelleadconnectorhq.com, msgsndr.com, gohighlevel.com, plus white-label customer domainsRecognises set-sticky-contacts, lc-form-submit, V2 form fields shape, and contact-id payloads.
Typeformtypeform.com
Jotformjotform.com, jotform.us
Mailchimplist-manage.com

White-label deployments (e.g. a GHL form served from app.<your-customer>.com instead of leadconnectorhq.com) are auto-detected: the script scans the page for iframes whose src carries provider fingerprints (/widget/form/, /widget/survey/, /forms/<id>) and dynamically allowlists those iframe origins.

Turning it on

Owned by the super admin. The capture_website_forms flag lives in the global Identity Graph defaults (and can be overridden per company). On the customer side there's no toggle — when the admin enables it, the form-intercept script is injected alongside the widget on every page where the widget loads. See Admin Controls.

Known limitations

  • Some GoHighLevel V2 forms submit server-to-server. If GHL's iframe doesn't post any client-side event after submit, we can't see it — the form data goes directly from the iframe to GHL's backend. In that case the canonical alternative is to set up a GHL workflow that webhooks form submissions back to your tenant.
  • Iframes from origins not in the allowlist are ignored. If you're using an embedded form provider that isn't listed above, contact support and we can add it.
  • Cleared browser storage loses the verification anchor. The next session will be treated as claimed until another verification trigger fires (form, CRM landing, inbound call).