How AI is applied across API Evangelist and APIs.io. Read my AI disclosure →
API Evangelist API Evangelist
Discovery
Learnings
Guidance
Toolbox
Alignment
API Evangelist LLC

Agentic discovery and onboarding · walked through, step by step

How an agent finds an API, proves who it is, and gets trusted

On October 15, 2026 I ran our own agent, API Evangelist, against four small APIs I operate: Yawplet, Yarnhen, Hagglebee and Eventwren. It found each one on APIs.io, proved who it was, and each site decided on its own to trust it — in under seven seconds per site. This page walks through that flow one step at a time, with what was actually sent and returned, using Yawplet as the example. Scroll, and the diagram follows.

API Evangelist, the consumer agent APIs.io, the directory yawplet.com, the provider the account owner, a person
Discover
1agent → APIs.io

The agent searches for a need, not a brand

An agent usually arrives knowing what it wants to do, not which company does it. So the first call is a plain keyless search of the APIs.io catalog for "post short messages". No account, no key.

GET https://apis.io/api/v1/search?q=post+short+messages

Discovery has to work by need. In the first run it mostly did for providers and not at all for their APIs, which is why the API descriptions were rewritten and search was changed the same day.

2APIs.io → agent

APIs.io answers with Yawplet as the top provider

The catalog knows Yawplet because Yawplet is listed there like any other provider, with its contract, docs, pricing and agent card. The agent now has a domain to go to.

"providers": { "top": [ { "slug": "yawplet", "name": "Yawplet", "website": "https://yawplet.com" }, … ] }
Read the provider
3agent → yawplet.com

It reads two files the provider publishes for agents

The A2A agent card says what the agent can ask for. The API Onboarding Descriptor says how to get in, what the provider checks about an agent, and what still needs a person. Both sit at well-known paths, so the agent doesn't need to read documentation to find them.

GET https://yawplet.com/.well-known/agent-card.json
GET https://yawplet.com/.well-known/api-onboarding
4yawplet.com → agent

20 skills, an optional trust check, and the gaps stated up front

The descriptor lists one optional verification: present an APIs.io attestation and, at the anchored tier with a verified key binding, be recorded as trusted. Its gaps say plainly that a person has to fund the account once.

"verification": [{ "facet": "identity_anchor", "min_grade": "verified", "blocking": false }]
"gaps": [ "A person is needed once, for money: …" ]

An agent should learn the rules before it starts, not at a 402.

Check with the directory
5agent → APIs.io (signed)

It asks APIs.io whether it meets this provider's rules

Every request the agent makes to APIs.io is signed with a key published on apievangelist.com (Web Bot Auth). That signature is how APIs.io knows which agent is asking, without a password or an API key.

GET https://apis.io/api/v1/kya/match?provider=https://yawplet.com
Signature-Agent: sig1="https://apievangelist.com"
6APIs.io → agent

Ready: it meets what Yawplet asks for

APIs.io compares the agent's Know Your Agent record against Yawplet's descriptor and says what is met and what is missing. Here, nothing is missing.

{ "provider": "https://yawplet.com", "ready": true, "met": [ { "requirement": "identity_anchor", … } ] }
Get vouched for
7agent → APIs.io (signed)

It asks APIs.io for an attestation addressed to Yawplet

An attestation is a short-lived statement from APIs.io about this agent, for one provider. The agent names the audience; APIs.io decides what it can truthfully say.

POST https://apis.io/api/v1/kya/attest
{ "aud": "https://yawplet.com" }
8APIs.io → agent

A ten-minute attestation, bound to the agent's key

It's a signed JWT that says: this is the agent that controls apievangelist.com, its tier is anchored, and this is good for ten minutes, for yawplet.com only. It names the agent's signing key, so it only counts on a request signed by that key.

{ "iss": "https://apis.io", "sub": "wba:apievangelist.com", "aud": "https://yawplet.com",
  "exp": now + 600, "cnf": { "jkt": "k-9LPs…" },
  "kya": { "tier": "anchored", "disclosure": 0.818 } }

APIs.io vouches for facts it can check. It never tells a provider whom to trust.

Present it, and let the provider decide
9agent → yawplet.com (signed)

The agent hands the attestation to Yawplet

It sends the attestation in a header, on a request it signs with the same key. The same works at signup, and over MCP and A2A, where the signed request is the MCP or A2A call itself.

POST https://yawplet.com/v1/account/kya
APIs-IO-Attestation: eyJhbGciOiJSUzI1NiIsInR5cCI6Imt5YStqd3Qi…
Signature-Agent: sig1="https://apievangelist.com"
10yawplet.com → APIs.io

Yawplet checks that APIs.io really issued it

It fetches APIs.io's public signing keys and verifies the signature, that the attestation is addressed to yawplet.com, that it hasn't expired, and that its ID hasn't been used before.

GET https://apis.io/.well-known/jwks.json
✓ RS256 signature   ✓ aud = https://yawplet.com   ✓ not expired   ✓ jti unused
11yawplet.com → apievangelist.com

It checks the request came from the key the attestation names

Yawplet fetches the agent's public key from apievangelist.com, matches it against the key in the attestation, and verifies the request signature. A copied attestation is useless without the private key that signs the request around it.

GET https://apievangelist.com/.well-known/http-message-signatures-directory
✓ thumbprint = cnf.jkt   ✓ Ed25519 signature verifies   ✓ signed under five minutes ago
12yawplet.com → agent

Yawplet decides: trusted

Then it applies its own rule, which is one line: anchored with a verified binding is trusted. It records the decision and its reasons on the account. Each of the four sites decides for itself.

{ "decision": "trusted", "tier": "anchored", "bound": true,
  "reasons": [ "apis.io tier: anchored",
               "request signed by apievangelist.com, the key the attestation is bound to",
               "registered agent: https://apis.io/agents/api-evangelist/" ],
  "unlocks": { "search_free_per_day": 500 } }

Trust buys something small and visible: 500 free searches a day instead of 100. It doesn't lower prices, skip moderation or replace the owner's card.

Try it
13agent → yawplet.com

The agent dry-runs a post

Every check a real post gets — validation, price, account standing, the abuse prefilter — and nothing charged.

POST https://yawplet.com/v1/posts?dry_run=true
{ "text": "Testing the API Evangelist onboarding journey.", "topics": ["apis", "agents"] }
14yawplet.com → agent

It would post, for two cents

Everything up to here was machine to machine. API Evangelist's own account is funded by the platform, so it can go straight on to posting.

{ "would_post": true, "price": 20000 }   // micro-dollars: $0.02
The one step that needs a person
15agent → account owner

A new agent hands its human one link, with instructions

A brand-new account's first real post answers 402 verify_email with an account_url. The agent can't verify an inbox it doesn't own, so it gives the link to the person it works for, and tells them what to do with it: open it, press "Verify email", click the link that arrives.

402 { "code": "verify_email", "account_url": "https://yawplet.com/account?t=…", "for_human": true }

Money is no longer a human step. Before this, the agent tops up its own balance from its own wallet over x402 — USDC on Base, paid into the site's wallet, credited in about a second:

POST /v1/account/topup?amount=10000000   → 402 { accepts: [ 10 USDC on Base ] }
retry with X-PAYMENT                      → 200 { "balance": 10000000, "network": "base" }

person: one emaileverything else: agent

16account owner → yawplet.com

The owner verifies one email address, and that's it

In the real-money run on October 18, 2026 this took about four minutes, most of it looking for an email that is only sent once the button is pressed. Sixteen seconds later the agent posted, paid from the balance it funded itself.

The email stays on purpose. A wallet is cheaper to make than an inbox, and the email is where accountability lands on a person. A card still works too, for an owner who would rather pay that way.

Build to it

Everything above is built from open pieces: RFCs, an IETF draft, and two small public documents. Here is what each side does, in order, and the first step is the one worth doing this week.

The code is open source: api-commons/kya-tools verifies attestations for providers and signs requests with Web Bot Auth for agents. It has no dependencies, is Apache-2.0, and is the same code these four sites run.

If you run an API

  1. Publish /.well-known/api-onboarding. An API Onboarding Descriptor says how an agent gets an account, how it authenticates, what you check about it, and what still needs a person. Yawplet's is a working example: yawplet.com/.well-known/api-onboarding. This alone lets an agent find out whether it qualifies before it tries.
  2. Say what agents can do. Serve an A2A agent card or an MCP server card, and if you run MCP, OAuth discovery (RFC 9728 and RFC 8414) with dynamic client registration (RFC 7591), so a client connects without a pasted key.
  3. Accept an attestation. Read the APIs-IO-Attestation header at signup. Verify the RS256 signature against apis.io/.well-known/jwks.json, that aud is your origin, that it hasn't expired, and that its jti is new.
  4. Check the binding. If it names a key (cnf.jkt), accept it only on a request Web Bot Auth-signed by that key, from the domain the attestation is about.
  5. Decide with your own rule, and say what trust buys. Store the decision and the reasons per agent. Start small and visible, and publish it in your descriptor.
  6. Report back. Sign a conduct report as your own domain to POST https://apis.io/api/v1/agents/{sub}/reports: good standing as well as abuse. That's what fills in an agent's history for the next provider.
  7. Optionally, let agents pay. An x402 top-up into a prepaid balance takes the card out of onboarding while keeping refunds and penalties working.

If you build agents

  1. Get a domain-anchored identity. Make an Ed25519 key, publish its public half at /.well-known/http-message-signatures-directory on your own domain, and sign your requests with Web Bot Auth. It replaces a password with something only you can produce.
  2. Fill in your KYA record. A signed PATCH https://apis.io/api/v1/kya/me discloses who runs you and how to reach them. Disclosure is yours to raise; verification is what apis.io could confirm. How the record works.
  3. Register your agent card at apis.io/agents, as a consumer, a provider, or both.
  4. Before each provider, match and attest. GET /api/v1/kya/match?provider=… tells you what you're missing; POST /api/v1/kya/attest with aud gets you a ten-minute attestation for that provider only.
  5. Present it on a signed request, at signup or after, over REST, MCP or A2A.
  6. Hold a wallet. Where a provider offers x402 top-ups, your agent can fund its own balance. A Coinbase CDP server wallet works and keeps the keys out of your code. Fund it on Base.
  7. Hand your human one link, with words. When a provider needs a person, say exactly what to press and what email to look for.

Want help with any of it, or want your API listed as an example? Get in touch. I'd rather this get copied than stay mine.

Read more