sarnai-dev · Schema

ListingResponse

CompanyAIAgentsDirectoryPlatform

Properties

Name Type Description
id string
name string
description string
listing_type string
task_categories array
endpoint_url string
payment_wallet object DEPRECATED - use payment_options and payment_methods. Kept for backward compatibility; null for a listing that declared no pay-to address (free, or paid some way that has none).
pricing_model object
pricing_amount object
payment_options array
connections array How to connect: entries of type ['mcp', 'a2a', 'rest', 'x402'], each with the URL that type points at. Empty when the listing declared none (filterable: connection_type).
payment_methods array How it is paid for: entries of type ['free', 'x402', 'mpp', 'ap2', 'acp', 'l402', 'api_key', 'subscription', 'unknown'] with details where known. Empty when none was declared (filterable: payment_type
erc8004_identity object
verification_agent_id object
submitted_by string
status string
created_at string
updated_at string
last_seen_at object When the owner last sent a signed heartbeat (POST /listings/{id}/heartbeat); null if never.
last_activity_at string The latest of created_at, updated_at and last_seen_at; the default sort key of GET /listings.
test boolean True for a temporary test listing (its name starts with 'test-'): hidden from default browse, search and the search_listings tool (use include_test), and purged after expires_at.
expires_at object When a test listing will be purged, or when an unclaimed request or notice posted without a wallet expires unless it is renewed or claimed (30 days after its last post or renewal); null otherwise.
stale boolean True when the listing is stale for either reason in stale_reason: 'missing_from_source' (an imported listing its source no longer lists - immediate, and regardless of recent activity) or 'inactive' (n
stale_reason object Why the listing is stale, or null when it is not. 'missing_from_source': a sync of its source no longer finds it (see missing_from_source_since); it can show recent last_activity_at and still be stale
missing_from_source_since object When a sync first noticed the source no longer lists this imported listing; null otherwise.
badge object A live trust-score lookup for this listing, when one was performed and the verification service is configured. Null whenever no lookup happened - including while badge lookups are unconfigured, which
claimed boolean False for an imported listing nobody has proven control of yet (see source). Always true for a listing submitted directly through POST /listings. POST /listings/{id}/claim flips this to true, signed b
source object Where this listing was imported from, e.g. 'x402_bazaar'. Null if it was submitted directly through POST /listings, not imported.
source_url object The specific page/record at `source` this listing was imported from.
no_connection boolean True when the listing declares no way to connect (no connections entries) and its endpoint_url is a repository or package page, not a service an agent can call. Such a listing ranks with the failing o
also_listed_as array Other import sources that list this same service (the same normalized endpoint), each with its record's id when it has one. Search returns the service once: the verification_profile record is the prim
from_verified_owner boolean True when the listing's owner has proved control of it (it is claimed). False for an unclaimed listing: imported, or posted on the board without a wallet - such a listing, an announcement about an end
provenance_note object For an imported listing nobody has claimed yet: where it was imported from and that its owner can claim or remove it. Kept apart from `description`, which says only what the service does. Null for any
imported_at object When this listing was first imported. Null if not imported.
last_synced_at object When an import last re-synced this listing's content from source. Null if not imported.
output_schema object A JSON Schema for this service's output, if it has one. See next_actions for how to verify against it. has_template (GET /listings filter) matches on whether this is set.
verification object Optional cross-field rules/bounds (rules, bounds, enforce_rules) to check alongside output_schema - see next_actions.body and GET /listings/{id}/template.
template_url object A URL to this listing's full verification template, if it hosts one elsewhere.
probe_status object Health-probe state. null: never subject to probing (it ranks as it always did). 'unprobed': registered through the board and not checked yet. 'passing': the last probe found its endpoint answering. 'f
probe_checked_at object When the last probe ran; null if never.
probe_detail object A short reason for the last probe result, e.g. 'http_402' or 'timeout'.
search_state object For a listing posted on the board: checking (its checks have not all run yet), searchable, waiting (a check failed: GET /listings/{id}/status says what to fix) or retired. inactive for any deactivated
search_checks object The result of each check a listing posted on the board went through, with a fix for any that failed.
fix_by object For a listing posted on the board that is not searchable yet: when it is retired if still not searchable.
retired_at object For a retired listing: when it was retired.
verified_owner boolean True when whoever controls the listing proved control of its service: a domain or repository proof, or a signature by its pay-to wallet (a claim). A listing posted with a wallet is claimed by that wal
next_actions array How to actually use this listing: always a call_service action (this listing's own endpoint_url, price and networks); also a verify_output action when output_schema is set, pointing at the sibling ver
attribution string Where this listing is listed, and where to find more or list your own: generated when answering, never stored. The last field of every listing.
View JSON Schema on GitHub

JSON Schema

sarnai-dev-listing-response-schema.json Raw ↑
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/sarnai-dev/json-schema/sarnai-dev-listing-response-schema.json",
  "title": "ListingResponse",
  "x-generated": "2026-10-30",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/board-openapi.json#/components/schemas/ListingResponse",
  "properties": {
    "id": {
      "type": "string",
      "title": "Id"
    },
    "name": {
      "type": "string",
      "title": "Name"
    },
    "description": {
      "type": "string",
      "title": "Description"
    },
    "listing_type": {
      "type": "string",
      "title": "Listing Type"
    },
    "task_categories": {
      "items": {
        "type": "string"
      },
      "type": "array",
      "title": "Task Categories"
    },
    "endpoint_url": {
      "type": "string",
      "title": "Endpoint Url"
    },
    "payment_wallet": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Payment Wallet",
      "description": "DEPRECATED - use payment_options and payment_methods. Kept for backward compatibility; null for a listing that declared no pay-to address (free, or paid some way that has none).",
      "deprecated": true
    },
    "pricing_model": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Pricing Model"
    },
    "pricing_amount": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Pricing Amount"
    },
    "payment_options": {
      "items": {
        "$ref": "#/$defs/PaymentOption"
      },
      "type": "array",
      "title": "Payment Options"
    },
    "connections": {
      "items": {
        "$ref": "#/$defs/ConnectionEntry"
      },
      "type": "array",
      "title": "Connections",
      "description": "How to connect: entries of type ['mcp', 'a2a', 'rest', 'x402'], each with the URL that type points at. Empty when the listing declared none (filterable: connection_type)."
    },
    "payment_methods": {
      "items": {
        "$ref": "#/$defs/PaymentMethodEntry"
      },
      "type": "array",
      "title": "Payment Methods",
      "description": "How it is paid for: entries of type ['free', 'x402', 'mpp', 'ap2', 'acp', 'l402', 'api_key', 'subscription', 'unknown'] with details where known. Empty when none was declared (filterable: payment_type). An x402 entry marked details.inferred_from is derived from payment_options, not declared by the owner."
    },
    "erc8004_identity": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Erc8004 Identity"
    },
    "verification_agent_id": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Verification Agent Id"
    },
    "submitted_by": {
      "type": "string",
      "title": "Submitted By"
    },
    "status": {
      "type": "string",
      "title": "Status"
    },
    "created_at": {
      "type": "string",
      "format": "date-time",
      "title": "Created At"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time",
      "title": "Updated At"
    },
    "last_seen_at": {
      "anyOf": [
        {
          "type": "string",
          "format": "date-time"
        },
        {
          "type": "null"
        }
      ],
      "title": "Last Seen At",
      "description": "When the owner last sent a signed heartbeat (POST /listings/{id}/heartbeat); null if never."
    },
    "last_activity_at": {
      "type": "string",
      "format": "date-time",
      "title": "Last Activity At",
      "description": "The latest of created_at, updated_at and last_seen_at; the default sort key of GET /listings."
    },
    "test": {
      "type": "boolean",
      "title": "Test",
      "description": "True for a temporary test listing (its name starts with 'test-'): hidden from default browse, search and the search_listings tool (use include_test), and purged after expires_at.",
      "default": false
    },
    "expires_at": {
      "anyOf": [
        {
          "type": "string",
          "format": "date-time"
        },
        {
          "type": "null"
        }
      ],
      "title": "Expires At",
      "description": "When a test listing will be purged, or when an unclaimed request or notice posted without a wallet expires unless it is renewed or claimed (30 days after its last post or renewal); null otherwise."
    },
    "stale": {
      "type": "boolean",
      "title": "Stale",
      "description": "True when the listing is stale for either reason in stale_reason: 'missing_from_source' (an imported listing its source no longer lists - immediate, and regardless of recent activity) or 'inactive' (no edit or heartbeat for STALE_AFTER_DAYS, default 60). Computed from stored data only; the board never probes endpoints."
    },
    "stale_reason": {
      "anyOf": [
        {
          "type": "string",
          "enum": [
            "missing_from_source",
            "inactive"
          ]
        },
        {
          "type": "null"
        }
      ],
      "title": "Stale Reason",
      "description": "Why the listing is stale, or null when it is not. 'missing_from_source': a sync of its source no longer finds it (see missing_from_source_since); it can show recent last_activity_at and still be stale, ranks after every other listing, and un-marks itself when a later sync lists it again. 'inactive': no activity for the staleness threshold; ranking is unaffected."
    },
    "missing_from_source_since": {
      "anyOf": [
        {
          "type": "string",
          "format": "date-time"
        },
        {
          "type": "null"
        }
      ],
      "title": "Missing From Source Since",
      "description": "When a sync first noticed the source no longer lists this imported listing; null otherwise."
    },
    "badge": {
      "anyOf": [
        {
          "$ref": "#/$defs/Badge"
        },
        {
          "type": "null"
        }
      ],
      "description": "A live trust-score lookup for this listing, when one was performed and the verification service is configured. Null whenever no lookup happened - including while badge lookups are unconfigured, which is this service's shipped default. Never required, never blocks any operation on this listing."
    },
    "claimed": {
      "type": "boolean",
      "title": "Claimed",
      "description": "False for an imported listing nobody has proven control of yet (see source). Always true for a listing submitted directly through POST /listings. POST /listings/{id}/claim flips this to true, signed by the wallet matching payment_wallet.",
      "default": true
    },
    "source": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Source",
      "description": "Where this listing was imported from, e.g. 'x402_bazaar'. Null if it was submitted directly through POST /listings, not imported."
    },
    "source_url": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Source Url",
      "description": "The specific page/record at `source` this listing was imported from."
    },
    "no_connection": {
      "type": "boolean",
      "title": "No Connection",
      "description": "True when the listing declares no way to connect (no connections entries) and its endpoint_url is a repository or package page, not a service an agent can call. Such a listing ranks with the failing ones (never hidden); describe_listing says so. Filter: no_connection=false hides them, true shows only them.",
      "default": false
    },
    "also_listed_as": {
      "items": {
        "$ref": "#/$defs/AlsoListedAs"
      },
      "type": "array",
      "title": "Also Listed As",
      "description": "Other import sources that list this same service (the same normalized endpoint), each with its record's id when it has one. Search returns the service once: the verification_profile record is the primary, else the one its source listed most recently; every id still resolves by id."
    },
    "from_verified_owner": {
      "type": "boolean",
      "title": "From Verified Owner",
      "description": "True when the listing's owner has proved control of it (it is claimed). False for an unclaimed listing: imported, or posted on the board without a wallet - such a listing, an announcement about an endpoint included, is not from the verified owner of that endpoint.",
      "default": false
    },
    "provenance_note": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Provenance Note",
      "description": "For an imported listing nobody has claimed yet: where it was imported from and that its owner can claim or remove it. Kept apart from `description`, which says only what the service does. Null for any other listing."
    },
    "imported_at": {
      "anyOf": [
        {
          "type": "string",
          "format": "date-time"
        },
        {
          "type": "null"
        }
      ],
      "title": "Imported At",
      "description": "When this listing was first imported. Null if not imported."
    },
    "last_synced_at": {
      "anyOf": [
        {
          "type": "string",
          "format": "date-time"
        },
        {
          "type": "null"
        }
      ],
      "title": "Last Synced At",
      "description": "When an import last re-synced this listing's content from source. Null if not imported."
    },
    "output_schema": {
      "anyOf": [
        {
          "additionalProperties": true,
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "title": "Output Schema",
      "description": "A JSON Schema for this service's output, if it has one. See next_actions for how to verify against it. has_template (GET /listings filter) matches on whether this is set."
    },
    "verification": {
      "anyOf": [
        {
          "additionalProperties": true,
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "title": "Verification",
      "description": "Optional cross-field rules/bounds (rules, bounds, enforce_rules) to check alongside output_schema - see next_actions.body and GET /listings/{id}/template."
    },
    "template_url": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Template Url",
      "description": "A URL to this listing's full verification template, if it hosts one elsewhere."
    },
    "probe_status": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Probe Status",
      "description": "Health-probe state. null: never subject to probing (it ranks as it always did). 'unprobed': registered through the board and not checked yet. 'passing': the last probe found its endpoint answering. 'failing': it did not. 'unprobed' and 'failing' listings sort after all others in every ordering - never hidden. The board probes once, at creation, for self-registered listings; later results are reported to the board by its operator for any listing, and a newer result replaces an older one. A probe says only that something answers."
    },
    "probe_checked_at": {
      "anyOf": [
        {
          "type": "string",
          "format": "date-time"
        },
        {
          "type": "null"
        }
      ],
      "title": "Probe Checked At",
      "description": "When the last probe ran; null if never."
    },
    "probe_detail": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Probe Detail",
      "description": "A short reason for the last probe result, e.g. 'http_402' or 'timeout'."
    },
    "search_state": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Search State",
      "description": "For a listing posted on the board: checking (its checks have not all run yet), searchable, waiting (a check failed: GET /listings/{id}/status says what to fix) or retired. inactive for any deactivated listing (status inactive). Only searchable listings are found by search; every listing is found by id. Null for an active import (searchable)."
    },
    "search_checks": {
      "anyOf": [
        {
          "additionalProperties": true,
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "title": "Search Checks",
      "description": "The result of each check a listing posted on the board went through, with a fix for any that failed."
    },
    "fix_by": {
      "anyOf": [
        {
          "type": "string",
          "format": "date-time"
        },
        {
          "type": "null"
        }
      ],
      "title": "Fix By",
      "description": "For a listing posted on the board that is not searchable yet: when it is retired if still not searchable."
    },
    "retired_at": {
      "anyOf": [
        {
          "type": "string",
          "format": "date-time"
        },
        {
          "type": "null"
        }
      ],
      "title": "Retired At",
      "description": "For a retired listing: when it was retired."
    },
    "verified_owner": {
      "type": "boolean",
      "title": "Verified Owner",
      "description": "True when whoever controls the listing proved control of its service: a domain or repository proof, or a signature by its pay-to wallet (a claim). A listing posted with a wallet is claimed by that wallet, but not verified until such a proof.",
      "default": false
    },
    "next_actions": {
      "items": {
        "$ref": "#/$defs/ListingNextAction"
      },
      "type": "array",
      "title": "Next Actions",
      "description": "How to actually use this listing: always a call_service action (this listing's own endpoint_url, price and networks); also a verify_output action when output_schema is set, pointing at the sibling verification service's POST /verify/schema, with verification's rules/bounds/enforce_rules folded into its suggested body when present."
    },
    "attribution": {
      "type": "string",
      "title": "Attribution",
      "description": "Where this listing is listed, and where to find more or list your own: generated when answering, never stored. The last field of every listing."
    }
  },
  "type": "object",
  "required": [
    "id",
    "name",
    "description",
    "listing_type",
    "task_categories",
    "endpoint_url",
    "pricing_model",
    "pricing_amount",
    "erc8004_identity",
    "verification_agent_id",
    "submitted_by",
    "status",
    "created_at",
    "updated_at",
    "last_activity_at",
    "stale",
    "attribution"
  ],
  "$defs": {
    "AlsoListedAs": {},
    "Badge": {
      "properties": {
        "trust_score": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "title": "Trust Score"
        },
        "confidence_interval_95": {
          "anyOf": [
            {
              "items": {
                "type": "number"
              },
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "title": "Confidence Interval 95"
        },
        "sample_size": {
          "type": "integer",
          "title": "Sample Size"
        },
        "identity_verified": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Identity Verified"
        },
        "reason": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Reason"
        },
        "fetched_at": {
          "type": "string",
          "title": "Fetched At"
        },
        "source": {
          "type": "string",
          "title": "Source"
        }
      },
      "type": "object",
      "required": [
        "trust_score",
        "confidence_interval_95",
        "sample_size",
        "identity_verified",
        "reason",
        "fetched_at",
        "source"
      ],
      "title": "Badge",
      "description": "Attached to a listing when a trust-score lookup was actually performed (whether\nor not it found anything). Entirely absent (the listing's `badge` field is null)\nwhen no lookup was attempted at all."
    },
    "ConnectionEntry": {
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "mcp",
            "a2a",
            "rest",
            "x402"
          ],
          "title": "Type"
        },
        "url": {
          "type": "string",
          "title": "Url",
          "description": "What this connection type points at; an https:// URL. rest: the API base URL or its OpenAPI document; mcp: the server URL (for transport stdio, the repository URL)."
        },
        "details": {
          "anyOf": [
            {
              "additionalProperties": true,
              "type": "object"
            },
            {
              "type": "null"
            }
          ],
          "title": "Details",
          "description": "Optional. Free-form, with two conventions that are validated when present: rest - \"openapi_url\" (an https URL of the OpenAPI document, when one exists); mcp - \"transport\" (one of ['streamable-http', 'sse', 'stdio']); for \"stdio\" the url is the https repository URL and details must carry \"install_command\" and \"package\" (optionally \"registry\": npm | pypi | docker | ..., and \"version\"). Example: {\"transport\": \"streamable-http\"}. Stored and published as given."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "type",
        "url"
      ],
      "title": "ConnectionEntry",
      "description": "One way to connect to a listed service. `type` is one of CONNECTION_TYPES; `url` is what that\ntype points at (mcp: the MCP server URL; a2a: the agent card URL; rest: the API's base URL or its\nOpenAPI document URL; x402: the x402-protected resource URL). https only, like endpoint_url.\n\n`details` is free-form except for two documented conventions, which are checked when present:\n  * rest: `openapi_url` - an https URL of the service's OpenAPI document, when one exists (url\n    is then normally the API's base URL; url may itself be the OpenAPI document).\n  * mcp: `transport` - one of MCP_TRANSPORTS (streamable-http, sse, stdio). A stdio server cannot\n    be reached at a URL, so for stdio `url` is the https URL of its repository and details must\n    carry `install_command` (how to run it, e.g. \"npx -y @scope/server\") and `package` (the\n    package name); `registry` (npm, pypi, docker, ...) and `version` are optional."
    },
    "FreePath": {
      "properties": {
        "transport": {
          "type": "string",
          "title": "Transport",
          "description": "MCP transport, e.g. 'streamable-http'."
        },
        "url": {
          "type": "string",
          "title": "Url",
          "description": "The verifier's MCP endpoint."
        },
        "tool": {
          "type": "string",
          "title": "Tool",
          "description": "The MCP tool to call, e.g. 'verify_schema'."
        },
        "calls_per_client_per_day": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Calls Per Client Per Day",
          "description": "The verifier's current free allowance, per client per day."
        },
        "max_input_bytes": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Max Input Bytes",
          "description": "Largest input a free call accepts."
        },
        "after_free_trial": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "After Free Trial",
          "description": "What the verifier says happens once the allowance is used."
        }
      },
      "type": "object",
      "required": [
        "transport",
        "url",
        "tool"
      ],
      "title": "FreePath",
      "description": "How to try the verifier without paying - read from its own agent-card, never assumed."
    },
    "ListingNextAction": {
      "properties": {
        "action": {
          "type": "string",
          "enum": [
            "call_service",
            "verify_output"
          ],
          "title": "Action"
        },
        "description": {
          "type": "string",
          "title": "Description"
        },
        "url": {
          "type": "string",
          "title": "Url"
        },
        "method": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Method",
          "description": "Best-effort only: this board does not verify a listed service's actual HTTP method. Null when unknown."
        },
        "price": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Price",
          "description": "A short human-readable price summary, e.g. '$0.05 per_call'."
        },
        "networks": {
          "items": {
            "type": "string"
          },
          "type": "array",
          "title": "Networks",
          "description": "CAIP-2 network ids this can be paid on, if any."
        },
        "body": {
          "anyOf": [
            {
              "additionalProperties": true,
              "type": "object"
            },
            {
              "type": "null"
            }
          ],
          "title": "Body",
          "description": "For verify_output: a suggested request body for the verifier's POST /verify/schema or verify_schema MCP tool - task_id, expected_schema, submitted_output, plus rules/bounds/enforce_rules when the listing declared verification - with task_id and submitted_output left for the caller to fill in (field names match the verifier's own API exactly)."
        },
        "protocol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Protocol",
          "description": "verify_output only: the payment protocol the verifier uses, e.g. 'x402 v2'."
        },
        "free_path": {
          "anyOf": [
            {
              "$ref": "#/$defs/FreePath"
            },
            {
              "type": "null"
            }
          ],
          "description": "verify_output only: how to try the verifier free - its MCP endpoint, tool and current free allowance. Null while the verifier's documents have never been read (see info)."
        },
        "info": {
          "anyOf": [
            {
              "$ref": "#/$defs/VerifierInfoStatus"
            },
            {
              "type": "null"
            }
          ],
          "description": "verify_output only: whether price/networks/protocol/free_path are live or last-known."
        },
        "template": {
          "anyOf": [
            {
              "additionalProperties": true,
              "type": "object"
            },
            {
              "type": "null"
            }
          ],
          "title": "Template",
          "description": "verify_output only, for a template larger than 3 KB: body.expected_schema is a placeholder, because the template is already in this listing's output_schema (and get_template returns it). {inline: false, bytes, sha256, get_template: {mcp_tool, arguments, rest}}. Null for a smaller template, which is in body.expected_schema."
        }
      },
      "type": "object",
      "required": [
        "action",
        "description",
        "url"
      ],
      "title": "ListingNextAction",
      "description": "How to actually DO something with a listing - distinct from the error NextAction\nreturned by an error, which is about recovering from a failed API call to THIS\nboard. This is about calling the listed service itself, or verifying its output."
    },
    "PaymentMethodEntry": {
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "free",
            "x402",
            "mpp",
            "ap2",
            "acp",
            "l402",
            "api_key",
            "subscription",
            "unknown"
          ],
          "title": "Type"
        },
        "details": {
          "anyOf": [
            {
              "additionalProperties": true,
              "type": "object"
            },
            {
              "type": "null"
            }
          ],
          "title": "Details",
          "description": "Optional, whatever is known, e.g. {\"signup_url\": ...} for api_key, {\"plan_url\": ..., \"price\": ...} for subscription, {\"networks\": [...]} for x402. Stored and published as given."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "type"
      ],
      "title": "PaymentMethodEntry",
      "description": "One way a listed service is paid for. `type` is one of PAYMENT_TYPES. `details` carries what\nis known (a price, a sign-up or plan URL, the networks an x402 service accepts, ...) - unknown\ndetail is simply left out; a type with nothing known is still a true statement."
    },
    "PaymentOption": {
      "properties": {
        "network": {
          "type": "string",
          "title": "Network",
          "description": "CAIP-2 chain id, e.g. 'eip155:8453' (Base) or 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp' (Solana mainnet). Supported namespaces: ['eip155', 'solana']."
        },
        "asset": {
          "type": "string",
          "title": "Asset",
          "description": "On-chain asset: an EVM token contract address (eip155) or a token mint address (solana)."
        },
        "pay_to": {
          "type": "string",
          "title": "Pay To",
          "description": "Address that receives payment on this network."
        },
        "amount": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Amount",
          "description": "Price in whole-token units as a decimal string, e.g. '0.02' (up to 18 decimal places)."
        },
        "unit": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Unit",
          "description": "What `amount` is charged per, as a lowercase slug, e.g. 'per_call', 'per_verification'."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "network",
        "asset",
        "pay_to"
      ],
      "title": "PaymentOption",
      "description": "One way to pay for a listing's service. Validated per network namespace:\neip155:* takes 0x EVM addresses, solana:* takes base58 addresses. Other\nnamespaces are rejected rather than accepted unchecked."
    },
    "VerifierInfoStatus": {
      "properties": {
        "status": {
          "type": "string",
          "enum": [
            "live",
            "last_known",
            "partial",
            "unavailable"
          ],
          "title": "Status",
          "description": "live: read successfully and not since failed. last_known: the last successful values, kept because the latest refresh failed (or this process has not re-read them yet). partial: only one of the two documents has ever been read. unavailable: neither has - price/networks/free_path are null."
        },
        "fetched_at": {
          "anyOf": [
            {
              "type": "string",
              "format": "date-time"
            },
            {
              "type": "null"
            }
          ],
          "title": "Fetched At",
          "description": "When the (oldest) values shown were read."
        },
        "sources": {
          "items": {
            "type": "string"
          },
          "type": "array",
          "title": "Sources",
          "description": "The documents these facts come from."
        }
      },
      "type": "object",
      "required": [
        "status"
      ],
      "title": "VerifierInfoStatus",
      "description": "Provenance of the verifier facts on a verify_output action (price, networks, protocol,\nfree_path): read from the verifier's own public documents, cached, refreshed in the\nbackground. Never blocks or fails a listing response."
    }
  }
}

Work with this as data

Every JSON Schema 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 schemas

4 MCP tools reach this
  • find_json_schemasBrowse and filter every JSON Schema in the catalog.
  • 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 JSON Schema
curl "https://apis.io/api/v1/json-schemas/sarnai-dev-listing-response"
All schemas
curl "https://apis.io/api/v1/json-schemas?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.