{
  "schema": "aaes/capability-pack/1",
  "provider": "brave",
  "version": "1.0.0",
  "description": "Brave Search API web search: run one read-only web search and return titles, URLs and descriptions for research with citations.",
  "notes": "This pack registers one capability, brave.web.search, for the research-with-citations skill. It calls the documented POST form of the Web Search endpoint, https://api.search.brave.com/res/v1/web/search, with the query in the request body. The GET form takes the query in the URL, and the connector dials the registered URL and ignores a caller's query string, so GET could not carry a query. Egress is the one host api.search.brave.com.\n\nA request contract admits only these body fields: q (required; Brave allows at most 600 characters and 75 words), count (Brave allows 1 to 20, default 20), offset (0 to 9), country, search_lang, safesearch (off, moderate or strict; Brave's default is moderate), freshness and extra_snippets. Every other field is refused before dispatch, including goggles, summary and the rich-callback options. The connector does not check the numeric ranges or the query length; Brave rejects values outside them.\n\nThe capability is a read at the R0 floor. The search results are public web content, but the query text leaves the deployment and goes to Brave, and an agent's query can carry internal context, so the capability is classed internal. Policy decides who may search and how often; Brave counts only successful requests against the plan quota and reports X-RateLimit-Limit, X-RateLimit-Policy, X-RateLimit-Remaining and X-RateLimit-Reset headers.\n\nTerms to review before enabling, from Brave's Search API terms of use (last updated 1 September 2026): a customer may not store, cache or build a database of search results beyond the transient storage the application needs, may not redistribute or resell them, and may not use them to create, evaluate, train, fine-tune or benchmark models. An order form can change these terms. Attribution is optional. A research workflow that cites a result should cite the source page's URL and keep only what the answer needs.\n\nNot registered: the other Brave endpoints (news, image, video, suggest, spellcheck, local points of interest, summarizer and AI answers), the GET form of web search, and Goggles. AAES has not been certified by Brave; the endpoint is configuration to review and test, and the vendor has not endorsed it.",
  "credential": {
    "secret_ref_id": "secret-ref-brave-search-api-key",
    "custody": "customer_vault",
    "inject": "header",
    "inject_name": "X-Subscription-Token",
    "note": "A Brave Search API subscription token, held only in the client's own secret manager under this reference and resolved at execution. The stored material is the bare token, the complete X-Subscription-Token header value; Brave's reference calls it the subscription token generated for the product. The token is created and revoked in the Brave Search API dashboard; the retrieved pages document no expiry, so rotation and revocation are administrative actions the deployment owns, and a revoked value fails closed at Brave. The caller never supplies the token, and the connector refuses a caller-supplied credential header. Executor hygiene: the value must live only in executor memory for the lifetime of a call, must never be written to logs, traces or diagnostics, and must not appear in crash dumps."
  },
  "capabilities": [
    {
      "capability_id": "brave.web.search",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "internal",
      "egress_allowlist": [
        "api.search.brave.com"
      ],
      "endpoint": "https://api.search.brave.com/res/v1/web/search",
      "method": "POST",
      "connector": "http",
      "actions": [
        "read"
      ],
      "resource_id": "brave-web-search",
      "request_contract": {
        "fields": {
          "q": {
            "type": "string",
            "required": true
          },
          "count": {
            "type": "integer"
          },
          "offset": {
            "type": "integer"
          },
          "country": {
            "type": "string"
          },
          "search_lang": {
            "type": "string"
          },
          "safesearch": {
            "type": "string",
            "enum": [
              "off",
              "moderate",
              "strict"
            ]
          },
          "freshness": {
            "type": "string"
          },
          "extra_snippets": {
            "type": "boolean"
          }
        }
      },
      "description": "Run one web search and return Brave's results: web.results[] with title, url and description for each page. The method is POST, with the query in the body, but the effect is a read, so it sits at the R0 floor. The query text is sent to Brave, so the capability is classed internal.",
      "requires_review": true
    }
  ],
  "resources": [
    {
      "resource_id": "brave-web-search",
      "kind": "api",
      "locator": "https://api.search.brave.com/res/v1/web/search",
      "data_class": "internal",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN"
    }
  ],
  "review": {
    "state": "draft",
    "date": "2026-10-29",
    "sources": [
      "https://api-dashboard.search.brave.com/api-reference/web/search/post (retrieved 2026-10-29)",
      "https://api-dashboard.search.brave.com/api-reference/web/search/get (retrieved 2026-10-29)",
      "https://api-dashboard.search.brave.com/documentation/quickstart (retrieved 2026-10-29)",
      "https://api-dashboard.search.brave.com/documentation/guides/rate-limiting (retrieved 2026-10-29)",
      "https://api-dashboard.search.brave.com/terms-of-service (retrieved 2026-10-29)"
    ],
    "reviewer_id": "aaes-eng"
  }
}
