{
  "openapi": "3.1.0",
  "info": {
    "title": "SourceTier API",
    "version": "0.1.0",
    "summary": "The global intelligence, discovery and buying platform for technology.",
    "description": "Every value is returned with its verification state, confidence, observation date and sources. A verification_state of \"unknown\" describes our research (searched, nothing reliable found), never the product. Values that hold for one edition, region or package only are returned as scoped_attributes and are never merged into attributes. The same data is available to agents over the Model Context Protocol at https://sourcetier.com/mcp.",
    "contact": {
      "url": "https://sourcetier.com/imprint"
    },
    "x-mcp": {
      "endpoint": "https://sourcetier.com/mcp",
      "transport": "streamable-http",
      "authentication": "none"
    }
  },
  "externalDocs": {
    "url": "https://sourcetier.com/developers",
    "description": "Developer documentation, MCP setup, evidence contract."
  },
  "servers": [
    {
      "url": "https://sourcetier.com"
    }
  ],
  "paths": {
    "/api/v1/": {
      "get": {
        "operationId": "index",
        "summary": "Endpoint list, evidence contract, MCP and OpenAPI addresses.",
        "responses": {
          "200": {
            "description": "The index.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "required": [
                    "name",
                    "version",
                    "endpoints",
                    "mcp",
                    "openapi"
                  ],
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "version": {
                      "type": "string"
                    },
                    "endpoints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "openapi": {
                      "type": "string",
                      "format": "uri"
                    },
                    "mcp": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "evidence_contract": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/methodology": {
      "get": {
        "operationId": "methodology",
        "summary": "Source tiers, confidence formula, publishing gates, measured reader precision.",
        "responses": {
          "200": {
            "description": "Read from the code that applies it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/organizations": {
      "get": {
        "operationId": "listOrganizations",
        "summary": "All organizations with product counts.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The next_cursor of the previous page. Overrides offset."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of the list.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Page"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "organizations": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true,
                            "properties": {
                              "slug": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              },
                              "kind": {
                                "type": "string"
                              },
                              "product_count": {
                                "type": "integer"
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/categories": {
      "get": {
        "operationId": "listCategories",
        "summary": "All categories with path and product counts.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The next_cursor of the previous page. Overrides offset."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of the list.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Page"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "categories": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true,
                            "properties": {
                              "slug": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              },
                              "path": {
                                "type": "string"
                              },
                              "product_count": {
                                "type": "integer"
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/attributes": {
      "get": {
        "operationId": "listAttributes",
        "summary": "All attribute definitions: key, type, unit, which kinds they apply to.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The next_cursor of the previous page. Overrides offset."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of the list.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Page"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "attributes": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true,
                            "properties": {
                              "key": {
                                "type": "string"
                              },
                              "label": {
                                "type": "string"
                              },
                              "type": {
                                "type": "string"
                              },
                              "unit": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "applies_to": {},
                              "comparable": {
                                "type": [
                                  "boolean",
                                  "null"
                                ]
                              },
                              "higher_is_better": {
                                "type": [
                                  "boolean",
                                  "null"
                                ]
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/products": {
      "get": {
        "operationId": "listProducts",
        "summary": "Products, filterable by kind, category and vendor.",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Product kind, e.g. software, hardware, ai_agent, service."
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Category slug."
          },
          {
            "name": "vendor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Vendor slug."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The next_cursor of the previous page. Overrides offset."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of the list.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Page"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "products": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ProductSummary"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/products.csv": {
      "get": {
        "operationId": "listProductsCsv",
        "summary": "The product list as CSV (same filters and paging); total and next cursor in the X-Total and X-Next-Cursor headers.",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Product kind."
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Category slug."
          },
          {
            "name": "vendor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Vendor slug."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The next_cursor of the previous page. Overrides offset."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of the list as CSV.",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/products/{slug}": {
      "get": {
        "operationId": "getProduct",
        "summary": "One product with every attribute, its evidence, scoped values, withdrawals and identifiers.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The slug as returned by the list and search endpoints."
          }
        ],
        "responses": {
          "200": {
            "description": "The product.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Product"
                }
              }
            }
          },
          "404": {
            "description": "No entity with this slug.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/products/{slug}/prices": {
      "get": {
        "operationId": "getProductPrices",
        "summary": "Price observations, statistics per window and the deal assessment with its reasons.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The slug as returned by the list and search endpoints."
          }
        ],
        "responses": {
          "200": {
            "description": "Price lines.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "slug": {
                      "type": "string"
                    },
                    "contract": {
                      "type": "string"
                    },
                    "lines": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No entity with this slug.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/products/{slug}/changes": {
      "get": {
        "operationId": "getProductChanges",
        "summary": "The timeline of one product.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The slug as returned by the list and search endpoints."
          },
          {
            "name": "all",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Pass 1 to include changes that are not material."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Changes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "slug": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "changes": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Change"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No entity with this slug.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/products/{slug}/record": {
      "get": {
        "operationId": "getProductRecord",
        "summary": "The statements our record held for one product at a date or moment (as_of), each with its statement_id.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The slug as returned by the list and search endpoints."
          },
          {
            "name": "as_of",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "A date (YYYY-MM-DD, meaning the end of that day in Europe/Berlin time, the zone of every retrieved_on date) or an ISO 8601 timestamp with a time zone.",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "The record at as_of.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "required": [
                    "slug",
                    "as_of",
                    "statements",
                    "contract"
                  ],
                  "properties": {
                    "slug": {
                      "type": "string"
                    },
                    "as_of": {
                      "type": "string"
                    },
                    "as_of_moment": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "first_recorded_at": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "before_first_record": {
                      "type": "boolean"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "statements": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/StatementVersion"
                      }
                    },
                    "contract": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "as_of is missing, not a date or in the future.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No entity with this slug.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/statements/{id}": {
      "get": {
        "operationId": "getStatement",
        "summary": "Every version of one statement under its stable id, with the changes attached to it.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^st_[0-9a-f]{20}$"
            },
            "description": "The statement_id from an attribute, a scoped value or a change."
          }
        ],
        "responses": {
          "200": {
            "description": "The statement and its versions.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "required": [
                    "statement_id",
                    "attribute",
                    "versions",
                    "contract"
                  ],
                  "properties": {
                    "statement_id": {
                      "type": "string"
                    },
                    "subject": {},
                    "attribute": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "scope": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "region": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "current": {},
                    "version_count": {
                      "type": "integer"
                    },
                    "versions": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/StatementVersion"
                      }
                    },
                    "changes": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Change"
                      }
                    },
                    "page_url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "contract": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "301": {
            "description": "The statement moved to another id after two duplicate entities were merged; Location names it."
          },
          "404": {
            "description": "No statement with this id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vendors/{slug}": {
      "get": {
        "operationId": "getVendor",
        "summary": "One organization with attributes, products and register identifiers.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The slug as returned by the list and search endpoints."
          }
        ],
        "responses": {
          "200": {
            "description": "The vendor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Vendor"
                }
              }
            }
          },
          "404": {
            "description": "No entity with this slug.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents": {
      "get": {
        "operationId": "listAgents",
        "summary": "AI agents with their estimated autonomy level and every contribution to it.",
        "parameters": [
          {
            "name": "vendor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Vendor slug."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Agents.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "contract": {
                      "type": "string"
                    },
                    "agents": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{slug}": {
      "get": {
        "operationId": "getAgent",
        "summary": "One AI agent with its estimated autonomy level, attributes and identifiers.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The slug as returned by the list and search endpoints."
          }
        ],
        "responses": {
          "200": {
            "description": "The agent.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "404": {
            "description": "No entity with this slug.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/integrations": {
      "get": {
        "operationId": "listIntegrations",
        "summary": "Documented integration edges with sources.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Integrations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EdgeList"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/integrations/{slug}": {
      "get": {
        "operationId": "getIntegrations",
        "summary": "Documented integrations of one product.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The slug as returned by the list and search endpoints."
          }
        ],
        "responses": {
          "200": {
            "description": "Integrations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EdgeList"
                }
              }
            }
          },
          "404": {
            "description": "No entity with this slug.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/alternatives": {
      "get": {
        "operationId": "listAlternatives",
        "summary": "Documented alternative_to edges, each with the vendor that stated it.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Alternatives.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EdgeList"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/alternatives/{slug}": {
      "get": {
        "operationId": "getAlternatives",
        "summary": "Documented alternatives to one product.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The slug as returned by the list and search endpoints."
          }
        ],
        "responses": {
          "200": {
            "description": "Alternatives.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EdgeList"
                }
              }
            }
          },
          "404": {
            "description": "No entity with this slug.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/compare": {
      "get": {
        "operationId": "compare",
        "summary": "Two products side by side, one row per shared attribute, with the decision and its reason.",
        "parameters": [
          {
            "name": "a",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "First product slug."
          },
          {
            "name": "b",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Second product slug."
          }
        ],
        "responses": {
          "200": {
            "description": "The comparison.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "required": [
                    "products",
                    "rows"
                  ],
                  "properties": {
                    "products": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Ref"
                      }
                    },
                    "rows": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "a and b are required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No entity with this slug.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/search": {
      "get": {
        "operationId": "search",
        "summary": "Structured search: full text plus attribute filters. Products with an undocumented filter stand under cannot_say.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Words to search for."
          },
          {
            "name": "kind",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Product kind."
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Category slug."
          },
          {
            "name": "vendor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Vendor slug."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "attribute filters",
            "in": "query",
            "description": "Any attribute key as a parameter: soc2=true, ram_gb.min=16, price_usd.max=900. Unknown keys are returned under unknown_filters.",
            "schema": {
              "type": "string"
            },
            "style": "form",
            "explode": true,
            "allowReserved": true
          }
        ],
        "responses": {
          "200": {
            "description": "Matches and cannot_say.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "query": {
                      "type": "string"
                    },
                    "unknown_filters": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "considered": {
                      "type": "integer",
                      "description": "How many products the filters were held against: every product in scope, not only the ones returned. The limit cuts the lists after filtering, matches first."
                    },
                    "matches": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SearchHit"
                      }
                    },
                    "cannot_say": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SearchHit"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/ask": {
      "get": {
        "operationId": "ask",
        "summary": "A question in words, read deterministically as filters; the reading is returned with the answer.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The question, up to 300 characters.",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "The reading and the answer. partial is true when a word could not be read as a filter or when a read requirement cannot be checked (requirements.not_checked: a household or team size, a device budget, a non-USD budget, each with its reason); matches is then empty and partial_matches carries the products with the open words. variant_matches are products whose editions document the value while the family does not. named lists a product or a vendor the question calls by name; the answer is then that product or that vendor's products. The website and the MCP tool ask_question share this evaluation.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "question": {
                      "type": "string"
                    },
                    "read": {},
                    "named": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "not_understood": {},
                    "partial": {
                      "type": "boolean"
                    },
                    "requirements": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "filters": {},
                    "matches": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "partial_matches": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "variant_matches": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "category_candidates": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "cannot_say": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "q is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/finder": {
      "get": {
        "operationId": "listFinderProfiles",
        "summary": "The published finder profiles with their inputs and weights.",
        "responses": {
          "200": {
            "description": "Profiles.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "profiles": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/finder/{profile}": {
      "get": {
        "operationId": "finder",
        "summary": "A ranked shortlist for one profile. Inputs are query parameters named after the profile's input keys.",
        "parameters": [
          {
            "name": "profile",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "A profile key from /api/v1/finder."
          },
          {
            "name": "inputs",
            "in": "query",
            "description": "Each input key of the profile as its own parameter, e.g. budget=1200.",
            "schema": {
              "type": "string"
            },
            "style": "form",
            "explode": true,
            "allowReserved": true
          }
        ],
        "responses": {
          "200": {
            "description": "Ranked, not_enough_data and ruled_out.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "profile": {
                      "type": "string"
                    },
                    "ranked": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "not_enough_data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "ruled_out": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Unknown profile; the message names the known ones.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/changes": {
      "get": {
        "operationId": "listChanges",
        "summary": "The change feed across the catalog, by alert type.",
        "parameters": [
          {
            "name": "since",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Earliest day, YYYY-MM-DD."
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated alert types: price_drop, price_increase, new_price, new_product, new_ai_agent, new_integration, new_alternative, security_certification, product_change, documented, research_update, funding, acquisition, source_changed."
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Category slug."
          },
          {
            "name": "statement_id",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Only changes attached to this stable statement id. Merged ids resolve to their target; unknown ids return an empty feed, never the global feed."
          },
          {
            "name": "all",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Pass 1 to include changes that are not material."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Changes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "since": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "types": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "contract": {
                      "type": "string"
                    },
                    "changes": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Change"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/export/{dataset}.json": {
      "get": {
        "operationId": "export",
        "summary": "Bulk export of products or claims. Needs a bulk licence key.",
        "parameters": [
          {
            "name": "dataset",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "products",
                "claims"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 20000,
              "default": 5000
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The next_cursor of the previous page. Overrides offset."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "security": [
          {
            "ApiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "A page of the export.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Page"
                    },
                    {
                      "type": "object",
                      "additionalProperties": true
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "The key is not of the bulk tier.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/export/{dataset}.csv": {
      "get": {
        "operationId": "exportCsv",
        "summary": "The bulk export as CSV; JSON-valued cells (attributes, sources) stay JSON. Needs a bulk licence key.",
        "parameters": [
          {
            "name": "dataset",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "products",
                "claims"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 20000,
              "default": 5000
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The next_cursor of the previous page. Overrides offset."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "security": [
          {
            "ApiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "A page of the export as CSV; total and next cursor in X-Total and X-Next-Cursor.",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "The key is not of the bulk tier.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Optional for every endpoint except the exports. Tiers: open (1000 requests per day); licensed (50000 requests per day); bulk (200000 requests per day, bulk export). Without a key the open tier applies. See /data-licensing."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "see": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "Page": {
        "type": "object",
        "required": [
          "count",
          "total",
          "offset",
          "limit",
          "next_cursor"
        ],
        "properties": {
          "count": {
            "type": "integer"
          },
          "total": {
            "type": "integer",
            "description": "Before paging."
          },
          "offset": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Pass back as cursor; null means you have everything."
          }
        }
      },
      "Ref": {
        "type": "object",
        "required": [
          "slug",
          "name"
        ],
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "Source": {
        "type": "object",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "tier": {
            "type": [
              "integer",
              "null"
            ],
            "description": "1 is best."
          },
          "type": {
            "type": [
              "string",
              "null"
            ]
          },
          "retrieved_on": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "role": {
            "type": "string",
            "enum": [
              "evidence",
              "checked_without_finding"
            ]
          }
        },
        "additionalProperties": true
      },
      "Attribute": {
        "type": "object",
        "required": [
          "verification_state",
          "confidence",
          "observed_on",
          "sources"
        ],
        "description": "One statement about a product or vendor with its evidence. The value is null when verification_state is unknown.",
        "properties": {
          "label": {
            "type": [
              "string",
              "null"
            ]
          },
          "value": {},
          "unit": {
            "type": [
              "string",
              "null"
            ]
          },
          "verification_state": {
            "type": "string",
            "enum": [
              "verified",
              "corroborated",
              "vendor_stated",
              "customer_reported",
              "estimated",
              "unknown"
            ]
          },
          "statement_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Stable across new values, withdrawals and merges; its history is under /api/v1/statements/{statement_id}."
          },
          "claim_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The current version; it changes when the value changes."
          },
          "confidence": {
            "type": [
              "number",
              "null"
            ]
          },
          "confidence_parts": {},
          "observed_on": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "last_checked_on": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "later_reads": {},
          "valid_from": {
            "type": [
              "string",
              "null"
            ]
          },
          "extraction": {},
          "reader": {
            "type": [
              "string",
              "null"
            ]
          },
          "parser_version": {},
          "method": {
            "type": [
              "string",
              "null"
            ]
          },
          "note": {
            "type": [
              "string",
              "null"
            ]
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Source"
            }
          }
        },
        "additionalProperties": true
      },
      "ProductSummary": {
        "type": "object",
        "required": [
          "slug",
          "name"
        ],
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "vendor_slug": {
            "type": "string"
          },
          "vendor": {
            "type": "string"
          },
          "evidence_density": {
            "type": "number"
          },
          "data_completeness": {
            "type": "number"
          }
        },
        "additionalProperties": true
      },
      "Product": {
        "type": "object",
        "required": [
          "slug",
          "name",
          "kind",
          "vendor",
          "attributes",
          "scoped_attributes",
          "withdrawn",
          "identifiers",
          "contract"
        ],
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "discontinued": {
            "type": "boolean"
          },
          "canonical_slug": {
            "type": "string"
          },
          "requested_slug": {
            "type": "string"
          },
          "vendor": {
            "$ref": "#/components/schemas/Ref"
          },
          "mark": {},
          "mark_attempt": {},
          "attributes": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/Attribute"
            }
          },
          "scoped_attributes": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "withdrawn": {
            "type": "object",
            "additionalProperties": true
          },
          "identifiers": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "contract": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "Vendor": {
        "type": "object",
        "required": [
          "slug",
          "name",
          "attributes",
          "products",
          "identifiers"
        ],
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "type": [
              "string",
              "null"
            ]
          },
          "mark": {},
          "mark_attempt": {},
          "attributes": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/Attribute"
            }
          },
          "withdrawn": {
            "type": "object",
            "additionalProperties": true
          },
          "products": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Ref"
            }
          },
          "identifiers": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        },
        "additionalProperties": true
      },
      "SearchHit": {
        "type": "object",
        "required": [
          "slug",
          "name"
        ],
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "vendor": {
            "type": [
              "string",
              "null"
            ]
          },
          "kind": {
            "type": [
              "string",
              "null"
            ]
          },
          "evidence_density": {
            "type": [
              "number",
              "null"
            ]
          },
          "data_completeness": {
            "type": [
              "number",
              "null"
            ]
          },
          "matched_filters": {
            "type": "array",
            "items": {}
          },
          "unresolved_filters": {
            "type": "array",
            "items": {}
          }
        },
        "additionalProperties": true
      },
      "Change": {
        "type": "object",
        "properties": {
          "id": {},
          "type": {
            "type": [
              "string",
              "null"
            ]
          },
          "label": {
            "type": [
              "string",
              "null"
            ]
          },
          "material": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "sentence": {
            "type": [
              "string",
              "null"
            ]
          },
          "noticed_at": {},
          "subject": {},
          "before": {},
          "after": {},
          "claim_id": {},
          "statement_id": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "additionalProperties": true
      },
      "StatementVersion": {
        "type": "object",
        "required": [
          "claim_id",
          "verification_state",
          "recorded_at",
          "sources"
        ],
        "description": "One version of a statement. confidence_recorded is the confidence stored when the version was written.",
        "properties": {
          "statement_id": {
            "type": "string"
          },
          "claim_id": {
            "type": "string"
          },
          "value": {},
          "unit": {
            "type": [
              "string",
              "null"
            ]
          },
          "verification_state": {
            "type": "string",
            "enum": [
              "verified",
              "corroborated",
              "vendor_stated",
              "customer_reported",
              "estimated",
              "unknown"
            ]
          },
          "confidence_recorded": {
            "type": [
              "number",
              "null"
            ]
          },
          "observed_on": {
            "type": [
              "string",
              "null"
            ]
          },
          "recorded_at": {
            "type": "string",
            "format": "date-time"
          },
          "ended_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "ended_by": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "superseded",
              "withdrawn",
              null
            ]
          },
          "ended_later": {
            "type": [
              "string",
              "null"
            ]
          },
          "withdrawal_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "excerpt": {
            "type": [
              "string",
              "null"
            ]
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Source"
            }
          }
        },
        "additionalProperties": true
      },
      "EdgeList": {
        "type": "object",
        "required": [
          "count",
          "contract"
        ],
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "count": {
            "type": "integer"
          },
          "contract": {
            "type": "string"
          },
          "integrations": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "alternatives": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        },
        "additionalProperties": true
      }
    }
  }
}