Skip to content

For API consumers ​

Every listing on AirnodeHub is an API served through an Airnode, so you consume them all the same way: find it, read its self-description, call it, and verify what came back. Each step is machine-readable, so the consumer can be an agent as easily as a person.

If your agent speaks MCP, every one of those steps is served as a tool at one endpoint, so it can do them without you wiring up any of this by hand.

A client that knows only the Hub's domain finds the rest from it. /.well-known/api-catalog is an RFC 9727 linkset naming the resolve endpoint, its OpenAPI document at /openapi.json, the MCP server, these docs and /llms.txt. Every page and document the Hub serves carries the same set in a Link header. Your agent can start from any one of them and reach the others without a person telling it where to look.

Finding an API ​

Say what you need in plain English and the Hub answers with the calls that could serve it, each with its parameters, an example filled in, the same call in the provider's own form, its price and who will have attested to the answer before anything is spent. A model reads the listing registry to choose, so it understands a request phrased in words no listing uses, and every candidate it returns is checked back against the registry before you see it: the parameter contract, the price and the address come from the API's own document rather than from the model. If it cannot be reached you get a 503 rather than a guess, since a candidate carries an address and a price and nothing that never read your intent should arrive wearing them. Send it again in a moment.

Ask for "yesterday" or "the last three hours" and the dates come back filled in, worked out from the current time in UTC and from the timezone your request appears to come from. Near midnight, or when your agent runs a long way from you, name the date in the intent rather than leaving it to be inferred.

The Hub's home page does this as a conversation. Say what you need and the assistant searches the catalogue, shows you the plan of calls with the price of each step, runs it when you approve, and verifies every response against the address the listing signs with before it answers. The endpoint underneath is what an agent calls, and it is free:

sh
curl -X POST https://airnodehub.api3.org/resolve \
  -H 'Content-Type: application/json' \
  -d '{ "intent": "current USD price of ETH" }'

Free, but rate limited per caller, since every resolve costs us inference to serve. Over the limit you get a 429 rather than an answer. Reading the listings costs nothing, so list-listings, search-listings, get-listing-details and get-operation-details over MCP are not limited, and an agent that searches rather than resolving repeatedly never meets the limit.

We record the intents the Hub resolves and the answer each one got: the operations offered, the parameters filled in for them, and anything it could not resolve. An intent nothing on the Hub can serve is the most useful thing you can tell us, since it names an API worth listing, and it is why we keep it rather than answering and forgetting it. When nothing matches, the Hub says so and points you at Discord, where you can ask for help or name the API you came for.

Alongside it we keep your IP address, roughly where that is, the network the request came over, what software made the call and Cloudflare's reading of whether the caller is a bot. We use it to keep the endpoint available to everyone, to apply the rate limit, and to understand how the Hub is being used.

When browser analytics is enabled on the Hub, we measure visits to catalogue pages and clicks on selected documentation and discovery links. We exclude chat prompts, conversation links and wallet addresses from those analytics events. Campaign labels and a referral source can accompany a visit; resource clicks tell us which guides people open, not whether an agent connected. Direct MCP and API requests do not run this browser measurement.

You can also browse the catalogue and search the listings. Agents read /llms.txt, which the site serves generated from the same listing registry: a one-line summary of the marketplace, how to call a listing, and one link per listing with its description. /llms-full.txt is the same registry with every operation, its parameters and its price written out, for an agent that would rather read one file than follow the links. Either is enough to find and use every API on the Hub.

Either way, a listing resolves to the URL of a deployed Airnode. A listing marked first-party is one the original data source operates itself, so the attestation reaches all the way back to the producer. Any other listing is run by someone over a source they do not own, and the attestation is provenance for the relay rather than for producing the data. Check which one you are calling before you decide what a signature buys you. Integrations covers what a listing is made of, and AirnodeHub is where the details of each one live.

If you publish articles about AirnodeHub, see For publishers for the referral link, campaign labels and examples.

Reading what it serves ​

A GET of the listing URL returns the Airnode's own OpenAPI document: the operations it serves, the parameters each one takes, and under x-airnode the address to verify responses against.

sh
curl https://airnode-nodary.fly.dev/

A listing's page on the Hub renders a saved copy of this same document for a person. The Airnode's own answer is the authority: an agent should read the listing URL directly, and you can too when it matters.

The HTTP interface covers what is in the document and what is deliberately left out of it.

Calling an operation ​

A POST to the same URL names an operation and its parameters:

sh
curl -X POST https://airnode-nodary.fly.dev/ \
  -H 'Content-Type: application/json' \
  -d '{ "operation": "latestFeeds", "parameters": { "name": "ETH/USD" } }'

The response is the upstream data plus the attestation over it. data is the upstream body exactly as received, as one string, since that is what the signature covers:

json
{
  "airnode": "0xE70f1e8b22a21e4Bb5188918a3033341b281E4c0",
  "requestHash": "0x…",
  "timestamp": "1752580000",
  "data": "{\"ETH/USD\":{\"value\":1877.62,\"timestamp\":1752579990000,\"category\":\"crypto\"}}",
  "signature": "0x…"
}

An unknown operation is a 404, a missing, unknown or mistyped parameter is a 400, and an upstream failure is a 502.

A client that speaks the provider's own interface rather than this envelope, a JSON-RPC library pointed at an RPC URL for one, calls the same Airnode through its passthrough: the provider's method, path, query and body sent to the listing URL followed by /api, and the provider's response back as it is, with the attestation in headers. The RPC URL such a client is configured with is that route with its network filled in, https://airnode-drpc.fly.dev/api/ogrpc?network=ethereum for Ethereum on the dRPC listing, and the listing page shows the line for whichever network you pick. The HTTP interface covers it, and the statuses below are the envelope's. Through the passthrough the upstream's own status comes back as it is, so a 429 there is the provider's rate limit.

What a status means ​

Every answer is one of a short list of statuses, and each says what to do next.

StatusFromIt meansDo
200AirnodeThe upstream answered and the response is attested.Verify it.
400AirnodeThe parameters, the projection or the payment header are wrong.Fix the request. It cost nothing.
402AirnodeThe operation is priced and no valid payment came with the call.Sign the requirements in PAYMENT-REQUIRED and retry.
404AirnodeNo such operation.Read GET / again.
502AirnodeThe upstream failed, or refused with upstreamStatus. Nothing was charged.Retry later, or pick another candidate if upstreamStatus is a 4xx.
429HubToo many resolves from one caller.Search the listings instead. That is unlimited.
503HubThe resolver could not answer.Send the intent again in a moment.

A listing's page on the Hub lays the operations out the way the provider documents them, each a request to the passthrough you can fill in and send from the browser, with the URL and a curl to copy, and hands the response with its headers straight to verification on the page.

Verifying the response ​

Check that the signature is the listed address signing over exactly this request, this time and these bytes. Attestation documents the algorithm and a client side implementation, and a listing's page on the Hub runs the same check in the browser, on a POST / response pasted as its JSON or on a passthrough response pasted as curl --include prints it, headers and all, beside the request it answered. There is deliberately no verify endpoint to call: verification is yours to do, so an Airnode is never asked to grade its own work.

Verification is what makes the responses composable. An answer your agent assembles from several listings can carry every underlying attestation along, so whoever consumes the aggregate can verify each original source rather than trusting the last hop. Attested data covers why that works.

To carry them along, keep each attestation whole, exactly as it came, beside the operation, the parameters and the projection you sent it, or, for a passthrough response, the headers and the body as received beside the request you sent. The request hash binds the signature to those, and a verifier re-derives it from them. There is no bundle format for a composed answer yet and no verifier that takes one. So you pass each source attestation and the derivation, and whoever consumes it verifies each source on its own.

Paying ​

Discovery is always free, and a listing may price the operations it serves with x402: performing one becomes the paid resource, settled per request in a USD stablecoin without a human in the loop. A priced operation answers an unpaid call with 402 and the payment requirements in the PAYMENT-REQUIRED header. The caller signs an authorization to pay and retries the call with it in the PAYMENT-SIGNATURE header, which is a step an agent takes on its own. Any x402 v2 client does this for you. You need no account and no API key, just a wallet. A listing that prices nothing stays free to call. See payments for how this maps onto the endpoints.

On the Hub itself, the assistant asks your wallet to sign each priced step of a plan when you run it, and sending a priced operation from its listing page does the same for one call. Over MCP, a client that speaks x402 pays through call-operation.

Most operations that return data are priced, from $0.01 a call, and paid in aUSD, a test dollar on Base Sepolia that you can mint from its faucet, so you pay for calls without spending real money. An agent can mint its own by calling mintFromFaucet on the token from the account it pays with. Minting needs Base Sepolia ETH for gas, and paying a call needs none. Most lookups are free: an operation that turns a name into an id another operation takes, or lists the ids it accepts, costs nothing, so a plan pays only for the data it came for. Read the price out of the listing's own document rather than assuming it.