satohub-ai X402 Merchants API

An evidence-ranked index of the sellers who take x402 payments. Every reading is dated and carries its method; `unknown` means no reading is held, never a failure.

Operations 1

GET /api/x402/services Find a paid x402 service for a need #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/satohub-ai:satohub-ai-x402-merchants-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

satohub-ai-x402-merchants-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Sato Hub public X402 Merchants 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: x402-merchants
  description: An evidence-ranked index of the sellers who take x402 payments. Every reading is dated and carries its method; `unknown` means no reading is held, never a failure.
paths:
  /api/x402/services:
    get:
      tags:
      - x402-merchants
      operationId: findX402Services
      summary: Find a paid x402 service for a need
      description: 'Describe what you need in plain words and get indexed x402 services (paid APIs and data an agent can call and pay per request), ranked by what Sato Hub observed. The same results as the MCP tool `onchain_agent_find_x402_service`.


        Ranking, evidence only: (1) USDC payments to the payout address on Base in the last seven days from several outside payers that do not look like machine noise; (2) the listed URL answered HTTP 402 with a payment payload when we asked; (3) everything else, unknown before no. Ties go to the lower per-call price, then the URL. Listing count, a seller''s own description and any payment to us never move a result.


        `unknown` means we hold no reading, never that anything failed. A hit describes what was observed; it is not an endorsement, and this call never pays for or calls a service. When nothing matches, `hits` is empty and `guidance` says how to broaden: a hit is never invented. The `need` text is not stored.'
      parameters:
      - name: need
        in: query
        required: true
        schema:
          type: string
          maxLength: 200
        description: What the service should do, in plain words.
      - name: category
        in: query
        required: false
        schema:
          type: string
          enum:
          - market-data
          - onchain-data
          - web-data
          - search
          - inference
          - media
          - security
          - identity
          - dev-tools
          - commerce
          - agents
          - other
        description: Narrow to one category.
      - name: chain
        in: query
        required: false
        schema:
          type: string
        description: Narrow to a chain by name, e.g. Base or Solana.
      - name: max_price_usd
        in: query
        required: false
        schema:
          type: number
          minimum: 0
        description: Per-call price ceiling in USD. Listings with no decodable per-call price are left out when this is set.
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 20
          default: 10
        description: Hits to return.
      responses:
        '200':
          description: Ranked hits (possibly none) with the ranking rule and guidance.
          content:
            application/json:
              schema:
                type: object
                required:
                - hits
                - matched
                - capped
                - match_mode
                - ranking
                - guidance
                properties:
                  hits:
                    type: array
                    items:
                      type: object
                      required:
                      - url
                      - network
                      - chain
                      - category
                      - merchant
                      - sato_url
                      properties:
                        url:
                          type: string
                          description: The listed resource URL, normalised.
                        network:
                          type: string
                          description: The network as the catalogue gave it (CAIP-2).
                        chain:
                          type: string
                          description: Chain display name, e.g. Base or Solana.
                        description:
                          type:
                          - string
                          - 'null'
                          description: The seller's own description. Never used for ranking.
                        category:
                          type: string
                          enum:
                          - market-data
                          - onchain-data
                          - web-data
                          - search
                          - inference
                          - media
                          - security
                          - identity
                          - dev-tools
                          - commerce
                          - agents
                          - other
                        price_usd:
                          type:
                          - number
                          - 'null'
                          description: USD per call as the seller registered it. Present only where the asset is USDC on Base or Solana; null otherwise. A registration, not an observed charge.
                        merchant:
                          type: object
                          required:
                          - slug
                          - pay_to
                          - answers_402
                          - payments
                          - is_ours
                          properties:
                            slug:
                              type: string
                            display_host:
                              type:
                              - string
                              - 'null'
                            pay_to:
                              type: string
                            answers_402:
                              type: object
                              properties:
                                state:
                                  type: string
                                  enum:
                                  - 'yes'
                                  - 'no'
                                  - unknown
                                checked_at:
                                  type:
                                  - string
                                  - 'null'
                                  format: date-time
                                probed:
                                  type:
                                  - integer
                                  - 'null'
                                answered:
                                  type:
                                  - integer
                                  - 'null'
                            payments:
                              type: object
                              description: USDC payments observed to the payout address. Base only; our own payers are excluded from the payer count.
                              properties:
                                state:
                                  type: string
                                  enum:
                                  - 'yes'
                                  - 'no'
                                  - unknown
                                window_days:
                                  type:
                                  - integer
                                  - 'null'
                                window_end:
                                  type:
                                  - string
                                  - 'null'
                                transfers:
                                  type:
                                  - integer
                                  - 'null'
                                distinct_payers:
                                  type:
                                  - integer
                                  - 'null'
                                usdc:
                                  type:
                                  - number
                                  - 'null'
                                noise:
                                  type:
                                  - boolean
                                  - 'null'
                                artemis_pass:
                                  type:
                                  - boolean
                                  - 'null'
                                method:
                                  type: string
                            claimed_at:
                              type:
                              - string
                              - 'null'
                              format: date-time
                              description: Set when the payout address signed our claim message. Proves control of the key, nothing about the service.
                            is_ours:
                              type: boolean
                              description: True for Sato Hub's own addresses. Shown, labelled, never ranked up.
                        sato_url:
                          type: string
                          format: uri
                          description: Canonical Sato Hub page for the merchant.
                  matched:
                    type: integer
                    description: Candidates that matched and were ranked.
                  capped:
                    type: boolean
                    description: True when a read hit its page cap on a very broad need; add a filter to see the rest.
                  match_mode:
                    type: string
                    enum:
                    - all_terms
                    - any_terms
                    description: '`any_terms` when no listing matched every word and the search was retried on several of them.'
                  evidence_as_of:
                    type:
                    - string
                    - 'null'
                    format: date-time
                    description: Latest collector run among the returned hits.
                  ranking:
                    type: string
                  guidance:
                    type: array
                    items:
                      type: string
                  unavailable:
                    type: boolean
        '400':
          description: '`need` is missing or a filter value is not valid.'
        '404':
          description: The x402 Merchants index is not switched on.
        '503':
          description: The index could not be read just now.
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