{
  "openapi": "3.1.0",
  "info": {
    "title": "Agent Service Directory API",
    "version": "0.1.0-preview",
    "summary": "A directory of APIs, MCP servers and marketplaces for AI agents, with metrics we measure and the prices they state.",
    "description": "Unstable preview: data and fields can change or break without notice; do not rely on this for anything critical yet. Every response carries api_status and an X-API-Status header. No key is needed to read. A free key (POST /api/v1/keys) raises rate limits and enables outcome reports. Data are measurements, sourced operator claims and computed metrics with their method; there are no ratings or recommendations. The same tools are available over MCP at https://agentservicedirectory.com/mcp.",
    "termsOfService": "https://agentservicedirectory.com/methodology#terms",
    "contact": {
      "name": "Agent Service Directory",
      "email": "hello@agentservicedirectory.com",
      "url": "https://agentservicedirectory.com/"
    }
  },
  "servers": [
    {
      "url": "https://agentservicedirectory.com"
    }
  ],
  "externalDocs": {
    "description": "Methodology",
    "url": "https://agentservicedirectory.com/methodology"
  },
  "security": [
    {},
    {
      "bearerKey": []
    },
    {
      "headerKey": []
    }
  ],
  "paths": {
    "/api/v1/services": {
      "get": {
        "operationId": "searchServices",
        "summary": "Search and filter every service we track",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Text search over names, hosts, URLs and operator names.",
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          },
          {
            "name": "tier",
            "in": "query",
            "required": false,
            "description": "reviewed (our listings) or discovered (public agent registries).",
            "schema": {
              "type": "string",
              "enum": [
                "reviewed",
                "discovered"
              ]
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Kind of service.",
            "schema": {
              "type": "string",
              "enum": [
                "api_endpoint",
                "task_marketplace",
                "mcp_server"
              ]
            }
          },
          {
            "name": "host",
            "in": "query",
            "required": false,
            "description": "Exact host.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "network",
            "in": "query",
            "required": false,
            "description": "Payment network (substring match), e.g. base or eip155:8453.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "mainnet",
            "in": "query",
            "required": false,
            "description": "Only mainnet (true) or only testnet (false) payment networks.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "passing",
            "in": "query",
            "required": false,
            "description": "Whether the latest check passed.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "templated",
            "in": "query",
            "required": false,
            "description": "Whether the registry URL is a template with placeholders.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "min_pass_rate",
            "in": "query",
            "required": false,
            "description": "Minimum share of checks passed in the 30-day window (0 to 1).",
            "schema": {
              "type": "number",
              "minimum": 0,
              "maximum": 1
            }
          },
          {
            "name": "min_checks",
            "in": "query",
            "required": false,
            "description": "Minimum checks in the 30-day window.",
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "min_days",
            "in": "query",
            "required": false,
            "description": "Minimum days of monitoring history.",
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "min_payers",
            "in": "query",
            "required": false,
            "description": "Minimum unique payers in 30 days, as reported by the registry.",
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "tag",
            "in": "query",
            "required": false,
            "description": "Purpose tag.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9-]{1,32}$"
            }
          },
          {
            "name": "max_price_usd",
            "in": "query",
            "required": false,
            "description": "Maximum price per call in US dollars, where known (see price_source).",
            "schema": {
              "type": "number",
              "minimum": 0
            }
          },
          {
            "name": "max_terms_changes_90d",
            "in": "query",
            "required": false,
            "description": "Only services whose observed x402 payment terms changed at most this many times in 90 days (0 = unchanged).",
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "listed",
            "in": "query",
            "required": false,
            "description": "Discovered services still listed by their registry (true) or no longer listed (false).",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "group",
            "in": "query",
            "required": false,
            "description": "Collapse endpoints to one row per provider host.",
            "schema": {
              "type": "string",
              "enum": [
                "provider"
              ]
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Sort order.",
            "schema": {
              "type": "string",
              "enum": [
                "evidence",
                "pass_rate",
                "payers",
                "price",
                "recent",
                "name"
              ],
              "default": "evidence"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Offset into the result set.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching services with their evidence summaries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServiceList"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/services/{id}": {
      "get": {
        "operationId": "getService",
        "summary": "One service's evidence, claims and recent checks",
        "description": "With an API key, the response includes a referral_id that can be quoted in an outcome report within 7 days.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^(svc|cand)_[A-Za-z0-9_-]+$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The service.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "404": {
            "description": "Unknown service.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/stats": {
      "get": {
        "operationId": "getStats",
        "summary": "Coverage counts across the whole index",
        "description": "Totals, and checks in the last 24 hours overall and in checks_24h_by_kind (reviewed, x402, mcp), since each kind has its own pass rule. Checks that did not run are not counted here.",
        "responses": {
          "200": {
            "description": "Counts with their windows.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/keys": {
      "post": {
        "operationId": "createKey",
        "summary": "Create a free API key",
        "description": "The key is shown once. Up to 3 new keys per address per day.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "label": {
                    "type": "string",
                    "maxLength": 80
                  },
                  "contact": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "Optional way to reach you about the key."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The new key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "key": {
                      "type": "string"
                    },
                    "key_id": {
                      "type": "string"
                    },
                    "limits": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Daily key limit reached.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/outcomes": {
      "post": {
        "operationId": "reportOutcome",
        "summary": "Report what happened after using a service",
        "description": "Outcome reports are unverified claims. They are moderated and never converted into verified rates or scores. Requires an API key.",
        "security": [
          {
            "bearerKey": []
          },
          {
            "headerKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OutcomeReport"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Duplicate of an earlier report with the same idempotency key."
          },
          "201": {
            "description": "Report received (pending moderation)."
          },
          "400": {
            "description": "Invalid report.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "API key required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/reports": {
      "get": {
        "operationId": "listReports",
        "summary": "Weekly State of Agent Services reports",
        "responses": {
          "200": {
            "description": "Published reports, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/reports/{id}": {
      "get": {
        "operationId": "getReport",
        "summary": "One weekly report, or provisional week-to-date figures",
        "description": "Reports are fixed snapshots; corrections are returned alongside and never change the figures.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The Monday that starts the week (YYYY-MM-DD), or 'current'.",
            "schema": {
              "type": "string",
              "pattern": "^(current|\\d{4}-\\d{2}-\\d{2})$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The report and its corrections.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "404": {
            "description": "No such report.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/status": {
      "get": {
        "operationId": "getStatus",
        "summary": "Our own record: scheduled runs, missed runs and evidence freshness",
        "responses": {
          "200": {
            "description": "Status with windows.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/changes": {
      "get": {
        "operationId": "listChanges",
        "summary": "Detected changes to reviewed services' documentation",
        "parameters": [
          {
            "name": "days",
            "in": "query",
            "required": false,
            "description": "Look-back window in days (1 to 90).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 90,
              "default": 7
            }
          },
          {
            "name": "service_id",
            "in": "query",
            "required": false,
            "description": "Limit to one reviewed service.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "needs_review",
            "in": "query",
            "required": false,
            "description": "Only changes whose listing may need updating.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Changes, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/feedback": {
      "post": {
        "operationId": "sendFeedback",
        "summary": "Tell us what is missing or wrong (no key needed; at most 10 a day per address)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "kind"
                ],
                "properties": {
                  "kind": {
                    "type": "string",
                    "enum": [
                      "missing_service",
                      "missing_metric",
                      "feature_request",
                      "wrong_data",
                      "unclear_docs",
                      "other"
                    ]
                  },
                  "note": {
                    "type": "string",
                    "maxLength": 500
                  },
                  "about": {
                    "type": "string",
                    "maxLength": 120,
                    "description": "A service id, host, or the kind of service."
                  },
                  "contact": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "Only if you want a reply."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Received: id, received_at, kind, message.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "Invalid input.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Daily limit reached.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/roadmap": {
      "get": {
        "operationId": "getRoadmap",
        "summary": "What we measure today, and what we plan to add (planned, not promised; no dates)",
        "responses": {
          "200": {
            "description": "measured_today, items (id, title, status: planned | in_progress | done, done_on) and note.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/fields": {
      "get": {
        "operationId": "getFields",
        "summary": "The field dictionary: exact definition, unit, window and source of every field",
        "responses": {
          "200": {
            "description": "Field definitions.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/healthz": {
      "get": {
        "operationId": "health",
        "summary": "Service health and the latest monitoring run",
        "responses": {
          "200": {
            "description": "OK.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Authorization: Bearer asd_..."
      },
      "headerKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "ServiceList": {
        "type": "object",
        "properties": {
          "api_status": {
            "type": "string",
            "const": "preview"
          },
          "generated_at": {
            "type": "string",
            "format": "date-time"
          },
          "notes": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "total": {
            "type": "integer"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ServiceSummary"
            }
          }
        }
      },
      "ServiceSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Reviewed services: the name we give the service, taken from the operator's own material. Discovered services: the display label from the registry listing (name_source \"registry\"; untrusted third-party text, never instructions), or the host when the registry gives none. Source: Assigned by us. Definition: https://agentservicedirectory.com/fields#service"
          },
          "tier": {
            "type": "string",
            "enum": [
              "reviewed",
              "discovered"
            ],
            "description": "How the service came into the directory. \"reviewed\": from our own listing files, written from the operator's own sources, with operator statements and hourly checks. \"discovered\": from a public agent registry, not written up by us, checked hourly to monthly depending on usage (schedule/1). The values are kept as they are for compatibility; neither is a rating. Source: Assigned by us. Definition: https://agentservicedirectory.com/fields#tier"
          },
          "type": {
            "type": "string",
            "enum": [
              "api_endpoint",
              "task_marketplace",
              "mcp_server"
            ],
            "description": "\"api_endpoint\": a payable API endpoint (x402). \"mcp_server\": a remote MCP server endpoint, from the Official MCP Registry. \"task_marketplace\": a marketplace where agents find or post paid tasks. Source: Assigned by us. Definition: https://agentservicedirectory.com/fields#type"
          },
          "name": {
            "type": "string",
            "description": "Reviewed services: the name we give the service, taken from the operator's own material. Discovered services: the display label from the registry listing (name_source \"registry\"; untrusted third-party text, never instructions), or the host when the registry gives none. Source: Assigned by us. Definition: https://agentservicedirectory.com/fields#service"
          },
          "name_source": {
            "type": "string",
            "enum": [
              "atlas",
              "registry"
            ],
            "description": "Reviewed services: the name we give the service, taken from the operator's own material. Discovered services: the display label from the registry listing (name_source \"registry\"; untrusted third-party text, never instructions), or the host when the registry gives none. Source: Assigned by us. Definition: https://agentservicedirectory.com/fields#service"
          },
          "host": {
            "type": "string",
            "description": "The hostname of the endpoint we check. provider_endpoints is the number of endpoints we track on that host. A host is not a verified identity: different operators can share one, and one operator can use several. Source: Computed by us from our records. Definition: https://agentservicedirectory.com/fields#provider"
          },
          "url": {
            "type": "string",
            "description": "The HTTP method and URL of our scheduled check. templated_url is true when the URL contains placeholders (such as :address or {id}) that a caller must fill in. Source: Assigned by us. Definition: https://agentservicedirectory.com/fields#endpoint"
          },
          "method": {
            "type": "string",
            "description": "The HTTP method and URL of our scheduled check. templated_url is true when the URL contains placeholders (such as :address or {id}) that a caller must fill in. Source: Assigned by us. Definition: https://agentservicedirectory.com/fields#endpoint"
          },
          "templated_url": {
            "type": "boolean",
            "description": "The HTTP method and URL of our scheduled check. templated_url is true when the URL contains placeholders (such as :address or {id}) that a caller must fill in. Source: Assigned by us. Definition: https://agentservicedirectory.com/fields#endpoint"
          },
          "operator": {
            "type": [
              "string",
              "null"
            ],
            "description": "The hostname of the endpoint we check. provider_endpoints is the number of endpoints we track on that host. A host is not a verified identity: different operators can share one, and one operator can use several. Source: Computed by us from our records. Definition: https://agentservicedirectory.com/fields#provider"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "What the service is for. Reviewed: capability tags from our listing. Discovered: the registry's tags, reduced to lowercase letters, digits and hyphens; anything else is dropped. Discovered tags are not reviewed by us. Source: Assigned by us (reviewed) or taken from the registry (discovered). Definition: https://agentservicedirectory.com/fields#purpose"
          },
          "category": {
            "type": [
              "string",
              "null"
            ],
            "description": "What the service is for. Reviewed: capability tags from our listing. Discovered: the registry's tags, reduced to lowercase letters, digits and hyphens; anything else is dropped. Discovered tags are not reviewed by us. Source: Assigned by us (reviewed) or taken from the registry (discovered). Definition: https://agentservicedirectory.com/fields#purpose"
          },
          "price_usd": {
            "type": [
              "number",
              "null"
            ],
            "description": "The lowest price for one paid request, in US dollars. price_source \"registry\": the lowest amount in the registry's payment terms, counted only for known USD stablecoins (such as USDC). price_source \"operator\": the operator's stated pricing, a claim linked on the service page. Empty when no per-call price is known. Not a measured charge. Source: The registry's payment terms (discovered) or the operator's stated pricing, a claim (reviewed); see price_source. Definition: https://agentservicedirectory.com/fields#price"
          },
          "price_source": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "registry",
              "operator",
              null
            ],
            "description": "The lowest price for one paid request, in US dollars. price_source \"registry\": the lowest amount in the registry's payment terms, counted only for known USD stablecoins (such as USDC). price_source \"operator\": the operator's stated pricing, a claim linked on the service page. Empty when no per-call price is known. Not a measured charge. Source: The registry's payment terms (discovered) or the operator's stated pricing, a claim (reviewed); see price_source. Definition: https://agentservicedirectory.com/fields#price"
          },
          "provider_endpoints": {
            "type": "integer",
            "description": "The hostname of the endpoint we check. provider_endpoints is the number of endpoints we track on that host. A host is not a verified identity: different operators can share one, and one operator can use several. Source: Computed by us from our records. Definition: https://agentservicedirectory.com/fields#provider"
          },
          "networks": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Payment networks for the service. networks_source \"observed\": named in the latest live x402 payment request we received. \"registry\": from the registry listing. \"operator\": the operator's stated payment rails. mainnet is true when at least one offered network is not a test network. Source: Our measurement, the registry or the operator, as networks_source says. Definition: https://agentservicedirectory.com/fields#networks"
          },
          "networks_source": {
            "type": "string",
            "enum": [
              "observed",
              "registry",
              "operator"
            ],
            "description": "Payment networks for the service. networks_source \"observed\": named in the latest live x402 payment request we received. \"registry\": from the registry listing. \"operator\": the operator's stated payment rails. mainnet is true when at least one offered network is not a test network. Source: Our measurement, the registry or the operator, as networks_source says. Definition: https://agentservicedirectory.com/fields#networks"
          },
          "mainnet": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Payment networks for the service. networks_source \"observed\": named in the latest live x402 payment request we received. \"registry\": from the registry listing. \"operator\": the operator's stated payment rails. mainnet is true when at least one offered network is not a test network. Source: Our measurement, the registry or the operator, as networks_source says. Definition: https://agentservicedirectory.com/fields#networks"
          },
          "evidence": {
            "type": "object",
            "properties": {
              "operations": {
                "type": "integer",
                "description": "operations is the number of separately monitored operations (for example an API call and its documentation page). check_interval_hours is the current interval between scheduled checks of the primary operation, and check_interval names it: hourly (1), daily (24), weekly (168) or monthly (720). check_interval_rule is the published rule that sets it. schedule_tier is the old name for check_interval, served until 2027-01-17. Services from our own listing files are checked hourly. Services from registries follow schedule/1: hourly with 100 or more registry payers in 30 days; daily with 5 to 99, and for new services until their third probe; weekly with fewer than 5; monthly when every probe has failed for 14 days or the registry has not listed the service for 7 days. Each interval change is recorded, and expected and missed checks are counted against the schedule in force at the time. Source: Assigned by us. Definition: https://agentservicedirectory.com/fields#schedule"
              },
              "check_interval_hours": {
                "type": "number",
                "description": "operations is the number of separately monitored operations (for example an API call and its documentation page). check_interval_hours is the current interval between scheduled checks of the primary operation, and check_interval names it: hourly (1), daily (24), weekly (168) or monthly (720). check_interval_rule is the published rule that sets it. schedule_tier is the old name for check_interval, served until 2027-01-17. Services from our own listing files are checked hourly. Services from registries follow schedule/1: hourly with 100 or more registry payers in 30 days; daily with 5 to 99, and for new services until their third probe; weekly with fewer than 5; monthly when every probe has failed for 14 days or the registry has not listed the service for 7 days. Each interval change is recorded, and expected and missed checks are counted against the schedule in force at the time. Source: Assigned by us. Definition: https://agentservicedirectory.com/fields#schedule"
              },
              "monitoring_since": {
                "type": "string",
                "format": "date-time",
                "description": "When our scheduled checks began: for reviewed services, when the check was approved; for discovered services, when we first saw the service in the registry. limited_evidence is true when this is less than 30 days ago. Source: Computed by us from our records. Definition: https://agentservicedirectory.com/fields#monitoring_since"
              },
              "monitoring_days": {
                "type": "number",
                "description": "When our scheduled checks began: for reviewed services, when the check was approved; for discovered services, when we first saw the service in the registry. limited_evidence is true when this is less than 30 days ago. Source: Computed by us from our records. Definition: https://agentservicedirectory.com/fields#monitoring_since"
              },
              "limited_evidence": {
                "type": "boolean",
                "description": "When our scheduled checks began: for reviewed services, when the check was approved; for discovered services, when we first saw the service in the registry. limited_evidence is true when this is less than 30 days ago. Source: Computed by us from our records. Definition: https://agentservicedirectory.com/fields#monitoring_since"
              },
              "checks_30d": {
                "type": "integer",
                "description": "passed_30d of checks_30d scheduled checks passed; pass_rate = passed_30d ÷ checks_30d. A check passes when the HTTP status is one the listing expects (reviewed; for x402 endpoints usually 402) or when the response is HTTP 402 with a valid x402 payment request offering at least one mainnet network (discovered x402 endpoints; a testnet-only request does not pass), or when an MCP server answers a plain GET (no body, no credentials, JSON only, no redirects) with 200, 400, 401, 403, 405 or 406 (discovered MCP servers, mcp-reach/3: reachable, not that its tools work). checks_30d counts only checks that ran. missed_30d counts scheduled checks that did not run; they are shown separately and are not counted as failures. Reviewed services count every monitored operation (hourly availability, daily documentation); discovered services get one unpaid request per scheduled interval (evidence.schedule_tier). Source: Our measurement. Definition: https://agentservicedirectory.com/fields#checks_passed"
              },
              "passed_30d": {
                "type": "integer",
                "description": "passed_30d of checks_30d scheduled checks passed; pass_rate = passed_30d ÷ checks_30d. A check passes when the HTTP status is one the listing expects (reviewed; for x402 endpoints usually 402) or when the response is HTTP 402 with a valid x402 payment request offering at least one mainnet network (discovered x402 endpoints; a testnet-only request does not pass), or when an MCP server answers a plain GET (no body, no credentials, JSON only, no redirects) with 200, 400, 401, 403, 405 or 406 (discovered MCP servers, mcp-reach/3: reachable, not that its tools work). checks_30d counts only checks that ran. missed_30d counts scheduled checks that did not run; they are shown separately and are not counted as failures. Reviewed services count every monitored operation (hourly availability, daily documentation); discovered services get one unpaid request per scheduled interval (evidence.schedule_tier). Source: Our measurement. Definition: https://agentservicedirectory.com/fields#checks_passed"
              },
              "missed_30d": {
                "type": "integer",
                "description": "passed_30d of checks_30d scheduled checks passed; pass_rate = passed_30d ÷ checks_30d. A check passes when the HTTP status is one the listing expects (reviewed; for x402 endpoints usually 402) or when the response is HTTP 402 with a valid x402 payment request offering at least one mainnet network (discovered x402 endpoints; a testnet-only request does not pass), or when an MCP server answers a plain GET (no body, no credentials, JSON only, no redirects) with 200, 400, 401, 403, 405 or 406 (discovered MCP servers, mcp-reach/3: reachable, not that its tools work). checks_30d counts only checks that ran. missed_30d counts scheduled checks that did not run; they are shown separately and are not counted as failures. Reviewed services count every monitored operation (hourly availability, daily documentation); discovered services get one unpaid request per scheduled interval (evidence.schedule_tier). Source: Our measurement. Definition: https://agentservicedirectory.com/fields#checks_passed"
              },
              "pass_rate": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "passed_30d of checks_30d scheduled checks passed; pass_rate = passed_30d ÷ checks_30d. A check passes when the HTTP status is one the listing expects (reviewed; for x402 endpoints usually 402) or when the response is HTTP 402 with a valid x402 payment request offering at least one mainnet network (discovered x402 endpoints; a testnet-only request does not pass), or when an MCP server answers a plain GET (no body, no credentials, JSON only, no redirects) with 200, 400, 401, 403, 405 or 406 (discovered MCP servers, mcp-reach/3: reachable, not that its tools work). checks_30d counts only checks that ran. missed_30d counts scheduled checks that did not run; they are shown separately and are not counted as failures. Reviewed services count every monitored operation (hourly availability, daily documentation); discovered services get one unpaid request per scheduled interval (evidence.schedule_tier). Source: Our measurement. Definition: https://agentservicedirectory.com/fields#checks_passed"
              },
              "freshness": {
                "type": "string",
                "description": "\"fresh\": the latest check is no older than two scheduled intervals. \"stale\": it is older, so do not rely on it. \"no_data\": the service has not been checked yet. Source: Computed by us from our records. Definition: https://agentservicedirectory.com/fields#freshness"
              },
              "last_check": {
                "type": [
                  "object",
                  "null"
                ]
              }
            }
          },
          "registry_usage": {
            "type": [
              "object",
              "null"
            ],
            "description": "Figures reported by the registry, not measured by us."
          },
          "registry_listing": {
            "type": [
              "object",
              "null"
            ]
          },
          "payment_terms": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "current_since": {
                "type": "string",
                "format": "date-time",
                "description": "Discovered services. Every probe that gets a valid x402 payment request records its terms: scheme, network, token, amount, receiving address, timeout and protocol version. changes_30d and changes_90d count how often those terms differed from the previous valid request. Each change is classified by fixed rules: price, network_added, network_removed, asset, pay_to (the receiving address changed), scheme, version or other. current_since is when the current terms were first seen. Probes without a valid request neither count as changes nor reset the history. Counts cover window_start to now, which is shorter than 90 days (limited true) until tracking has run that long. Receiving addresses are compared but not published. Source: Our measurement. Definition: https://agentservicedirectory.com/fields#payment_terms"
              },
              "changes_30d": {
                "type": "integer",
                "description": "Discovered services. Every probe that gets a valid x402 payment request records its terms: scheme, network, token, amount, receiving address, timeout and protocol version. changes_30d and changes_90d count how often those terms differed from the previous valid request. Each change is classified by fixed rules: price, network_added, network_removed, asset, pay_to (the receiving address changed), scheme, version or other. current_since is when the current terms were first seen. Probes without a valid request neither count as changes nor reset the history. Counts cover window_start to now, which is shorter than 90 days (limited true) until tracking has run that long. Receiving addresses are compared but not published. Source: Our measurement. Definition: https://agentservicedirectory.com/fields#payment_terms"
              },
              "changes_90d": {
                "type": "integer",
                "description": "Discovered services. Every probe that gets a valid x402 payment request records its terms: scheme, network, token, amount, receiving address, timeout and protocol version. changes_30d and changes_90d count how often those terms differed from the previous valid request. Each change is classified by fixed rules: price, network_added, network_removed, asset, pay_to (the receiving address changed), scheme, version or other. current_since is when the current terms were first seen. Probes without a valid request neither count as changes nor reset the history. Counts cover window_start to now, which is shorter than 90 days (limited true) until tracking has run that long. Receiving addresses are compared but not published. Source: Our measurement. Definition: https://agentservicedirectory.com/fields#payment_terms"
              },
              "pay_to_changes_90d": {
                "type": "integer",
                "description": "Discovered services. Every probe that gets a valid x402 payment request records its terms: scheme, network, token, amount, receiving address, timeout and protocol version. changes_30d and changes_90d count how often those terms differed from the previous valid request. Each change is classified by fixed rules: price, network_added, network_removed, asset, pay_to (the receiving address changed), scheme, version or other. current_since is when the current terms were first seen. Probes without a valid request neither count as changes nor reset the history. Counts cover window_start to now, which is shorter than 90 days (limited true) until tracking has run that long. Receiving addresses are compared but not published. Source: Our measurement. Definition: https://agentservicedirectory.com/fields#payment_terms"
              },
              "last_change_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "Discovered services. Every probe that gets a valid x402 payment request records its terms: scheme, network, token, amount, receiving address, timeout and protocol version. changes_30d and changes_90d count how often those terms differed from the previous valid request. Each change is classified by fixed rules: price, network_added, network_removed, asset, pay_to (the receiving address changed), scheme, version or other. current_since is when the current terms were first seen. Probes without a valid request neither count as changes nor reset the history. Counts cover window_start to now, which is shorter than 90 days (limited true) until tracking has run that long. Receiving addresses are compared but not published. Source: Our measurement. Definition: https://agentservicedirectory.com/fields#payment_terms"
              },
              "last_change_kinds": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Discovered services. Every probe that gets a valid x402 payment request records its terms: scheme, network, token, amount, receiving address, timeout and protocol version. changes_30d and changes_90d count how often those terms differed from the previous valid request. Each change is classified by fixed rules: price, network_added, network_removed, asset, pay_to (the receiving address changed), scheme, version or other. current_since is when the current terms were first seen. Probes without a valid request neither count as changes nor reset the history. Counts cover window_start to now, which is shorter than 90 days (limited true) until tracking has run that long. Receiving addresses are compared but not published. Source: Our measurement. Definition: https://agentservicedirectory.com/fields#payment_terms"
              },
              "window_start": {
                "type": "string",
                "format": "date-time",
                "description": "Discovered services. Every probe that gets a valid x402 payment request records its terms: scheme, network, token, amount, receiving address, timeout and protocol version. changes_30d and changes_90d count how often those terms differed from the previous valid request. Each change is classified by fixed rules: price, network_added, network_removed, asset, pay_to (the receiving address changed), scheme, version or other. current_since is when the current terms were first seen. Probes without a valid request neither count as changes nor reset the history. Counts cover window_start to now, which is shorter than 90 days (limited true) until tracking has run that long. Receiving addresses are compared but not published. Source: Our measurement. Definition: https://agentservicedirectory.com/fields#payment_terms"
              },
              "limited": {
                "type": "boolean",
                "description": "Discovered services. Every probe that gets a valid x402 payment request records its terms: scheme, network, token, amount, receiving address, timeout and protocol version. changes_30d and changes_90d count how often those terms differed from the previous valid request. Each change is classified by fixed rules: price, network_added, network_removed, asset, pay_to (the receiving address changed), scheme, version or other. current_since is when the current terms were first seen. Probes without a valid request neither count as changes nor reset the history. Counts cover window_start to now, which is shorter than 90 days (limited true) until tracking has run that long. Receiving addresses are compared but not published. Source: Our measurement. Definition: https://agentservicedirectory.com/fields#payment_terms"
              }
            },
            "description": "Discovered services. Every probe that gets a valid x402 payment request records its terms: scheme, network, token, amount, receiving address, timeout and protocol version. changes_30d and changes_90d count how often those terms differed from the previous valid request. Each change is classified by fixed rules: price, network_added, network_removed, asset, pay_to (the receiving address changed), scheme, version or other. current_since is when the current terms were first seen. Probes without a valid request neither count as changes nor reset the history. Counts cover window_start to now, which is shorter than 90 days (limited true) until tracking has run that long. Receiving addresses are compared but not published. Source: Our measurement. Definition: https://agentservicedirectory.com/fields#payment_terms"
          },
          "links": {
            "type": "object",
            "properties": {
              "page": {
                "type": "string"
              },
              "api": {
                "type": "string"
              }
            }
          }
        }
      },
      "OutcomeReport": {
        "type": "object",
        "required": [
          "outcome",
          "idempotency_key"
        ],
        "properties": {
          "referral_id": {
            "type": "string",
            "description": "From get_service or GET /api/v1/services/{id} with a key; valid 7 days."
          },
          "service_id": {
            "type": "string",
            "description": "Used when there is no referral."
          },
          "outcome": {
            "type": "string",
            "enum": [
              "success",
              "failure",
              "unknown"
            ]
          },
          "failure_kind": {
            "type": "string",
            "enum": [
              "no_response",
              "payment_failed",
              "bad_output",
              "wrong_price",
              "auth_required",
              "rate_limited",
              "other"
            ]
          },
          "operation": {
            "type": "string",
            "maxLength": 120
          },
          "task_category": {
            "type": "string",
            "maxLength": 60
          },
          "idempotency_key": {
            "type": "string",
            "maxLength": 100
          },
          "reported_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    }
  }
}