---
title: "Identify a visitor"
method: POST
path: "/api/v1/identify"
tags: ["conversions"]
---

# Identify a visitor

`POST /api/v1/identify`

## Request

- Base URL: `https://api.growomat.com`
- URL: `https://api.growomat.com/api/v1/identify`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer

Records who a visitor is (by email, phone or your own id, all hashed at rest) together with the ad click id that brought them, so that a conversion reported later by email alone can still be credited to the click. Where the click id is gone, the identity itself is used for Enhanced Conversions for Leads.

Also accepted with the `campaigns:write` scope, and with a **website key** (`grow_pub_…`), which is the credential the site tag carries. A personal token still works for server-to-server callers.

**Errors**

- `400 VALIDATION_ERROR`: the body failed validation; `details.issues[]` names each field.

## Headers

- `X-Space-Id` string

## Request body

- IdentifyRequest: Who a visitor is and which click brought them. Provide an `email` or an `externalId`, ideally with a click id.
  - `email` string: The visitor's email. Hashed at rest and used for identity matching.
  - `externalId` string: Your own id for the visitor, for example a CRM or customer id.
  - `phone` string: Phone number in E.164 format. Hashed at rest.
  - `msclkid` string: Microsoft Advertising click id.
  - `gclid` string: Google Ads click id.
  - `gbraid` string: Google Ads click id for app campaigns on iOS.
  - `wbraid` string: Google Ads click id for web campaigns on iOS.
  - `rdt_cid` string: Reddit Ads click id.
  - `fbclid` string: Meta click id.
  - `oppref` string: ChatGPT Ads click id.
  - `li_fat_id` string: LinkedIn Ads click id.
  - `clickId` string: A click id when you do not know which kind it is; set `clickIdType` with it.
  - `clickIdType` 'msclkid' | 'gclid' | 'gbraid' | 'wbraid' | 'rdt_cid' | 'fbclid' | 'oppref' | 'li_fat_id': Which kind of click id `clickId` is.
  - `landingUrl` string: The page the visitor landed on.
  - `clickedAt` string, date-time: When the CLICK happened, as observed at landing — not when this beacon was sent. Meta derives `fbc` from it. Ignored if unparseable or in the future; defaults to arrival time.
  - `utm` object: UTM parameters from the landing URL.
  - `consent` ConsentSignal: Consent Mode signals for visitors in the EEA. `UNKNOWN` is sent to the platform as `DENIED`.
    - `ad_user_data` 'GRANTED' | 'DENIED' | 'UNKNOWN': Whether user data may be used for advertising.
    - `ad_personalization` 'GRANTED' | 'DENIED' | 'UNKNOWN': Whether ads may be personalised.

## Response `200`

OK. The result is in `data`. List responses also carry `meta` with `nextCursor` and `total`.

- SuccessEnvelope: The shape of every successful response.
  - `data` unknown, required
  - `meta` object: Present on list responses.
    - `nextCursor` union: Pass as `cursor` to get the next page. `null` on the last page.
      - string
      - number
    - `total` integer: Number of items in this page.

## Other responses

- `201`: Created. The new resource is in `data`.
- `400`: The request is malformed or fails validation. `error.code` is `VALIDATION_ERROR` (with `details.issues[]` naming each field), `INVALID_REQUEST` (the body is not valid JSON or has the wrong shape), or one of the specific codes listed in this operation's description.
- `401`: The bearer token is missing, invalid, expired or revoked (`INVALID_TOKEN`).
- `403`: The token lacks the scope this operation needs (`INSUFFICIENT_SCOPE`), the plan is read-only (`READ_ONLY_MODE`), or the caller is not a member of the Space named in `X-Space-Id` (`NOT_A_MEMBER`).
- `404`: No such resource in the active Space (`NOT_FOUND`), or `X-Space-Id` names a Space that does not exist (`SPACE_NOT_FOUND`).
- `409`: The request conflicts with the current state, for example a delete blocked by dependents or a sync already running. This operation's description names the `error.code` values it can return.
- `429`: Too many requests (`RATE_LIMITED`). Wait for the number of seconds in the `Retry-After` header, then retry.

## Changes

- **2026-10-20** `f02611b531aa`: 9 info
  - added the new optional request property `clickedAt`
  - added the new optional request property `fbclid`
  - added the new optional request property `li_fat_id`
  - added the new optional request property `oppref`
  - …5 more

[Operation history](https://skmtc.dev/growomat/apis/growomat-public-api/changes/api/v1/identify/post.md)

---

[API](https://skmtc.dev/growomat/apis/growomat-public-api.md) · [All operations](https://skmtc.dev/growomat/apis/growomat-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/growomat/apis/growomat-public-api/revisions/f02611b531aa?raw)
