> ## Documentation Index
> Fetch the complete documentation index at: https://docs.allgoodhq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Identify and track

> Tell allGood who a visitor is, and record things they do that no form or page load describes.

Two calls on the tag. `identify()` says who the visitor is; `track()` records something they did.

<Note>
  If you've used Segment, PostHog or Amplitude, this is the same shape. Coming from Marketo: `identify()` is roughly `associateLead`, and there's no Munchkin equivalent of `track()` at all — anything that wasn't a page visit or a link click had to become a form submission or an API call.
</Note>

## identify()

Call it when your site already knows who someone is — after a login, a signup, or on an account page.

```js theme={null}
window.allgood.identify({
  email: "ada@example.com",
  firstName: "Ada",
  lastName: "Lovelace",
  company: "Northwind Analytics",
  plan: "enterprise",
});
```

The keys are free-form; there's no fixed list. `email` is the one that matters, because it's what connects an anonymous visitor to a known person.

Call it once per page, after you know. Calling it repeatedly with the same values is harmless but wasteful.

## track()

```js theme={null}
window.allgood.track("Pricing Calculator Used", { seats: 250, plan: "enterprise" });
window.allgood.track("Video Played", { videoId: "product-tour", percentComplete: 25 });
window.allgood.track("Demo Requested", { source: "pricing-page" });
```

The name is any non-empty string. The properties are any JSON you like. There's no event catalogue and nothing to register in advance.

**Naming convention:** `Object Verbed`, in title case — *Pricing Calculator Used*, *Demo Requested*. It's only a convention, but consistency is what makes the events usable six months later.

<Note>
  **Traits versus properties.** Traits describe *the person* — name, company, plan — and belong in `identify()`. Properties describe *what happened* — which button, how many seats — and belong in `track()`.
</Note>

## Calls made before the script loads

The script loads asynchronously, so your code may run first. Queue calls and they're replayed in order once the tag is ready.

Put this **above** the script tag:

```html theme={null}
<script>window.agq = window.agq || [];</script>
<script src="https://mk.brand.com/_ag/v1.js" data-ag-key="agsk_..." async></script>
```

Then queue like this, anywhere:

```js theme={null}
window.agq.push(["identify", { email: "ada@example.com" }]);
window.agq.push(["track", "Pricing Calculator Used", { seats: 250 }]);
```

`window.agq.push` keeps working after the tag has loaded, so you never have to branch on whether it's ready. One bad queued call doesn't stop the rest.

## What allGood adds, and won't take from you

Both calls travel as the same kind of event, batched a few at a time. allGood stamps on the things a page shouldn't be able to choose: when it was received, what the request said about itself, which account it came from, and which device.

**There's no timestamp argument, and one won't be accepted.** A page-supplied time is a time the page could choose.

## URLs get cleaned up

If you send a `url` property, allGood pulls out the attribution parameters — any `utm_` value, plus the usual advertising click ids — as fields of their own, then replaces anything in the query string that looks like an email address, or that's very long, with a marker. Don't put personal data in a URL and expect it to survive.

## Consent applies

Both calls go through the same gate as page views. Under the default posture, calls made before your consent platform answers are held and then sent on a yes; on a no, they're discarded and nothing more is sent for that page load. See [What consent gates](/mk/developer/web-edge/consent-behavior).

## Two settings can silence these

| Setting                                       | Effect                                            |
| --------------------------------------------- | ------------------------------------------------- |
| Web Tracking → **Send events to allGood** off | Nothing is recorded at all, including these calls |
| Web Tracking → **Automatic page views** off   | Only page views stop; these calls still send      |

If your calls produce nothing, check the first one before debugging your code.

## Where the events land

Each becomes an activity in that person's history, the same place a form submission lands. The `email` on an `identify()` is what resolves an anonymous device to a known person.

## Next

→ [Event capture API](/mk/developer/web-edge/reference/event-api), for sending events without the tag.
