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

# widget.visitor.identified

> A website visitor gave the widget their name, email or phone number.

Fires when a visitor gives the chat widget their contact details: by filling in
the widget's contact details form, or by answering a form in the widget that
asks for a name, an email address or a phone number.

## Payload

```json theme={null}
{
  "id": "whd_7Gx2dR5nM",
  "event": "widget.visitor.identified",
  "createdAt": "2026-09-11T13:05:02.884Z",
  "data": {
    "visitorId": "wv_5Hc2pR",
    "name": "Ada Lovell",
    "email": "ada@ravennafoods.com",
    "phone": null
  }
}
```

<ResponseField name="visitorId" type="string" required>
  The visitor. Always present.
</ResponseField>

<ResponseField name="name" type="string">
  The visitor's name as it stands after this submission, including one given
  earlier. `null` when they have never given one.
</ResponseField>

<ResponseField name="email" type="string">
  The visitor's email address, on the same terms as `name`.
</ResponseField>

<ResponseField name="phone" type="string">
  The visitor's phone number, on the same terms as `name`.
</ResponseField>

## Worth knowing

* **The details are self-reported.** They are whatever the visitor typed, and
  nothing checks them. Treat `email` as a lead rather than a verified address.
* **Every submission fires it**, including one that repeats details the visitor
  already gave.
* **A blank answer keeps the earlier value.** Only the details the visitor filled
  in are written, so a detail given earlier stays in the payload.
* **Verified visitors never fire it.** A visitor your site signs in through
  [widget visitor identity](/dev/api-reference/widget-identity) carries details
  your server vouched for, and the widget refuses to overwrite them from the
  visitor's side.
* **No conversation id.** The details belong to the visitor across all of their
  chats. Match `visitorId` against
  [`widget.conversation.started`](/dev/webhooks/events/widget-conversation-started)
  to connect the two.

## Example

```ts theme={null}
custral.on("widget.visitor.identified", async (event) => {
  const {visitorId, name, email} = event.data;
  if (!email) return;

  await marketing.upsertLead({
    email: String(email),
    name: name ?? undefined,
    source: "website-chat",
    visitorId,
  });
});
```


## Related topics

- [Widget](/dev/webhooks/events/widget.md)
- [Webhooks](/dev/webhooks/overview.md)
- [Event catalog](/dev/webhooks/events/overview.md)
- [Workflow Triggers](/automation/workflows/triggers.md)
- [Widget visitor identity](/dev/api-reference/widget-identity.md)
