# How to track leads in GA4 with generate_lead

> Record each enquiry in GA4 as generate_lead and each won job as close_convert_lead, then mark both as key events. Google tag and Measurement Protocol.

Source: https://roughfigure.com/blog/track-leads-in-ga4-with-generate-lead (updated 2026-11-11)

To track leads in Google Analytics 4, send a **`generate_lead`** event when someone enquires and a **`close_convert_lead`** event when the job is won, then mark both as **key events** in **Admin → Events**. You can send them from the browser with Google tag, or from your server with the **Measurement Protocol**, which still works when the browser tag is blocked and can report a win days later.

## Why use Google’s recommended event names

GA4 has a set of recommended events for lead generation. Using them, rather than names you make up, means GA4’s lead reports and Google Ads imports understand them without extra set-up. The ones worth knowing:

| Event                  | When                                  |
| ---------------------- | ------------------------------------- |
| `generate_lead`        | The enquiry arrives                   |
| `qualify_lead`         | You decide it’s a real, workable lead |
| `close_convert_lead`   | The job is won                        |
| `close_unconvert_lead` | The lead is lost                      |

Send a `value` and `currency` with each, so reports show money, not just counts.

## Option 1: from the page with Google tag

```js
gtag('event', 'generate_lead', { value: 1150, currency: 'GBP', lead_source: 'estimator' });
```

Simple, but it only knows what happens in the browser. It can’t report a job you win on the phone next week, and it’s blocked for visitors who decline cookies or use blockers.

## Option 2: from your server with the Measurement Protocol

```http
POST https://www.google-analytics.com/mp/collect?measurement_id=G-XXXXXXX&api_secret=<secret>
Content-Type: application/json

{
  "client_id": "1234567890.1793518000",
  "events": [{
    "name": "close_convert_lead",
    "params": { "value": 1320, "currency": "GBP" }
  }]
}
```

- **`client_id`** comes from the `_ga` cookie (the last two numbers). Saving it with the lead lets GA4 tie the win back to the visit, campaign and channel.
- Create the **API secret** in **Admin → Data streams → your stream → Measurement Protocol API secrets**.
- The Measurement Protocol doesn’t tell you about bad requests. Send to `/debug/mp/collect` while you set it up to see errors.

## Turn them into key events

In **Admin → Events**, find `generate_lead` and `close_convert_lead` and toggle **Mark as key event**. They then appear in acquisition reports by channel, so you see whether Google search, Facebook or your van’s [QR code](https://roughfigure.com/blog/qr-codes-for-tradesmen) brings the work.

## Doing it in RoughFigure

In RoughFigure we’ve built GA4 reporting in. Under **Integrations → Ads and analytics**, paste your measurement ID and Measurement Protocol API secret and click **Connect**. Each lead is sent as `generate_lead` with the middle of its estimate as the value, and each won job as `close_convert_lead` with the value you entered, tied to the customer’s visit for those who agreed. No contact details are sent to Google Analytics. [Read the guide](https://roughfigure.com/help/ads-and-analytics), or see [Google Ads offline conversions](https://roughfigure.com/blog/google-ads-offline-conversions-for-trades).

## Questions

### Why don’t my server events show in Realtime?

Without a `client_id` from a real visit, or with the wrong measurement ID, events can be dropped silently. Use the debug endpoint to check.

### Should I use generate_lead or a custom event like form_submit?

Use `generate_lead`. It’s the recommended name, and GA4’s lead reports expect it.

### Does GA4 need consent for these events?

In the UK and EU, analytics cookies usually need consent. Respect the customer’s choice before reading the `_ga` cookie.
