Register an agent, and rate one, without paying gas
Identity and reputation on 12 mainnets and 9 testnets with every fee on us — including the two paths where the rating stays yours instead of ours.
Where it runs
Read from GET /register when this page loads, never typed here:
The authorship problem, said out loud
On the plain path, the facilitator is the author of your rating.
A registry records msg.sender as the rater, and on POST /feedback that is us. Whatever name you put in the body, the chain says the facilitator said it. Reputation written that way is worth exactly as much as trusting the facilitator, which is not what any of this is for.
So there are two paths where the rater signs for themselves, and the facilitator only pays:
| path | how the rater stays the author | where |
|---|---|---|
POST /feedback/evm/preparePOST /feedback/evm/submit |
EIP-7702: the rater delegates their EOA to a feedback delegate and signs a digest; we send a type-4 transaction to the rater's own address, so the registry sees the rater as msg.sender |
only where a delegate is deployed and verified on chain — today base-sepolia alone. Mainnet waits on that deploy, and the table lives in the code rather than in this sentence |
POST /feedback/solana/preparePOST /feedback/solana/submit |
a partially-signed transaction: the rater signs as client, the facilitator stays fee payer only |
submit refuses any transaction that is not byte-for-byte the one it built |
Feedback has to have been paid for
A rating that anyone can write is a rating anyone will write. Every feedback carries a proof of payment, and the server checks all of it: the transaction exists on that network and succeeded, sits in the block the proof claims, contains a transfer of exactly that amount of that token from payer to payee, the payer is the rater, the payee is an address the identity registry ties to the agent, the block timestamp is inside the freshness window, the hash recomputes, and that (payment, agent) pair has not been spent before.
Two verdicts never block a write, in either phase. If the RPC could not be reached there is no verdict — our outage must not erase somebody's reputation. And the Solana path has no EVM receipt to read, so enforcing a check that never ran would quietly switch Solana reputation off. A gate that fails closed on its own blind spots is a gate that deletes data.
Two things that trip real integrations. Most agents have no wallet set on the registry — measured on Base, six agent ids in a row all read 0x0 — so ownership is read from ownerOf as well, and both are accepted. And a marketplace payment usually carries two transfers, a fee and the net to the agent: the proof must declare the net the payee actually receives, or the gate cannot find it.
Why an owner lookup can answer 503
There is no index behind it, and that shapes everything. The registries expose no owner-to-agent mapping, they are not enumerable — totalSupply() reverts on every deployed registry, verified on chain — and at least one chain caps log queries at 2000 blocks. So a cold lookup derives the highest agent id and scans ownership through Multicall3.
404and503are different answers and must not be collapsed. 404 is "this address owns no agent". 503 is "the lookup reached no verdict", and it saysretryable. Persisting a 503 as "not registered" is how a transient RPC failure becomes a permanent wrong answer — and on a registration path it mints a second identity for somebody who already had one.- A non-zero balance with no token found is a contradiction, not a miss. It means the scan range was wrong. It answers 503, and
POST /registerrefuses to mint on it. - The scan has a ceiling and it is visible. Base held 83,984 agents against the 192,000 the scan can walk, measured 2026-09-01; the service warns from 75% of the cap and answers 503 past it. The fix at that point is an owner index, not a bigger number.
- A registration that timed out is not a registration that failed. The mint may still land. Read it back before retrying.
Solana is not a port of the EVM path
It is a different program with its own account layouts, and three things bite. The config address is two hops, not one — a root config holds the collection and the collection seeds the registry config; the legacy single-seed derivation points at an address that was never initialised. Feedback submitted without a score is recorded and never scored: reputation stays at zero however much accumulates, and it is not retroactive. And the program forbids self-feedback, so an agent minted without a recipient stays with the facilitator, which then cannot rate it — which is why registering with a recipient mints, initialises the stats and transfers, in that order.
Reading it back
The routes
| Method | Route | What it answers | Moves money |
|---|---|---|---|
GET |
/register |
Registration endpoint schema, supported networks, and request format | no |
POST |
/register |
Register a new ERC-8004 agent on-chain. Facilitator pays gas. Supports optional recipient field to mint the NFT and transfer it to a user address |
no, but we pay gas |
GET |
/identity/:network/:agentId |
Get agent identity: owner address, registration URI, and payment wallet | no |
GET |
/identity/:network/:agentId/metadata/:key |
Read a specific metadata key from the agent's on-chain profile (returns hex + UTF-8) | no |
GET |
/identity/:network/total-supply |
Get total number of registered agents on a network | no |
GET |
/feedback |
Feedback submission schema and supported networks | no |
POST |
/feedback |
Submit on-chain reputation feedback (giveFeedback) | no, but we pay gas |
POST |
/feedback/revoke |
Revoke previously submitted feedback | no, but we pay gas |
POST |
/feedback/response |
Append agent response to feedback | no, but we pay gas |
GET |
/reputation/:network/:agentId |
Query aggregated reputation summary with optional tag filtering | no |
GET |
/identity/{network}/owner/{address} |
which agent an address owns — the lookup with no index behind it. 404 is "owns none"; 503 is "the lookup reached no verdict" and carries retryable: true. Persisting a 503 as "not registered" is how a transient RPC failure becomes a permanent wrong answer |
no |
GET |
/register/status/{jobId} |
poll an async registration: pending then mint_confirmed then done or failed. Terminal jobs age out after an hour |
no |
Gasless registration: The facilitator wallet pays all gas fees. Without recipient, the NFT stays with the facilitator. With recipient, the NFT is minted then transferred via ERC-721 safeTransferFrom (2 transactions, both paid by facilitator). Note: agentWallet is cleared on transfer and must be re-set by the new owner.
21 networks: ethereum, base, polygon, arbitrum, optimism, celo, bsc, monad, avalanche, scroll, skale, solana + testnets. CREATE2 (EVM) + Agent Registry program (Solana).
This is not describe.net, and the difference matters
describe.net is a different product that also reads ERC-8004. It is a cross-chain index: it scans every chain's registry events, resolves who owns each agent now rather than who minted it, applies one versioned aggregation policy, and answers a reputation question with a score and its composition. It charges for that work.
This facilitator is the other half. It is a gateway: it writes to one registry at a time and reads one registry at a time, live, for free, and it computes no score. There is no aggregation policy here, no cross-chain view and no ranking — /reputation/{network}/{agentId} hands back what that one registry says and stops.
So the two can disagree, and neither is the other's authority. They answer different questions. Do not treat a number from here as an index-wide score, and do not treat an index score as what a specific registry will say on the next block. And one warning worth borrowing from their measurements rather than restating as ours: an agentId alone identifies nobody. The same id exists on every chain with more agents than that number, and it belongs to different people on each — of 26,736 ids present on two or more chains, they measured zero with the same owner across all of them. The strong key is the wallet.