# Claimed vs Verified: What ERC-8004 Agent Identity Evidence Actually Proves Before an x402 Payment

> Source: <https://contextiq.trango-compute.com/blog/erc8004-claimed-vs-verified-agent-identity-policy-check-scoring>
> Published: 2026-10-02 00:00:00+00:00

# Claimed vs Verified: What ERC-8004 Agent Identity Evidence Actually Proves Before an x402 Payment

What ERC-8004 agent identity evidence proves: on-chain getAgentWallet, ENS/DID/email linkage claimed vs verified, and .well-known ownership, before an x402 payment.

An ERC-8004 registration answers one question: *did someone mint an agent identity?* It doesn't answer the question an agent about to sign an x402 payment actually has: *is the party behind this endpoint who they say they are?* Those are different claims with different evidence, and a scoring system that blurs them hands out trust it hasn't earned.

This post describes how ContextIQ's [Policy Check](https://contextiq.trango-compute.com/policy-check) and [ERC-8004 Inspector](https://contextiq.trango-compute.com/erc8004-inspector) keep them apart. Every identity signal is labelled **verified** or **claimed**, and endpoint ownership is checked against the domain itself. If you're new to the standard, start with [What Is ERC-8004?](https://contextiq.trango-compute.com/blog/what-is-erc-8004-ethereum-trustless-ai-agent-identity).

## The Problem: Registration Is Cheap

Minting an agent ID on the ERC-8004 Identity Registry costs gas and nothing else. The registration file the token points to is self-authored: the registrant chooses the `name`, the `services`, and whether to list an ENS name, a DID, or an email address. Anyone can list `research-agent.eth` without owning it.

So an identity check that only asks "is there a registration, a wallet and a filled-in metadata file?" mostly measures *effort to look legitimate*. It rewards all of it whether or not any of it was independently checked.

The fix isn't to distrust everything. It's to record, for each signal, *who vouches for it*.

## Three Kinds of Evidence

### 1. Agent wallet: authoritative, read from the chain

The payment wallet comes from the Identity Registry's `getAgentWallet(agentId)`, not from the registration file. The EIP states that `agentWallet` is reserved, can't be set through `setMetadata()`, and is automatically cleared when the agent NFT is transferred, so the new owner must re-verify it.

That last property matters: a wallet that was valid for the previous owner can't silently carry over. The Inspector reports exactly what the call returned:

| `agentWalletEvidence.status` | Meaning | 
|---|---|
| `verified` | `getAgentWallet` returned a non-zero address (`isAuthoritative: true` ) | 
| `zero_address` | The call succeeded and returned `0x000…` — no wallet set, or cleared by a transfer | 
| `missing` | The call reverted | 
| `unknown` | The RPC request itself failed, so the chain was never actually asked ( `isAuthoritative: false` ) | 

The `unknown` case is the one that's easy to get wrong. Treating a failed RPC call as "no wallet" would penalize an agent for an infrastructure hiccup.

Policy Check also uses the wallet as a cross-check. The `agentId` you supply identifies the agent being *paid*, the seller behind the endpoint, so the wallet is compared with the address the 402 challenge actually asks you to pay. An endpoint could otherwise present a legitimate agent's identity while requesting payment to an unrelated address. A mismatch is surfaced as a warning rather than a block, since a treasury address or a payment splitter is a legitimate reason for it.

### 2. Human linkage: declared is not verified

Registration files commonly declare `ENS`, `DID`, `email` and `web` entries under `services` (older files used `endpoints`; both are read). ContextIQ parses these and reports them as:

```
{
  "humanLinkage": {
    "status": "claimed",
    "confidence": "medium",
    "sources": [
      { "type": "ENS", "value": "research-agent.eth", "verification": "declared", "weight": "weak" },
      { "type": "DID", "value": "did:web:research-agent.example", "verification": "declared", "weight": "weak" }
    ],
    "summary": "Agent declares ENS and DID, but no external proof-of-human signal was verified."
  }
}
```

The rules are deliberately strict:

- ENS, DID, email and web values are **claimed** linkage. We don't resolve the ENS name or the DID document, so they stay`declared` .
- Confidence is `low` for one declared type and`medium` for two or more. It never reaches`high` from self-declared data.
- `externally_verified` is reserved for evidence that is actually checked: a World ID or Self proof, an Icebreaker credential, or an EAS attestation.**No verifier exists yet, so nothing emits that status today.** The type is in the response so the shape won't change when one ships.
- Malformed values (an "ENS" entry that isn't a `.eth` name, a "DID" without a`did:` prefix) are ignored rather than counted.

### 3. Endpoint ownership: the domain vouches for the agent

The ERC-8004 spec defines an endpoint domain verification file. A domain that serves an agent's endpoint publishes `https://{endpoint-domain}/.well-known/agent-registration.json`:

```
{
  "registrations": [
    {
      "agentId": 22,
      "agentRegistry": "eip155:8453:0x8004A169FB4a3325136EB29fA0ceB6D2e539a432"
    }
  ]
}
```

Only whoever controls the domain can serve that file, so a matching entry ties the on-chain agent to the party operating the endpoint. Policy Check fetches it from the endpoint's own origin (SSRF-guarded) and returns one of four results:

| `endpointOwnershipEvidence.status` | When | 
|---|---|
| `verified` | The file lists this `agentId` on this registry | 
| `mismatch` | The file lists *other* agents on this registry but not this one | 
| `unverified` | No file, unreadable file, redirect to another domain, or the agent appears only on a different chain | 
| `not_checked` | No endpoint to check | 

Two details are worth stating. A missing or unreachable file is `unverified`, never `mismatch`: a domain that doesn't publish the file isn't contradicting anything. And a redirect to a different domain is ignored, since otherwise a third party could vouch for the endpoint. A `tokenURI` hosted on the same domain is noted as corroboration but doesn't count as verification, because the registrant can point the URI anywhere.

## How the Evidence Feeds the Decision

Policy Check combines two kinds of input into one pre-payment decision: checks on the x402 endpoint's 402 challenge, and, when you supply an `agentId`, the evidence about the agent behind it. Each check is reported by name in the `reasons` list, so a decision can be traced to what produced it.

A few properties are worth stating:

- **Verified evidence counts for more than claimed evidence.** A self-declared ENS name or email is credited far less than an on-chain read or a domain-published registration, and unverified proof-of-human signals earn nothing.
- **Hard failures still block.** A malformed challenge, an unreachable endpoint, or an agent ID that isn't registered blocks the payment regardless of how strong the identity evidence is.
- **Weak identity behind a valid payment is a warning, not a block.** Whether an unproven agent is acceptable is the caller's judgment, so Policy Check says "look closer" rather than deciding for them.
- **Mismatches are surfaced as warnings.** If the endpoint's domain vouches for a different agent than the one you supplied, or the challenge pays an address that isn't the agent's own wallet, the agent and the endpoint may not belong together. That is a strong signal rather than proof of fraud.
- **No `agentId` means identity isn't evaluated.** The response says`not_evaluated` instead of substituting a default agent, and only the payment checks run.

The weighting behind these checks is not published and may change between releases. Treat the decision and the per-check reasons as the interface, and apply your own policy on top.

## What Changes in the API Response

The request is untouched: `{ "endpoint", "agentId"?, "network"? }`. The response gains fields, and `reasons` keeps its shape.

```
{
  "decision": "allow",
  "rubricVersion": 2,
  "trustEvidence": {
    "agentWallet":       { "status": "verified" },
    "humanLinkage":      { "status": "claimed", "confidence": "medium" },
    "endpointOwnership": { "status": "unverified" },
    "payTo":             { "status": "matches" }
  }
}
```

- `trustEvidence` summarizes each dimension, and reads`not_evaluated` when no`agentId` was supplied.
- `reasons` gains checks for human linkage, endpoint ownership and the payment address, and`agent_wallet_set` is now`agent_wallet_verified` .
- `rubricVersion` records which scoring version produced a result, so a stored decision can be read against the right one.
- The ERC-8004 Inspector response adds `agentWalletEvidence` ,`humanLinkage` ,`endpointOwnershipEvidence` and`trustEvidenceSummary` .

In the UI, each signal carries one of these labels: **Verified**, **Claimed**, **Unverified**, **Missing** or **Mismatch**, plus **Not evaluated** when nothing was checked. "Claimed" is a different color from "Verified" on purpose.

## What This Doesn't Prove

- **Ownership isn't personhood.** A verified`.well-known` file shows the endpoint's operator registered the agent. It says nothing about whether that operator is a person, a company, or a bot.
- **ENS and DID aren't resolved.** Claimed means claimed. Resolving and verifying them, and checking EAS, Icebreaker, World ID or Self proofs, is where`externally_verified` would come from.
- **DNS races remain.** The runtime resolves DNS itself, so a record could change between the safety check and the fetch. Checks and redirect re-validation reduce this but can't pin the IP.
- **It's a signal, not a verdict.** ERC-8004 is a draft standard, and strong evidence means the identity is better supported, not that a payment is safe.

To see these fields for a real agent, look one up in the [ERC-8004 Inspector](https://contextiq.trango-compute.com/erc8004-inspector), or run the combined check with an agent ID and an x402 endpoint in [Policy Check](https://contextiq.trango-compute.com/policy-check). For what to verify on the payment side of the decision, see the [x402 payment checklist](https://contextiq.trango-compute.com/blog/x402-payment-checklist-what-ai-agents-verify-before-signing).

Follow Trango Compute on LinkedIn

We post updates on new tools, context engineering patterns, and LLM cost research.

[Follow on LinkedIn](https://www.linkedin.com/company/trango-compute)
