Skip to content
· 6 min LIVE

Listed, Not Listed: Putting AgentBadge on Circle's Agent Services Marketplace — and Telling Machines the Truth

We submitted the Agent-Readiness Scan to Circle's Agent Services Marketplace — POST /api/total-scan, x402-paid, USDC on Arc via EIP-3009 transferWithAuthorization. While the listing sits in pending_review, every machine-readable surface we own (llms.txt, skill.json, /.well-known/agentbadge.json, Organization JSON-LD) already declares it with the honest status — and the settle telemetry was shipped before the first sale.

AB
AgentBadge Team
Agency for the Agentic Web
Listed, Not Listed: Putting AgentBadge on Circle's Agent Services Marketplace — and Telling Machines the Truth
🤖 For AI agents: Machine-readable: JSON Markdown llms.txt Agent Guide

We submitted our Agent-Readiness Scan to Circle's Agent Services Marketplace — POST /api/total-scan, x402-paid, USDC on Arc via EIP-3009 transferWithAuthorization. Before the listing is approved, every machine-readable surface we own (llms.txt, skill.json, /.well-known/agentbadge.json, Organization JSON-LD) already declares it — with the honest status pending_review, not listed. The submission took an afternoon; the discipline was deciding that our metadata tells machines what's true today, not what we hope is true tomorrow. And because a listing is worthless if the first sale is silent, we shipped the observability pack first: settle-failure alerts, a revenue ledger endpoint, and revenue in the daily ops digest.

Agents don't browse your website. They query an index.

A human finds a service on a marketplace page. An agent finds it in a machine-readable index — in Circle's case, GET https://api.circle.com/v2/x402/discovery/resources. That endpoint is the actual storefront: 2,650 resources when we checked, each carrying its accepts[] payment terms and provider metadata. The HTML catalog is a rendering of it, not the other way around.

So the question "are we listed?" has a precise, checkable answer — and today it's no:

curl -s 'https://api.circle.com/v2/x402/discovery/resources?query=total-scan' \
  | jq '.items[].resource'
# → empty while pending_review

One caveat we hit immediately: ?query= matches fuzzily — agentbadge returned anchor-x402 on an "agent" substring. The reliable check is the resource URL or your payout wallet in accepts[].payTo, not the name.

What we submitted

FieldValue
ServiceAgentBadge Agent-Readiness Scan
EndpointPOST https://agentbadge.xyz/api/total-scan
Paymentx402, USDC on Arc (eip155:5042002), EIP-3009 transferWithAuthorization
Flowagent hits endpoint → 402 with price → signs authorization → gets the scan

No API keys, no accounts, no custodial anything. The buyer is an agent; the payment is a signed authorization the facilitator settles on-chain.

Sequence diagram of the listing lifecycle and the buyer flow: operator submits the service to the marketplace form; the Discovery API index stays empty while status is pending_review; once approved the item is indexed and a buyer agent can browse the catalog, hit POST /api/total-scan, get a 402 with price/payTo/network, retry with a PAYMENT-SIGNATURE carrying the EIP-3009 authorization, the facilitator settles USDC on Arc, and the endpoint returns 200 with the scan report
The loop, end to end: form → review → index → agent → 402 → settle → report.

The honest-status decision

Here's the part we almost got wrong by convention. Once we added the marketplace to our machine-readable surfaces, the natural status to write was listed. It will be true eventually — probably. But today it isn't, and an LLM agent reading our llms.txt or skill.json has no way to know that "listed" means "we submitted a form."

So a single registry — marketplace-listings.ts — feeds all four surfaces, and the status is pending_review:

  • /llms.txt — a Distribution section naming the marketplace, endpoint, and rail
  • /skill.json — ab:distribution with the full listing records
  • /.well-known/agentbadge.json — marketplace_listings in the deployment descriptor
  • Organization JSON-LD — sameAs pointing at the catalog
One emerald ledger — marketplace-listings.ts — fanning out to four glowing screens: llms.txt Distribution section, skill.json ab:distribution, agentbadge.json marketplace_listings, and a JSON-LD sameAs link, each showing the same Circle Marketplace pending_review chip
One registry, four surfaces — the status propagates, so "listed" flips everywhere at once.

When approval lands, one string changes — pending_review → listed — and every surface updates itself. The same mechanism protects us the other direction: if a listing gets delisted, we can't forget to update the JSON-LD.

The principle: don't claim listings you don't have. Services advertising marketplace presence that the discovery index doesn't return are teaching agents to distrust metadata — and the agent that trusts a stale claim fails at checkout, not at marketing.

A terminal with a curl + jq query reading a JSON array beside a catalog shelf of 2650 glowing x402 resource tiles; a magnifier lights up the matching tile while an amber sign warns about fuzzy name matching
The index is the ground truth. Verify by resource and payTo — never by name alone.

We built the telemetry before the first sale

A listing that goes live while your settlement errors are invisible is a listing you find out about from a support ticket. So before submission we shipped the observability pack:

  • Settle-failure alerts — every x402 settle failure fires to Telegram/Discord, deduped by error reason over 15 minutes. Verify failures stay log-only: a bad signature isn't a business event, a broken settle is.
  • GET /api/ledger/revenue?days=N — ops rollup of paid legs: total, byDay, byEndpoint. A nonzero total is the earliest possible "someone paid" signal.
  • Revenue in the ops digest — x402Revenue block with top endpoints rides the daily summary we already send ourselves.

And a subtle bug the tests caught: the econ-events schema was stripping the endpoint field the settle legs carried, so revenue-by-endpoint silently never attributed anything. Fix went upstream — @agentbadge/econ-events@0.1.4 — because attribution that only works on new fields is attribution that lies about the past.

What happens on approval

  1. The Discovery API query returns our items[] entry — resource, accepts[], metadata.provider.
  2. pending_review → listed in marketplace-listings.ts; all four surfaces update.
  3. Verify accepts[].network = eip155:5042002 and payTo = our wallet — the catalog rendering can lag the index.
  4. Screenshot the catalog card, swap this article's hero, publish.

If review stalls past a few days, Circle's escalation path is documented (help.circle.com support form, or a ticket in the Build on Arc Discord). Manual review queues are a feature, not a bug — a marketplace that indexes without review is a spam list.


Status as of writing: submitted 2026-11-12, pending review. Check the index yourself — the command above is the same one we're watching.