Plenty has been written about each of these standards on its own. Almost nothing describes what happens when you use both, which is the configuration any real agent-to-agent transaction needs. They solve adjacent problems and the seam between them is where the interesting failures live.
Two standards, one transaction
ERC-8004 gives an agent an on-chain identity: a registry entry with a token id, an owner, endpoints, and a place to attach reputation and validation records. It answers who.
x402 gives a server a way to charge for a request: an unpaid call returns HTTP 402 with machine-readable payment requirements, the client settles, and the request is replayed. It answers how much and how.
Neither answers the other. x402 will happily take money from an agent nobody has ever heard of, and ERC-8004 will happily describe an agent that never pays for anything. A real transaction between two agents needs both, and the interesting part is what sits between them.
The order matters, and most examples get it backwards
The natural way to write the integration is: call the endpoint, get a 402, pay it, get the resource. Identity, if it appears at all, gets checked afterwards when you decide whether to trust what came back.
That is the wrong order for anything that costs real money. By the time you have paid, the only question left is whether you were right to, and a settled stablecoin transfer has no undo.
The correct sequence is: resolve the counterparty first, decide whether to transact, and only then satisfy the 402. Identity is a precondition of payment, not a post-hoc audit of it. This sounds obvious written down and is routinely the other way round in practice, because the 402 is what the code hits first and it is easy to let control flow dictate order of reasoning.
What the 402 challenge tells you about the payee
An x402 challenge names a `payTo` address, a network, an asset and an amount. That address is the seam.
The question nobody asks is whether the address in the challenge belongs to the agent you think you are buying from. Nothing in x402 asserts that, and nothing in ERC-8004 automatically binds a registry entry to the address a server happens to put in a 402 response.
So the check that matters is: does the `payTo` in this challenge match the address the counterparty proved control of on-chain? If a server can be persuaded to serve a 402 with someone else's address in it, or if an agent's registry entry lists an address it never proved it holds, the payment goes to the wrong place while every individual component behaves exactly as specified.
This is why KYA, the attestation that an agent controls the wallet it claims, is not a nicety. It is the thing that makes the seam load-bearing.
The identifier problem
ERC-8004 identities can be referenced several ways: a token id like `#849980`, a CAIP identifier like `eip155:5042002:8004/849980`, or the owner's `0x` address. All three resolve to the same agent.
That flexibility is convenient and it is also a place bugs hide. Code that compares identifiers as strings will decide that `#849980` and its CAIP form are different agents, and code that treats the owner address as the identity will merge two agents that share an owner.
Normalise to one canonical form at the boundary of your system and compare only that. An agent identity is not a string, and treating it like one works right up until an operator registers two agents from the same wallet.
Chains do not have to agree
Here is the part that catches people building their first cross-chain flow: the chain where identity lives and the chain where money moves are not required to be the same chain, and frequently are not.
An agent can hold an ERC-8004 registration on one network and settle x402 payments on another. Our own trust oracle does exactly this: identity reads against Circle Arc, settlement on X Layer.
Nothing is wrong with that, but it means your verification and your payment are two different chain reads against two different sources of truth, and they can disagree. An identity revoked on one chain does not automatically stop a payment settling on another. If your risk logic assumes both facts came from the same place, it will be confidently wrong at exactly the wrong moment.
Reputation has to be computed over payments, not claims
ERC-8004 has a reputation registry, which standardises how feedback gets recorded. It does not make that feedback true. Anyone can attest anything about anyone, and a registry entry full of glowing attestations from addresses nobody has heard of is worth precisely nothing.
The useful signal is on the x402 side: settlements. A payment is a claim somebody backed with money, which is a materially different kind of evidence from a rating.
So the practical build is to compute reputation from settlement history rather than from attestations, and use the reputation registry as a place to publish the result rather than as an input. That is the direction the two standards compose in: x402 produces the evidence, ERC-8004 gives it somewhere to live.
What a complete flow looks like
Resolve the counterparty from its identifier, normalised. Confirm it holds a registration and that KYA proves control of the wallet in question. Compute or fetch reputation over settled payments, not attestations. Size the risk to the amount you are about to send, not in the abstract. Check the payment against your own spending limits, which is a separate question from whether the counterparty is sound. Only then satisfy the 402, confirming that `payTo` matches the address you verified.
Six steps, of which x402 covers the last one and ERC-8004 covers parts of the first two. Everything between is the layer neither standard specifies, which is precisely why it is worth being deliberate about.
Trying it
A-Identity implements the middle of that flow as pay-per-call endpoints, and is itself an ERC-8004 agent paid over x402, so the whole loop is dogfooded rather than described.
`trust_preview` is free and needs no key, so you can see the shape of a verification result before wiring anything. The scoring method is published and the settlements behind it are listed with their transaction hashes.