Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: Sato Hub public Agent Economy API
version: 1.1.0
summary: Read access to the onchain agent library, its change feed, and the Agent Passport registry.
description: 'Public reads need no key and no account; the projects and listings routes take a bearer key. A Sato API key is optional on every metered endpoint and only raises limits. What is free, what is paid (the plans are Sato Check Team and Platform & Data), every limit and the fee schedule are listed on the pricing page, and the same sheet is machine-readable at /api/pricing.json.
Pricing: https://satohub.ai/pricing
License: Catalog data CC-BY-4.0 — attribution: data by satohub.ai. Scores/liveness are informational signals, not safety or quality guarantees.
Scores and liveness are informational signals computed from public evidence. They are not safety ratings, audits, or claims about returns. `verification_status` distinguishes self-reported from independently checked; self-reported is never presented as verified.
Every shape this API returns is also published as a versioned JSON Schema (draft 2020-12) at https://satohub.ai/schemas — catalogue at https://satohub.ai/schemas/index.json. They are referenced from components.schemas below, and v1 is additive-only: a breaking change becomes v2 at a new URL. Validate with additional properties allowed.
The same data is available to agents over MCP (Streamable HTTP, JSON-RPC) at https://satohub.ai/api/mcp — documented at https://satohub.ai/mcp. That endpoint is not described here because it is not REST.
INTERPRETED ANSWERS. A route template sent literally (`{slug}`), an empty query or body, a parameter under another name (`?package=` for `?target=`) or another spelling of a chain (`8453`, `eth`, `bsc`) is answered with the closest honest thing instead of a bare 4xx, and always LABELLED: the body carries an `interpretation` object (`interpreted_as`, `requested`, `rule`, `note`; the same four keys are repeated at the top level when they cannot collide with the record''s own fields), and the response carries the header `X-Sato-Interpreted: ` (plus `Content-Location` when there is a canonical URL). An interpreted answer is never an exact match. Nothing that moves money is ever interpreted beyond a chain spelling: no amount, token, taker, recipient, deployer or slippage is defaulted, a missing chain is never assumed, a chain is never guessed from an address, and a generic network word (`mainnet`, `testnet`) is never read as a chain (the answer lists the candidates). Writes are never interpreted, and a receipt is never served for a template.'
contact:
name: Sato Hub
url: https://satohub.ai
x-guidance: 'Free: search and read the onchain-agent catalog (/api/export/index.json, /api/changes, /api/resolve) and use the MCP server at /api/mcp. Paid over x402 (USDC on Base, no account or key): GET /api/x402/history/{slug} for one listing''s daily Sato Score record, GET /api/x402/agent-economy for the weekly agent-economy series. Each paid read is priced per unit delivered (daily points or rows returned): the 402 states the exact amount, the unit, the quantity and the formula, which is also on /pricing. The Sato Score measures how open, active and verifiable a project is; it is not a safety or returns grade.'
x-status:
page: https://satohub.ai/status/sato-hub
json: https://satohub.ai/api/status.json
feed: https://satohub.ai/status/feed.xml
note: Success ratios and latencies of Sato Hub's own hourly checks. Not a service-level agreement.
license:
name: CC-BY-4.0
url: https://creativecommons.org/licenses/by/4.0/
servers:
- url: https://satohub.ai
security: []
tags:
- name: agent-economy
description: Weekly on-chain measurements per venue, chain and lifecycle stage. Nothing in these responses may be summed — read each venue's unit first.
paths:
/api/export/adoption.json:
get:
tags:
- agent-economy
operationId: getAgentEconomyJson
summary: The measured agent economy for the current week
description: 'Weekly measurements of what is actually happening on-chain across the agent venues Sato Hub tracks — identity registries, service registries, a launchpad, a payment rail and account infrastructure — from public chain reads.
THE RESPONSE CARRIES ITS OWN RULES, in a `rules` array, because the commonest way to misuse this data is to add it up. Each venue declares what ONE UNIT of it is; a registration, a staked service, a token launch and a paid task are not the same object and share no denominator.
A null `value` means UNKNOWN and never zero. A rate with `publishable_rate: false` has too small a sample to quote. `covered_days` is what was actually observed, which is not always `window_days` — public nodes prune history, and on BNB Chain only hours of it are readable at all.
CURRENT WEEK ONLY. The weekly series is not part of the free export.
Solana identity registries are covered as UPPER BOUNDS (program-account counts; unit says so); Solana payment settlement is not covered by any row, and by transaction count x402 mostly settles there. Tempo memo-tagged transfers are MPP-shaped, not proof of MPP payments.'
parameters:
- name: venue
in: query
required: false
schema:
type: string
description: Restrict to one venue.
- name: chain
in: query
required: false
schema:
type: string
description: Restrict to one chain.
- name: stage
in: query
required: false
schema:
type: string
description: Restrict to one lifecycle stage.
- name: slug
in: query
required: false
schema:
type: string
description: Restrict to measurements attributed to one directory listing.
responses:
'200':
description: The week's measurements, plus the venue catalogue needed to interpret them.
content:
application/json:
schema:
type: object
properties:
schema_version:
type: string
generated_at:
type: string
format: date-time
source:
type: string
format: uri
license:
type: string
week:
type:
- string
- 'null'
rules:
type: array
items:
type: string
description: How these numbers may and may not be used. Part of the payload, not the documentation.
venues:
type: array
items:
type: object
description: 'The catalogue: what one unit is per venue, entry cost, measurability, declared overlaps, and how many confirmed contracts back it.'
count:
type: integer
measurements:
type: array
items:
type: object
description: 'One measurement at the grain (venue, chain, stage, week). NEVER sum these: an ERC-8004 registration, an Olas staked service, a Virtuals launch and a Mech task are four different objects, and `unit` says which one this row counts.'
properties:
venue:
type: string
description: erc8004 | olas | virtuals | x402 | erc4337_accounts | key_management | singularitynet | morpheus
chain:
type:
- string
- 'null'
description: Null for venue-level rows (a venue with no chain, e.g. key_management).
stage:
type: string
description: The lifecycle stage this row counts, e.g. registered, funded, active_beyond_registration, transacting, launched, graduated, settled_to_catalogued_seller.
week:
type: string
description: ISO week, e.g. 2026-W36.
week_start:
type: string
format: date
platform_host:
type:
- string
- 'null'
description: Set on breakdown rows attributing registrations to the platform that produced them.
belongs_to_slug:
type:
- string
- 'null'
description: The directory listing this row is attributed to, when one could be resolved.
value:
type:
- number
- 'null'
description: NULL means UNKNOWN. It never means zero — a measurement failure is not an observation of nothing.
unit:
type: string
description: What one of these IS. Read it before comparing two venues.
method:
type: string
description: How the figure was produced, in words. Travels with the number by design.
evidence_tier:
type: integer
enum:
- 1
- 2
- 3
description: 1 = proof (observing it IS the finding); 2 = indicator (countable but contaminated by human usage); 3 = inference (never assertable).
sample_size:
type:
- integer
- 'null'
description: Null for exact counts over a whole population.
denominator:
type:
- integer
- 'null'
window_days:
type:
- integer
- 'null'
description: The window requested.
covered_days:
type:
- number
- 'null'
description: The window ACTUALLY covered. Public nodes prune; these differ, and only this one is comparable across chains.
publishable_rate:
type: boolean
description: False when the sample is too small to quote as a finding. The row is still returned — it is a real observation, just not a result.
caveat:
type:
- string
- 'null'
description: What limited this specific measurement.
contract:
type:
- string
- 'null'
stale_contract:
type:
- boolean
- 'null'
description: True when the address confirmation is older than the re-check interval.
as_of:
type: string
format: date-time
venue_url:
type: string
format: uri
required:
- venue
- stage
- week
- value
- unit
- method
- evidence_tier
- as_of
/api/export/adoption.csv:
get:
tags:
- agent-economy
operationId: getAgentEconomyCsv
summary: The measured agent economy as CSV
description: Same rows as adoption.json. The method and caveat columns are carried deliberately — a spreadsheet is exactly where a number gets separated from its qualification.
parameters:
- name: venue
in: query
required: false
schema:
type: string
description: Restrict to one venue.
- name: chain
in: query
required: false
schema:
type: string
description: Restrict to one chain.
- name: stage
in: query
required: false
schema:
type: string
description: Restrict to one lifecycle stage.
- name: slug
in: query
required: false
schema:
type: string
description: Restrict to measurements attributed to one directory listing.
responses:
'200':
description: CSV.
content:
text/csv:
schema:
type: string
/api/export/adoption.ndjson:
get:
tags:
- agent-economy
operationId: getAgentEconomyNdjson
summary: The measured agent economy as newline-delimited JSON
description: One measurement per line. Streamable.
parameters:
- name: venue
in: query
required: false
schema:
type: string
description: Restrict to one venue.
- name: chain
in: query
required: false
schema:
type: string
description: Restrict to one chain.
- name: stage
in: query
required: false
schema:
type: string
description: Restrict to one lifecycle stage.
- name: slug
in: query
required: false
schema:
type: string
description: Restrict to measurements attributed to one directory listing.
responses:
'200':
description: NDJSON — one measurement per line.
content:
application/x-ndjson:
schema:
type: string
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: 'Two different credentials ride this header, and they are told apart by their shape.
• A SATO API KEY, `sk_sato_…` — optional on every metered endpoint. It is NEVER required: each of those endpoints answers an anonymous caller at the free limits, and a key only raises the caps and attributes the calls to an account. A key may also be sent as `X-Sato-Key`. An unknown or revoked key is served as if no key were present, never refused. Limits and plans: /pricing.
• A PRIVY ACCESS TOKEN for a signed-in account — required by the claim endpoints and the key-management endpoints. A token that is not a Sato key is treated as one of these.'
satoKey:
type: apiKey
in: header
name: X-Sato-Key
description: 'The same optional Sato API key, on its own header. Equivalent to `Authorization: Bearer sk_sato_…`.'
externalDocs:
description: The published Sato Hub formats, as JSON Schema.
url: https://satohub.ai/schemas