satohub-ai Satobot API

Sato Bot. A goal in plain words in, a BUILD PLAN out: the goal restated, a stack of real directory listings each carrying its Sato Score and `sato_url`, a deploy spec and a Preflight verdict per item, the first action when the goal implies one, the open questions and the next steps. Nothing in a plan is invented, `null` is unknown rather than zero, and a plan is a recommendation assembled from Sato Hub's own records at `checked_at` — not a security review, not a quality judgment, not a statement about returns. This tag holds no keys and signs nothing: a swap first-action is quoted at a NOMINAL size, never the caller's, and a launch first-action is a config the caller reads and signs itself.

Operations 4

GET /api/satobot/plan Turn a goal in plain words into a build plan #
POST /api/satobot/plan Same plan, JSON body #
GET /api/satobot/scaffold The build plan, as a starter repo (zip) #
POST /api/satobot/scaffold Same archive, JSON body — or scaffold a plan you already hold #

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-satobot-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-satobot-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Sato Hub public Satobot 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: satobot
  description: 'Sato Bot. A goal in plain words in, a BUILD PLAN out: the goal restated, a stack of real directory listings each carrying its Sato Score and `sato_url`, a deploy spec and a Preflight verdict per item, the first action when the goal implies one, the open questions and the next steps. Nothing in a plan is invented, `null` is unknown rather than zero, and a plan is a recommendation assembled from Sato Hub''s own records at `checked_at` — not a security review, not a quality judgment, not a statement about returns. This tag holds no keys and signs nothing: a swap first-action is quoted at a NOMINAL size, never the caller''s, and a launch first-action is a config the caller reads and signs itself.'
paths:
  /api/satobot/plan:
    get:
      tags:
      - satobot
      operationId: satobotPlan
      security:
      - {}
      - bearerAuth: []
      - satoKey: []
      summary: Turn a goal in plain words into a build plan
      description: 'Describe the onchain agent you want; get a plan you can act on.


        WHAT COMES BACK: the goal restated as it was understood (including the parsed intent and which chain was read from your words), a stack of REAL directory listings bucketed into slots — framework, wallet, payments, trading, data, MCP tooling, security — each carrying its Sato Score, liveness, the share of Sato Hub''s own daily checks it answered, whether its documented install was reproduced by us, and its `sato_url`; the published deploy spec for every item that has one; a Preflight verdict per item with one evidence line per check; the first action when the goal implies one; the questions you still have to answer; and the next steps.


        WHAT IT IS: a recommendation assembled from Sato Hub''s own records at `checked_at`. Nothing in a plan is invented — a component that is not a listing cannot appear — and `null` is unknown, never zero. A Sato Score measures how open, active and verifiable a project is; it is not a security review, a quality judgment or a statement about returns. A Preflight `unknown` means Sato Hub holds no record, not that something is wrong.


        CUSTODY: none. This endpoint never holds keys, signs, deploys or moves funds. A swap first-action carries a quote taken at a NOMINAL size — your size is yours to choose — and a launch first-action carries a config you read and sign yourself, with the fee disclosed before anything is signed.


        POST takes the same fields as a JSON body, with `constraints` as an array.'
      parameters:
      - name: goal
        in: query
        required: true
        schema:
          type: string
          maxLength: 600
        description: What you want to build, in plain words, e.g. 'a Base trading agent that swaps USDC to ETH on a signal'.
      - name: chain
        in: query
        required: false
        schema:
          type: string
          maxLength: 40
        description: Chain the agent runs on. When omitted it is read from the goal, and `chain_source` says which.
      - name: budget_usd
        in: query
        required: false
        schema:
          type: number
          minimum: 0
        description: Rough monthly budget. Restated in the plan; it does not filter the stack.
      - name: constraints
        in: query
        required: false
        schema:
          type: string
        description: Comma-separated hard constraints to restate back, e.g. self-custody only,no API keys.
      - name: format
        in: query
        required: false
        schema:
          type: string
          enum:
          - json
          - markdown
        description: '''json'' (default) or ''markdown'' — the short chat render, for a channel adapter.'
      responses:
        '200':
          description: The build plan.
          content:
            application/json:
              schema:
                type: object
                required:
                - goal
                - restatement
                - intent
                - stack
                - first_action
                - open_questions
                - next_steps
                - caveat
                - checked_at
                properties:
                  goal:
                    type: string
                  restatement:
                    type: string
                    description: The goal as it was understood, so a misread is visible before anything is built on it.
                  intent:
                    type: string
                    enum:
                    - swap
                    - launch
                    - trading
                    - payments
                    - data
                    - identity
                    - general
                  intent_signals:
                    type: array
                    items:
                      type: string
                    description: Which rule matched, and on what words.
                  chain:
                    type:
                    - string
                    - 'null'
                  chain_source:
                    type: string
                    enum:
                    - given
                    - parsed
                    - unknown
                  budget_usd:
                    type:
                    - number
                    - 'null'
                  constraints:
                    type: array
                    items:
                      type: string
                  matched_use_cases:
                    type: array
                    items:
                      type: string
                  stack:
                    type: array
                    items:
                      type: object
                      properties:
                        slot:
                          type: string
                        slot_label:
                          type: string
                        slug:
                          type: string
                        name:
                          type: string
                        category:
                          type: string
                        sato_url:
                          type: string
                          description: The canonical record. Cite it — it is the live one; this plan is a copy.
                        verify_url:
                          type:
                          - string
                          - 'null'
                        trust_score:
                          type:
                          - integer
                          - 'null'
                        trust_tier:
                          type:
                          - string
                          - 'null'
                        liveness_ok:
                          type:
                          - boolean
                          - 'null'
                        observed_success_pct:
                          type:
                          - number
                          - 'null'
                          description: Share of Sato Hub's OWN daily checks that succeeded. Never uptime.
                        observed_days:
                          type:
                          - integer
                          - 'null'
                        observed_window_start:
                          type:
                          - string
                          - 'null'
                          description: First check date the rate is over (additive).
                        install_verified:
                          type: boolean
                          description: The documented install was reproduced in an ephemeral container on the spec's date. It says nothing about runtime.
                        chains:
                          type: array
                          items:
                            type: string
                        why:
                          type: string
                          description: The fields this pick was ranked on.
                        deploy_spec:
                          type:
                          - object
                          - 'null'
                          description: runtime, install, entry, requires, deploy_status, source_url, as_of — null when the listing publishes none.
                        preflight:
                          type:
                          - object
                          - 'null'
                          description: '{ verdict: go|caution|no|unknown, rule, checked_at, evidence[], reason }. Null when the item was outside the preflight budget; `unknown` with a reason when the check did not complete.'
                  gaps:
                    type: array
                    items:
                      type: string
                    description: Where the directory has no strong match. Stated, not hidden.
                  first_action:
                    type: object
                    description: '{ kind: none|swap|launch, ready, missing[], note, ... }. A swap carries the route quote; a launch carries the venue route and, when name/symbol/deployer are known, a prepared config.'
                  open_questions:
                    type: array
                    items:
                      type: string
                  next_steps:
                    type: array
                    items:
                      type: string
                  citation_ask:
                    type: string
                  caveat:
                    type: string
                  rules:
                    type: array
                    items:
                      type: string
                  checked_at:
                    type: string
                    format: date-time
                  plan_url:
                    type: string
            text/markdown:
              schema:
                type: string
                description: The short chat render, when format=markdown.
        '400':
          description: Missing or malformed goal.
    post:
      tags:
      - satobot
      operationId: satobotPlanPost
      security:
      - {}
      - bearerAuth: []
      - satoKey: []
      summary: Same plan, JSON body
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - goal
              properties:
                goal:
                  type: string
                  maxLength: 600
                chain:
                  type: string
                  maxLength: 40
                budget_usd:
                  type: number
                  minimum: 0
                constraints:
                  type: array
                  items:
                    type: string
                    maxLength: 200
                  maxItems: 10
                format:
                  type: string
                  enum:
                  - json
                  - markdown
      responses:
        '200':
          description: As GET.
        '400':
          description: Missing or malformed input.
  /api/satobot/scaffold:
    get:
      tags:
      - satobot
      operationId: satobotScaffold
      security:
      - {}
      - bearerAuth: []
      - satoKey: []
      summary: The build plan, as a starter repo (zip)
      description: 'Builds the plan for a goal and writes it into a small starter repository, returned as a zip.


        WHAT IS IN IT: README.md (the plan rendered, every source URL, and the disclosure that Sato OS is ours) · sato.plan.json (the plan, signed at its own checked_at when a signing key is configured) · .env.example (every environment variable the stack''s own deploy specs declare, values BLANK, each under a comment naming which listing wants it) · install.sh (the documented install lines in order, each under its Preflight verdict) · agent.config.json (chain, tokens and the venue Sato Route chose, with chosen_by) · .mcp.json · docker-compose.yml, present only when every stack item documents a docker install.


        NOTHING IS GENERATED. Every line is a template constant or a field of the plan, copied verbatim. A value we do not hold is left blank with a comment, never filled with a plausible default.


        THE ONE SAFETY RULE: a documented install that pipes a remote script into a shell is written COMMENTED, with a warning above it — never as an executable line.


        DETERMINISTIC: the same plan yields a byte-identical archive; the timestamps come from the plan''s checked_at, not the clock. Capped at 2 MB.


        NON-CUSTODIAL: the archive holds no keys and no secrets, and nothing here signs, deploys or moves anything.'
      parameters:
      - name: goal
        in: query
        required: true
        schema:
          type: string
          maxLength: 600
        description: What you want to build, in plain words.
      - name: chain
        in: query
        schema:
          type: string
          maxLength: 40
        description: Chain the agent runs on. Read from the goal when omitted.
      - name: budget_usd
        in: query
        schema:
          type: number
          minimum: 0
      - name: constraints
        in: query
        schema:
          type: string
        description: Comma-separated hard constraints, restated back in the plan.
      responses:
        '200':
          description: The starter repo. `Content-Disposition` names the file; `Sato-Scaffold-Files` lists its contents.
          content:
            application/zip:
              schema:
                type: string
                format: binary
        '400':
          description: Missing or malformed goal.
        '413':
          description: The archive exceeded the 2 MB cap.
    post:
      tags:
      - satobot
      operationId: satobotScaffoldPost
      security:
      - {}
      - bearerAuth: []
      - satoKey: []
      summary: Same archive, JSON body — or scaffold a plan you already hold
      description: 'Identical to GET, plus one thing: post a `plan` you already have (as /api/satobot/plan returned it) and it is written into files without being rebuilt. The archive is byte-identical to the one that plan produces anywhere else.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                goal:
                  type: string
                  maxLength: 600
                chain:
                  type: string
                  maxLength: 40
                budget_usd:
                  type: number
                  minimum: 0
                constraints:
                  type: array
                  items:
                    type: string
                    maxLength: 200
                  maxItems: 10
                plan:
                  type: object
                  description: A build plan as /api/satobot/plan returns it. When present, goal/chain are ignored and the plan is used verbatim.
      responses:
        '200':
          description: As GET.
        '400':
          description: Missing or malformed input.
        '413':
          description: The archive exceeded the 2 MB cap.
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