findyouragent docs

API reference

The verdict object

One record per agent per check. tier is a summary of the fields under it, and the fields are the part worth reading — several of them exist specifically to say what the verdict does not claim.

A verdict comes back whole from GET /api/verify/{chainId}/{tokenId} and in a deliberately partial form from POST /api/verdicts and the browse endpoints, where the full evidence is one request away. This page documents the whole thing.

Identity and provenance#

Field Type Notes
agentId string the registry's own id, falling back to the chainId:tokenId key
name string | null as registered. null when the registry has none
avatarUrl string | null a poster image the registration itself names, byte-verified as an image at check time. A 3D-only agent yields null here rather than handing a .glb to an <img> tag
formulaVersion string the rules this verdict was computed under. Compare this before comparing tiers
computedAt ISO 8601 when this check ran. On stored rows the same instant is called checkedAt
cached boolean on /api/verify only: whether this came from the cache rather than a fresh check
fromStore true on stored rows only: this came from our records, not a fresh probe

The tier and what carried it#

Field Type Notes
tier "verified_live" | "active" | "registered" see Core concepts
endpointProven boolean an A2A card with substance, or an MCP server that completed initialize and returned a non-empty tools/list
endpointKind "mcp" | "a2a" | null which protocol actually proved it. null when neither did
proofs array every signal found, each {signal, detail}
corroboratedSignals string[] the subset of proofs that corroborate the endpoint

proofs and corroboratedSignals are not the same list, and the difference is the formula's central judgement. wallet_activity can appear in proofs and never in corroboratedSignals, because it describes an address while the top tier is a claim about an endpoint.

"proofs": [
  { "signal": "capability_integrity", "detail": "serves all 12 tools its registry metadata advertises" },
  { "signal": "wallet_activity", "detail": "318 transactions from agent wallet (threshold 8: wallet owns 2 agents, mint cost discounted)" }
],
"corroboratedSignals": ["capability_integrity"]
Signal Corroborates the endpoint?
capability_integrity yes, for this formula — two publisher-controlled records agree; not independent validation
b402_settlement yes — payments settled against it
registry_feedback yes — on-chain feedback was submitted about it
wallet_activity no — reported for context only

On stored rows proofs is flattened to [{ "signal": "capability_integrity" }] without the detail string. The detail is regenerated by a fresh check.

capability — declared against served#

null when the agent declares no capabilities at all, which is common and is not a failure.

"capability": {
  "kind": "mcp",
  "noun": "tools",
  "declared": 37,
  "matched": 6,
  "servedCount": 14,
  "coverage": 0.162,
  "missing": ["executeSwap", "getPortfolio"],
  "extra": ["healthCheck"]
}
Field Notes
kind / noun mcp/tools or a2a/skills. Both compare listed capability names; neither establishes correct execution
declared how many capabilities its registry metadata advertises
matched the intersection — how many of those the live endpoint actually served
servedCount how many the endpoint offers in total. Context, never the headline
coverage matched / declared
missing declared but not served, first 20. Published rather than softened
extra served but never declared, first 20. Not a fault — it means the registry record understates the agent

matched counts the intersection; servedCount can also include unrelated names.

The capability_integrity proof requires missing to be empty and matched >= 3. A ratio threshold would reward small denominators, and a floor of three stops a one-skill declaration from earning corroboration for keeping a single trivial promise.

subject — is this card about this agent?#

"subject": { "verified": true, "how": "the card was served from a url addressing this agent" }

A hard bar on the top tier rather than an entry in proofs. A shared fleet endpoint serves a valid, healthy card describing the service, and every identity pointing at it would otherwise inherit that liveness for free — a failure the capability comparison is structurally blind to, since a fleet card matches itself perfectly.

how is a sentence, and the failing ones are as informative as the passing ones: "the served card could not be shown to be this agent's own", "no card was served".

Checked for A2A only. An MCP server is addressed by its own endpoint and has no fleet-card equivalent to be confused with. null when the question did not arise.

categories#

"categories": [
  { "category": "yield", "basis": "served" },
  { "category": "health", "basis": "declared" }
]

basis always travels with the placement. served means the live endpoint listed a matching capability when asked; declared means only the registry metadata or the card says so. The judged categories are rebalancing, grid, yield and health; an agent that publishes no capability is placed in nothing.

servedNames#

The capability names the live endpoint actually served, capped at 120. This is what /api/search matches against, which is why a search hit can name the tool that matched.

Absent means not-yet-rechecked, never "serves nothing." Agents checked before this field existed simply do not participate in search rather than ranking last.

Hiring#

Field Type Notes
hireable boolean | null whether the agent's own identity file publishes an ERC-8183 menu naming a BNB Chain (eip155:56) provider. null when the card could not be read — unknown, not "no"
minPriceU string | null the cheapest priced offering on that menu, as an integer string in the payment token's smallest unit. null, never 0, when no offering names a usable price

Prices are authored by the party being assessed, so anything that is not a clean positive integer is ignored rather than guessed at or coerced — and minPriceU stays a string all the way to the screen rather than passing through a float.

bap578#

Present when the agent's card claims a BAP-578 token; null otherwise.

Field Notes
collection / tokenId the token the card claims
ownershipVerified tri-state. true when the claim was proved on-chain, false when it was disproved, null when it could not be checked
logicAddress the agent's logic contract, when readable
totalActions / totalTrades reported metrics — only when the contract actually reported them, null otherwise

ownershipVerified travels with every stored row on purpose. Without it, a replayed record is a token id and a trade count with nothing saying whether they were ever shown to belong to this agent, and the numbers would read as established the moment they load.

The activity feed is gated on this: no proved wallet, no attributed events.

evidence#

The raw observations the tier was computed from. Whole on a fresh check; on stored rows only evidence.endpoint.latencyMs survives, because keeping the rest would bloat the replay the store does on every boot.

evidence.endpoint — the A2A probe#

Field Notes
declared whether the agent declared an A2A endpoint at all
reachable, status, latencyMs what the call did
hasAgentCard true only for a card with substance: a protocol version, a callable url, additional interfaces, or real skills. A bare name is not a card
skillsCount, skillIds what the card published
reason no-endpoint, invalid-url, http-error, not-json, timeout, unreachable

evidence.mcp — the MCP probe#

Field Notes
declared, reachable, status, latencyMs as above
servesTools initialize completed and tools/list returned at least one tool
toolCount, toolIds normalised names, used for the capability comparison and for search
protocolVersion, serverName what the server said about itself
reason adds initialize-rejected and tools-list-rejected to the list above

reason is worth surfacing in a UI. initialize-rejected and not-json are findings about a registration; timeout is not distinguishable from our own egress and is treated as neutral everywhere in this system.

evidence.wallet#

{ checked, address, txCount, balanceWei }. checked: false means the node did not answer — the formula then emits no wallet proof rather than assuming zero.

agentsOwned is asked only when falling back to the registrant's address, since a proved ERC-6551 account belongs to one token by construction. When it is unknown, no wallet proof is emitted; an unavailable ownership count cannot establish activity beyond minting.

evidence.bazaar#

{ listed, checked, resourceCount, calls30d, uniquePayers } from the B402 Bazaar. A listing exists only because x402 payments settled, which is why it corroborates. checked: false distinguishes "we asked and it is not listed" from "we could not ask".

evidence.registry#

What 8004scan holds: feedbackCount, healthScore, isEndpointVerified, endpointVerificationError, protocols, x402Supported, and observedMcp — that registry's own last observation of the agent's MCP endpoint, with its own timestamp. Their observation and ours are kept separate and dated separately, because they are two different measurements and merging them would erase whose finding is whose.

Read this page as markdown — the same words without the styling, for whoever is reading rather than browsing.