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

# Identifying Shoppers

> Tell Remark who the current shopper is

You can tell the widget who the current shopper is, using either of two trust levels that work independently.

<CardGroup cols={2}>
  <Card title="Identify" icon="user">
    Tell Remark the shopper's email, phone, or name.
  </Card>

  <Card title="Verify" icon="shield-check">
    Verify the shopper's identity with a signed token.
  </Card>
</CardGroup>

You call both through `window.remark(...)`, which loads asynchronously, so your code needs to wait until it's ready before calling it. The examples below do that with the `whenRemarkReady` helper from [Waiting for Remark to initialize](/sdk/advanced#waiting-for-remark-to-initialize).

## Identify (unverified)

Use `identify` to tell Remark who the shopper might be, so it can greet them by name or attach the conversation to a known shopper.

```javascript theme={null}
whenRemarkReady(() => {
  window.remark('identify', {
    email: 'shopper@example.com',
    phone: '+1 415 555 0132',
    firstName: 'Sam',
    acceptsMarketing: true
  });
});
```

### Fields

| Field              | Type    | Description                                                                |
| ------------------ | ------- | -------------------------------------------------------------------------- |
| `email`            | string  | The shopper's email address.                                               |
| `phone`            | string  | The shopper's phone number. Any common format works. Remark normalizes it. |
| `firstName`        | string  | The shopper's first name, used to greet them.                              |
| `acceptsMarketing` | boolean | Whether the shopper has opted in to marketing.                             |

Every field is optional, but provide at least an `email` or `phone` for the shopper to count as identified.

<Warning>
  Because `identify` details come from the browser, anyone could claim any email.
  Use them for personalization only, not to gate order history, account details,
  or other sensitive data. Use [Verify](#verify) for that.
</Warning>

## Verify (trusted)

Verify proves a shopper is who they say they are, so Remark can show order history, account details, or act on their behalf. Your server creates a short, signed token naming the shopper, and Remark checks the signature before it trusts the token. The one rule is to keep that signing secret on your server and out of the browser: as long as it stays there, no one can forge a token. Remark holds its own copy so it can check the signature.

### 1. Get your signing secret

In the Remark dashboard, go to **Settings → Identity verification** and select **Generate secret**. Remark shows it only once, so copy it and store it somewhere only your server can read, such as an environment variable, and never in client-side code.

To replace a secret later, use **Regenerate**. The new secret works right away, and any token signed with the old one stops working, so regenerate when traffic is low.

### 2. Sign a token on your server

When you render a page for a signed-in shopper, create a short-lived [JSON Web Token](https://jwt.io) signed with that secret. The token must:

* use the `HS256` algorithm,
* include the shopper's `email`, `phone`, or both,
* set `sub` to the shopper's lead, so the token only works for that shopper's session,
* set an expiry (`exp`) about 5 minutes out. Remark rejects tokens that last much longer than that.

```javascript theme={null}
// Node.js, in your token endpoint. This runs on your server, never in the browser.
import jwt from 'jsonwebtoken';

// Remark sets the shopper's lead in the `remark_lead` cookie on your domain, so
// it arrives with this request. Bind the token to it.
const lead = req.cookies.remark_lead;

const token = jwt.sign(
  { email: 'shopper@example.com' }, // and/or phone, from your server-side session
  process.env.REMARK_IDENTITY_SECRET,
  { algorithm: 'HS256', subject: lead, expiresIn: '5m' }
);
```

The `sub` claim is what ties the token to one shopper. Remark gives every visitor a lead and stores it in the `remark_lead` cookie on your domain, so it rides along with the request above. If your token endpoint can't read that cookie, read the lead in the browser from `localStorage` under `remark_lead` and send it to your server. Unlike the email and phone, the lead is not sensitive, so reading it from the browser is fine: it only scopes the token to this session.

<Warning>
  Build the token for the shopper who is signed in to your server. Read their
  email or phone from your server-side session, never from a query parameter,
  form field, or anything else the browser sends. Otherwise someone could
  request a token that claims to be another shopper.
</Warning>

### 3. Verify from the page

Fetch a fresh token from your server when the page loads, then pass it to Remark:

```javascript theme={null}
async function verifyShopper() {
  const { token } = await fetch('/api/remark-identity-token').then((r) => r.json());
  window.remark('verify', token);
}

whenRemarkReady(verifyShopper);
```

<Info>
  Sign a fresh token on each page load rather than storing one and reusing it.
</Info>

### Confirming it worked

If the token checks out, Remark records the shopper's email and phone as verified.

If a token is invalid, expired, or set to last too long, Remark rejects it. The page doesn't get an error back, and nothing prints to the browser console unless the request itself fails. To confirm your tokens are being accepted, open **Settings → Identity verification** in the dashboard. The signing secret shows when it was last used: after a verified shopper loads a page, the badge changes from **Never used** to a recent time.

### Signing out

When the shopper signs out of your site, tell Remark to drop their verified status:

```javascript theme={null}
window.remark('unverify');
```

Call this from your sign-out handler. It works whether or not the shopper ever verified, so you don't have to track that yourself.

### Token reference

| Claim   | Required                 | Description                                                                                                                                  |
| ------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `email` | one of `email` / `phone` | The verified email address.                                                                                                                  |
| `phone` | one of `email` / `phone` | The verified phone number.                                                                                                                   |
| `sub`   | yes                      | The shopper's lead, from the `remark_lead` cookie. Binds the token to one session so a leaked token can't be reused against another shopper. |
| `exp`   | yes                      | Expiry, in Unix seconds. Keep it short, about 5 minutes. Remark rejects tokens that last much longer.                                        |

Remark normalizes the email and phone, so send real, well-formed values.
