Google Ads Lead Form Attribution for Developers

Add GCLID, GBRAID, WBRAID, UTM, and explicit advertising consent fields to a website form that sends leads to SupaBook

15 min. Updated 2026-10-23.

Lead Form Fields Required for Google Ads Attribution

A useful lead record combines contact information, the original advertising identifiers, acquisition context, and explicit consent evidence. Send these values to the tokenized SupaBook form webhook shown in your Lead Capture settings. Keep that URL out of logs and public documentation.

Tips

  • Recommended contact fields are fullName, email, and phone. At least one usable customer identifier is needed for enhanced matching.
  • Capture gclid, gbraid, and wbraid separately. Do not copy one value into another field.
  • Include UTM source, medium, campaign, term, and content for CRM reporting even when a Google click ID is missing.
  • Use an optional, unchecked advertising measurement consent control. Record GRANTED only after an affirmative selection.
  • Send raw CRM contact fields to SupaBook over HTTPS. SupaBook performs eligible Google normalization and hashing on the server.

Copy the Form and Attribution Code

Adapt the field names to your existing form and keep your current validation, spam protection, and success flow. The example stores one atomic attribution touch for up to 63 days and posts the consent evidence with the lead. Connect the storage call to your consent manager before using browser storage where required.

Important notes

  • Do not place Google OAuth tokens, Supabase service keys, or server credentials in website JavaScript.
  • Do not invent or backfill consent. If the visitor did not grant advertising measurement consent, send DENIED.
  • Do not attach a stored click ID to a later visit that contains a new campaign or click identifier. Replace the attribution touch as one unit.

Accessible HTML form example

Replace the placeholder with the tokenized webhook URL from SupaBook Lead Capture settings.

<form id="lead-form" data-supabook-webhook="YOUR_SUPABOOK_FORM_WEBHOOK_URL">
  <label>
    Name
    <input name="fullName" autocomplete="name" required>
  </label>
  <label>
    Email
    <input name="email" type="email" autocomplete="email" required>
  </label>
  <label>
    Phone
    <input name="phone" type="tel" autocomplete="tel">
  </label>
  <label>
    <input name="adDataConsent" type="checkbox" value="granted">
    I agree that my contact details may be used to measure advertising results.
  </label>
  <button type="submit">Send inquiry</button>
</form>

Attribution capture and submit handler

Use this as a reference module, then adapt it to your framework and consent manager.

const ATTRIBUTION_KEYS = [
  "utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content",
  "gclid", "gbraid", "wbraid"
];
const STORAGE_KEY = "supabook_form_attribution_v1";
const MAX_AGE_MS = 63 * 24 * 60 * 60 * 1000;

function canUseMarketingStorage() {
  // Replace this with your consent manager's advertising-storage check.
  return window.marketingConsentGranted === true;
}

function readStoredAttribution() {
  if (!canUseMarketingStorage()) return {};
  try {
    const saved = JSON.parse(localStorage.getItem(STORAGE_KEY) || "null");
    if (!saved || Date.now() - Date.parse(saved.captured_at) > MAX_AGE_MS) return {};
    return saved;
  } catch {
    return {};
  }
}

function captureAttribution() {
  const params = new URLSearchParams(window.location.search);
  const touch = Object.fromEntries(
    ATTRIBUTION_KEYS.flatMap((key) => params.get(key) ? [[key, params.get(key)]] : [])
  );
  const hasNewTouch = Object.keys(touch).length > 0;
  const attribution = hasNewTouch
    ? { ...touch, captured_at: new Date().toISOString(), landing_path: location.pathname }
    : readStoredAttribution();

  if (hasNewTouch && canUseMarketingStorage()) {
    localStorage.setItem(STORAGE_KEY, JSON.stringify(attribution));
  }
  return attribution;
}

const attribution = captureAttribution();
const form = document.querySelector("#lead-form");

form.addEventListener("submit", async (event) => {
  event.preventDefault();
  const fields = new FormData(form);
  const consentGranted = fields.get("adDataConsent") === "granted";
  const payload = {
    fullName: fields.get("fullName"),
    email: fields.get("email"),
    phone: fields.get("phone"),
    sourceType: "website_form",
    sourceName: document.title,
    referrerUrl: document.referrer || location.href,
    ...attribution,
    ad_user_data_consent: consentGranted ? "GRANTED" : "DENIED",
    ad_consent_recorded_at: new Date().toISOString(),
    ad_consent_source: "external_form_explicit_v1"
  };

  const response = await fetch(form.dataset.supabookWebhook, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(payload)
  });
  if (!response.ok) throw new Error("Lead submission failed");
});

Copy This Prompt Into Your Coding Assistant

Paste this prompt into your coding assistant while the website repository is open. It tells the assistant to preserve the existing form, integrate with the current consent system, and add focused tests instead of replacing the whole form.

Implementation prompt for an LLM

Replace generic references with your framework or form component name when known.

Update my existing website lead form for SupaBook Google Ads offline conversion tracking.

Requirements:
1. Preserve the current design, validation, analytics, success message, redirect, and spam protection.
2. Capture utm_source, utm_medium, utm_campaign, utm_term, utm_content, gclid, gbraid, and wbraid from the landing URL.
3. Treat each new attributed visit as one atomic touch. Never combine an old click ID with a new campaign.
4. Retain attribution for no more than 63 days, and use my existing consent manager before writing marketing data to browser storage.
5. Add an optional, unchecked advertising measurement consent checkbox with clear language. Do not make service conditional on advertising consent.
6. On submission, send the original click identifiers, UTM values, landing path, referrer, email, and phone to my SupaBook form webhook over HTTPS.
7. Send ad_user_data_consent as GRANTED only when the checkbox is selected. Otherwise send DENIED. Also send ad_consent_recorded_at as an ISO timestamp and ad_consent_source as external_form_explicit_v1.
8. Do not hash email or phone in the browser. SupaBook needs the contact record and hashes eligible identifiers server-side before a Google upload.
9. Do not put the SupaBook webhook URL or token in logs, analytics events, error messages, or source-control examples.
10. Add tests for GCLID, GBRAID, WBRAID, UTM-only, expired attribution, denied consent, repeat submission, and a new campaign replacing the prior touch.

Before editing, show me the exact files and submit handler you found. After editing, show the final payload shape with fake values and list every validation you ran.

Validate the Integration Before Sending Real Leads

Use fake contact information and test query parameters first. Confirm the lead appears in SupaBook with the expected acquisition fields and consent state before using the form in a live campaign.

  1. Test each click identifier

    Submit separate test visits with fake gclid, gbraid, and wbraid values. Confirm each value remains in its matching field.

  2. Test consent states

    Submit once with the checkbox selected and once without it. Confirm SupaBook records GRANTED and DENIED respectively.

  3. Test attribution replacement

    Visit with one campaign, then a second campaign. Confirm the second touch replaces the first as a unit instead of mixing identifiers.

  4. Test the existing form experience

    Confirm required fields, accessibility, spam controls, analytics, success messages, and redirects still behave exactly as expected.

  5. Use a real click only after review

    After the fake-data checks pass, use a controlled Google Ads test and review both SupaBook upload status and Google Ads offline data diagnostics.

Official resources

Browse more Integrations help articles or return to the SupaBook Help Center.

Canonical page: Google Ads Lead Form Attribution for Developers canonical page