> ## Documentation Index
> Fetch the complete documentation index at: https://fdbad6a-heedeo-e1965c.manicule.dev/llms.txt
> Use this file to discover all available pages before exploring further.
> For every page in one file, fetch https://fdbad6a-heedeo-e1965c.manicule.dev/llms-full.txt (large).
> To search and read these docs as tools, connect the MCP server at https://fdbad6a-heedeo-e1965c.manicule.dev/api/mcp.
> Every agent surface: https://fdbad6a-heedeo-e1965c.manicule.dev/.well-known/llms-manifest.json

# 10. Ask about a visitor (/ask-about-a-visitor)

<!-- agent-signals: reading_time_min: 3 · est_tokens: 1033 · updated: 2026-11-11 -->
Related: [Integrating Heedeo](/index.md), [Connect your app](/connect-your-app.md), [1. Quick start](/quick-start.md), [2. Serve Heedeo from your own domain (do this before you go live)](/serve-heedeo-from-your-own-domain.md), [3. One server call: evaluate or log](/one-server-call.md), [4. The fields to act on](/the-fields-to-act-on.md)

Between events, your server can ask what a visitor stands at now: `GET /v1/visitors/<visitor_id>` with the secret key; an id a merge retired answers the visitor it joined, with `visitor.merged_into` set. `DELETE` on the same address deletes the person (section 7, Deleting a person). `risks` is what is known about the person now, per question, with trust counted: `risks.account_abuse.score` and its reasons. It is not a verdict on any action: decide at the action, from its event. It uses your current settings, so a change shows on the next lookup.

```sh
curl -s -H "authorization: Bearer $HEEDEO_SECRET_KEY" https://app.heedeo.com/v1/visitors/8855…
```

The answer: `visitor` (`id`, `first_seen`, `last_seen`, `emails` and `accounts` over 24h, 7d and all time, `addresses` and `countries` over 1h, 24h and 7d, and as on an event `confidence`, `browsers` with what placed each and its `evidence`, `aliases` and `actions`), `listed` (your label on the visitor), `network` (the newest event's, with the fields section 4 describes, which an event older than a field lacks; `null` when no event is kept), `environment` (the newest identification's, as section 4 describes it; `null` without one), `risks` (above), `score` (`risks.account_abuse.score`), `thresholds` (`verify`, `review`, `block`: your workspace's), `suggested` (the band `score` reaches at your thresholds; kept for packages before pilot.18, which require it, and no verdict on the person), `trust` (each trust reason that holds, with its negative `weight`; the strongest counts), `related` (current links, as section 4 describes them: the same list the last event answered, unless links were made since), `outcomes` (`kind`, `outcome`, `label`, `created_at`), `visitor.actions` (as section 4) and `recent`, the visitor's newest 50 actions (`action`, `at`, `browser_id`, `suggested`, `outcome`), the newest first. With the package: `await heedeo.visitor(visitorId)`, the same `{ data, error }` shape. A visitor that is not yours answers 404. A lookup needs no event of its own.

## What Heedeo answered for an event

When a person writes in to say they were refused, the `event_id` in your log line is enough to see why. `GET /v1/evaluations/<event_id>` with the secret key answers that event's answer again: the body `evaluate()` received, read in your API version (section 3), so `related[]` holds what your version reads. `flagged` and `no_token` come first, then `answered_at` (when Heedeo gave it) and `action` (what it was for), then the rest; the other fields can come in another order than the first answer's. An event `logEvent()` sent reads back the same way.

```sh
curl -s -H "authorization: Bearer $HEEDEO_SECRET_KEY" https://app.heedeo.com/v1/evaluations/79c7…
```

It is history, not a decision now. `flagged`, `listed` and the reasons are what they were at the event, so a label you put on since does not change them, and nothing should be refused or let through on it later: send the new action as its own event, which reads every label of yours (the person's, their email's, their network's). `GET /v1/visitors/:id` (above) shows the person's own label only, so a Trust on their email or network is not in it, and a signup with no token has no visitor to read. An answer is kept 30 days, or as long as a flag holds its event (Review shows it), and deleted with its visitor (section 7). Past that, another workspace's id, an id that is no event's (a visitor's) and a malformed one each answer the same 404 `not_found`. Its `related[]` is as it was too: a neighbour deleted since is still named there, as section 7 says of answers about other people. A read is not an event: it records nothing and counts towards nothing.

With the package (0.2.0-beta.1 or later), `await heedeo.evaluation(eventId)` answers `{ data: { answeredAt, action, verdict }, error }`: `verdict` is the verdict `evaluate()` gave then, so `verdict.toLog()`, `has()` and `certain()` read it as they read the first one, under a name that says it is past. A miss is an `api_error` with `apiCode` `not_found`. From an AI assistant, `get_evaluation` answers the same (section 11).
