Back to the growth library
PLGIntegrations

Heap Signup Enrichment: Autocapture Still Needs a Name Attached

Heap captures every click without instrumentation, but it has no idea which signups are worth analyzing. Here's how PLG teams attach company and ICP data to Heap users and accounts so autocapture reports reflect fit, not noise.

Analyst reviewing a product usage dashboard with charts and session data

Heap records everything. It doesn't know who any of it is from

Heap's whole pitch is that you stop writing tracking code. Install the snippet, and every click, page view, and form submission gets captured automatically, then you define events retroactively against that raw session data. It works. The autocapture problem Heap was built to solve is real, and most teams that switch to it stop losing weeks to missing instrumentation.

What Heap doesn't solve, because it was never meant to, is the identity half of the problem. A session gets captured in full detail the moment someone lands on your signup page, before you know anything about them. By the time heap.identify() fires, you've already got a pile of anonymous events tied to a device ID, and no way to say whether that device belongs to a VP of engineering at a 400-person company or someone's cousin testing a free trial for fun.

Most Heap implementations patch this with whatever the signup form collected: a plan tier, maybe a referral source. That's enough to build a funnel chart. It's not enough to answer the question that actually matters in a weekly growth review: are we losing good-fit signups to a broken flow, or is the drop-off concentrated in people who were never going to convert regardless of what we fixed?

Groful resolves the company behind a signup, scores ICP fit, and surfaces relevant teammates before the user finishes onboarding. This post covers getting that specifically into Heap's identity and account model. If you haven't read the fundamentals yet, start with the PLG signup enrichment guide.

Why autocapture without fit data is just noise with good resolution

Heap's strength is that it captures interactions you didn't think to track, which is also its weakness when it comes to interpretation. A spike in rage-clicks on the pricing page could mean the page is broken, or it could mean a cluster of low-fit free users are confused by a plan they were never going to buy. Without a fit label on the session, Heap will show you the spike but not which story it's telling.

The same problem shows up in retention and conversion reports. A funnel from signup to "created first workspace" that converts at 18% overall might really be 40% for companies that match your ICP and 6% for everyone else. If you optimize against the blended 18%, you end up shipping changes aimed at a population that includes a lot of people who were never going to stick around, and the fixes that would move your actual target segment never get prioritized. This is the same reasoning behind PLG activation scoring and account scoring: behavioral data is only useful once you know which behavior belongs to which kind of account.

Heap's own differentiator, Journeys, makes this worse if you skip enrichment rather than better. Journeys shows you the paths people actually took through your product, pulled straight from captured events, no manual tagging. That's powerful for finding unexpected drop-off points. It's also a great way to confidently misdiagnose a problem if the paths it's showing you are a mix of accounts you want more of and accounts you don't.

Wiring enrichment into Heap

Heap gives you three places to attach identity data: the user (via heap.identify and heap.addUserProperties), the account (via Heap's account-level properties, if you're on a plan with Accounts enabled), and historical backfill through the REST API for sessions that already happened.

Identify the user and set properties at signup, not at login

Call enrichment right after signup completes, then identify the user and set properties in the same step, before any meaningful product event fires. If you wait until the next login, early onboarding events are stuck without company context permanently; Heap doesn't retroactively attach properties to events that already happened under an anonymous identity.

const enrichment = await fetch("https://api.groful.co/v1/enrichment/lookup", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${process.env.GROFUL_API_KEY}`,
  },
  body: JSON.stringify({ externalId: userId, email }),
}).then((res) => res.json());

heap.identify(userId);

heap.addUserProperties({
  "Company Domain": enrichment.company?.domain ?? "unknown",
  "Company Size Band": enrichment.company?.employeeCountBand ?? "unknown",
  "Job Title": enrichment.user?.jobTitle ?? "unknown",
  "ICP Fit": enrichment.company?.icpFit ?? "unknown",
  "ICP Confidence": enrichment.company?.confidence ?? "low",
});

heap.track("Signup Enriched", {
  "Company Domain": enrichment.company?.domain ?? "unknown",
  "ICP Fit": enrichment.company?.icpFit ?? "unknown",
});

If the enrichment call times out or fails, still run heap.identify() with the user ID you have and skip the property write rather than holding up the signup redirect for a third-party lookup.

Attach account-level properties if you're using Heap Accounts

Heap's Accounts feature lets you group users under a shared account ID, which matters for any product where more than one person from the same company signs up separately. Push the same enrichment payload to the account level through Heap's account properties API so reports can roll up by company rather than by individual user.

await fetch("https://heapanalytics.com/api/add_account_properties", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    app_id: process.env.HEAP_APP_ID,
    account_id: enrichment.company?.domain ?? "unknown",
    properties: {
      industry: enrichment.company?.industry ?? "unknown",
      employee_count: enrichment.company?.employeeCount ?? null,
      icp_fit: enrichment.company?.icpFit ?? "unknown",
    },
  }),
});

Without this step, Heap's account view exists but stays mostly empty, and anyone trying to build an account-level report ends up falling back to user-level data anyway.

Backfill existing sessions through the REST API

For a product that's been live for a while, don't wait for stale profiles to catch up on their own. Loop through your user table, resolve enrichment for anyone missing it, and push the result through Heap's add_user_properties endpoint as a batch job. Rate-limit the job against your enrichment credit budget as much as Heap's API limits; a backfill across tens of thousands of users can burn through a month of credits faster than expected if it isn't throttled.

Keep the property list to what you'll actually filter on

Six properties at the user level and three or four at the account level covers nearly every report a growth team builds in practice: domain, size band, job title, fit tier, confidence, and maybe a routing lane. Heap's event and property definitions get harder to search and slower to query once dozens of raw enrichment fields get pushed in as first-class properties. Keep the full payload in your warehouse and join it there when an analysis needs more than the dashboard surfaces.

What to actually build once fit data is in Heap

Funnels segmented by ICP fit. Take whatever core activation funnel you already track and rebuild it as two or three lines split by fit tier instead of one blended line. This is usually the single most clarifying chart a team can add.

Journeys filtered by account properties. Once account properties are populated, filter Journeys to high-fit accounts only before trying to diagnose a drop-off. The paths look different, often substantially, from the unfiltered version.

Retention by company size band. Heap's retention reports get more useful once you can compare a 10-person team's onboarding curve against a 300-person team's, instead of averaging both into one number that describes neither well.

A low-confidence watchlist. Sessions where enrichment came back with low confidence tend to cluster around shared inboxes, disposable domains, and personal email signups. If that same group also shows unusual rage-click or abandonment patterns in Heap, that's worth investigating as a data quality issue before it's treated as a product issue.

Where this breaks if a step gets skipped

Calling heap.identify() without ever calling addUserProperties(). Heap will still merge the anonymous and identified sessions correctly, but every report that depends on company or fit data will come back empty for that user, and it's easy to miss because identification itself still "worked."

Treating "unknown" as "bad fit." A signup still waiting on enrichment and a signup that resolved to a genuinely low-fit company are different states. Collapsing them into the same cohort inflates your low-fit numbers with cases that just haven't finished processing yet.

Skipping the Accounts setup. If Heap Accounts isn't configured, the account-properties API call above will silently do nothing useful, and anyone building an account-level report will fall back to deduplicating by domain in a spreadsheet instead.

Re-running enrichment on every page load. Company and ICP data doesn't change session to session. Cache the result and refresh weekly at most, rather than hitting the enrichment API and rewriting Heap properties on every visit.

A short rollout plan

Days 1–3: Wire the enrichment call into the signup flow, add heap.identify() and heap.addUserProperties(), and confirm the properties show up correctly in Heap's user lookup for a handful of test accounts.

Days 4–7: Set up Heap Accounts if it isn't already configured, push account-level properties for existing companies, and run the backfill job against your current user base.

Week 2: Rebuild your core activation funnel and one Journeys view as fit-segmented versions, and bring those into the next growth review instead of the blended charts the team has been using.

The autocapture is already solved. Identity is the part left over

Heap did the hard part of killing manual instrumentation. What's usually missing is a reliable answer to who a session belongs to before the data starts piling up under an anonymous ID. Get that resolved at signup, and Journeys, funnels, and retention reports stop needing a mental asterisk about who's actually in them.

Groful is built for growth managers who need that resolution done automatically rather than reconstructed later from a CRM export. Review the PLG signup enrichment solution, check pricing, or contact Groful to scope a Heap integration for your product.

Turn this playbook into workflow

Enrich signups, score ICP fit, and surface expansion opportunities with Groful.