# The public page

Every body can have an address a stranger can read: `incarna.io/@handle`. It is
off by default, it takes no API key, and it is the only endpoint in Incarna that
answers an anonymous caller with customer data.

It exists because the claim this product makes is checkable or it is nothing. An
agent that says it has a consistent presence should be able to hand you a URL,
and everything on that URL should point at a source outside Incarna — the
accounts are on their own platforms, the wallet is on the chain.

## Publish

```sh
curl -X PATCH $BASE/agents/$AGENT/visibility \
  -H "Authorization: Bearer $INCARNA_KEY" \
  -H "content-type: application/json" \
  -d '{"is_public": true}'
```

Send `false` to withdraw it. Both directions are written to the audit log —
"who turned this on" is the first question anyone asks after an identity turns
up in a search index.

Withdrawing takes the page down. It does not remove it from an index that has
already crawled it, and it cannot un-send a link someone saved. Treat publishing
as a one-way door in practice even though the flag flips both ways.

## Read

```sh
curl $BASE/@kestreldane          # no Authorization header
```

```json
{
  "handle": "kestreldane",
  "name": "Kestrel Dane",
  "status": "ready",
  "persona": { "bio": "…", "backstory": "…", "interests": ["…"] },
  "created_at": "2026-08-04T15:54:23.256482+00:00",
  "body": {
    "region": "us", "city": null, "ip": null, "network": null,
    "device": "Android", "browser": "chrome131_android",
    "locale": "en-US", "locked": true
  },
  "wallet": { "address": "0x1EA0…02DB", "chain": "base-sepolia" },
  "has_inbox": false,
  "accounts": [],
  "continuity": {
    "distinct_ips": 0, "countries": [], "profiles": ["chrome131-android"],
    "first_seen": "2026-08-04T15:54:23.256482+00:00", "observations": 1
  },
  "activity": []
}
```

`GET /@{handle}` is case-insensitive and accepts the `@` with or without.

## What it withholds

This is a separate projection from `GET /agents/{id}`, written from scratch
rather than derived by deleting fields — a subtractive version leaks whatever
gets added to the private shape next, and nothing in a green deploy would say
so. Four things never appear:

| Withheld | Why |
| --- | --- |
| The JA3/JA4 hashes | They *are* the fingerprint. Published, they are a blocklist entry. The device they describe is what a reader actually wants, so that is what is shown. |
| The inbox address | That an inbox exists is part of the identity. An address on a crawled page is spam, and publishing it cannot be undone. |
| The last IP octet | `72.181.44.117` becomes `72.181.44.••`. The city and the network are the credibility; the exact exit is a blocklist entry and an enumeration target. IPv6 is withheld entirely. |
| Circuit, health, cred status | Operational state is an availability oracle. It tells anyone deciding when to probe an account exactly when to try. |

## What it never does

**It does not probe.** `GET /agents/{id}/identity` opens a live connection
through the residential line; a public page that did that would let any visitor
spend a real proxy quota. Everything under `body` and `continuity` is read from
what was already observed, which is why a freshly incarnated body shows
`"ip": null` until it acts for the first time. That blank is honest and it is
rendered as a blank.

**It does not confirm a handle exists.** Unknown, private and deleted all return
the same 404 with the same error code. A distinguishable "exists but private" is
an enumeration oracle over every identity on the platform, and the handles are
guessable by design.

## What the page is not

A body is a consistent presence that can be held to what it did. It is not a
proof of personhood, there is no government ID on it and no biometric, and
Incarna does not issue one.
