{
  "openapi": "3.1.0",
  "info": {
    "title": "SAN Foundation Gateway API",
    "version": "1.0.0",
    "description": "Public API for the SAN Foundation gateway. The same data is exposed\nthrough two interchangeable surfaces: `/api/v1/*` is authenticated\nwith an `x-api-key` (`sk_…`) and billed in credits (per-call cost\nin `x-credits`); `/x402/v1/*` is paid per call in USDC over the\n[x402 protocol](https://x402.org) and requires no API key (per-call\ncost in `x-price-usd`).\n"
  },
  "servers": [
    {
      "url": "https://gateway.sanfoundation.com",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "API Key",
      "description": "Operations under `/api/v1/*`. Authenticate with a SAN API key\n(`x-api-key` header) and pay with prepaid credits — see each\noperation's `x-credits` for the per-call cost.\n"
    },
    {
      "name": "x402",
      "description": "Operations under `/x402/v1/*`. Pay per call in USDC over the\n[x402 protocol](https://x402.org) — see each operation's\n`x-price-usd` for the per-call cost. No API key required.\n"
    },
    {
      "name": "Registration",
      "description": "Public, unauthenticated self-onboarding for agents. One call mints an\nAPI key and grants the signup credit so an agent can immediately use\n`/api/v1/*`. Rate limited per client IP.\n"
    }
  ],
  "paths": {
    "/api/v1/register": {
      "post": {
        "operationId": "registerAgent",
        "tags": [
          "Registration"
        ],
        "summary": "Self-register and mint an API key",
        "description": "Create an account and mint an API key in a single unauthenticated\ncall — no login required. The account is granted the standard signup\ncredit and the plaintext API key is returned **exactly once** (it is\nhashed at rest and cannot be retrieved again — store it securely).\nSend the returned key as the `x-api-key` header on `/api/v1/*`\nrequests. Rate limited per client IP.\n",
        "responses": {
          "201": {
            "$ref": "#/components/responses/RegistrationOk"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRegistrations"
          }
        }
      }
    },
    "/api/v1/balance": {
      "get": {
        "operationId": "getBalance",
        "tags": [
          "API Key"
        ],
        "summary": "Check remaining balance",
        "description": "Return the calling key's remaining spendable balance in dollars. Free —\nthis call is never billed. Works at any balance, including zero (returns\n`\"0.00\"`), so an agent can always check its remaining balance.\n",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-credits": 0,
        "responses": {
          "200": {
            "$ref": "#/components/responses/BalanceOk"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/v1/agents": {
      "get": {
        "operationId": "listAgents",
        "tags": [
          "API Key"
        ],
        "summary": "List agents",
        "description": "Catalog of SAN agents (the `id`, `name`, `slug`, or `externalId` you pass as `{ref}` on the agent-scoped endpoints), optionally filtered by a case-insensitive `search` substring against `name`, `domain`, and `description`.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-credits": 0,
        "parameters": [
          {
            "$ref": "#/components/parameters/SearchQuery"
          },
          {
            "$ref": "#/components/parameters/AgentsLimit"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/AgentsList"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/agents/{ref}/events": {
      "get": {
        "operationId": "listAgentEvents",
        "tags": [
          "API Key"
        ],
        "summary": "List events",
        "description": "Most recently updated canonical events where the agent is primary or secondary, with each event collapsing matching source articles into a single record carrying `sourceCount` and a `sources[]` array.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-credits": 3,
        "parameters": [
          {
            "$ref": "#/components/parameters/AgentRef"
          },
          {
            "$ref": "#/components/parameters/EventsLimit"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/AgentEvents"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/AgentNotFound"
          }
        }
      }
    },
    "/api/v1/agents/{ref}/reports": {
      "get": {
        "operationId": "listAgentReports",
        "tags": [
          "API Key"
        ],
        "summary": "List reports",
        "description": "Generated reports for the agent in reverse-chronological order, each containing four audience-lensed sections (`personal`, `research`, `business_operations`, `trading_investments`) under both `situation` and `decisionAdvantage`.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-credits": 10,
        "parameters": [
          {
            "$ref": "#/components/parameters/AgentRef"
          },
          {
            "$ref": "#/components/parameters/ReportsLimit"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/AgentReports"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/AgentNotFound"
          }
        }
      }
    },
    "/api/v1/events/{eventId}": {
      "get": {
        "operationId": "getEvent",
        "tags": [
          "API Key"
        ],
        "summary": "Get event",
        "description": "Full canonical event envelope for a specific `evt_…` id, used to resolve a citation in an agent report back to the underlying event.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-credits": 0,
        "parameters": [
          {
            "$ref": "#/components/parameters/EventIdPath"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/EventEnvelope"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/EventNotFound"
          }
        }
      }
    },
    "/api/v1/web-search": {
      "post": {
        "operationId": "webSearch",
        "tags": [
          "API Key"
        ],
        "summary": "Web search",
        "description": "Searches the open web for a topic and returns up to 10 ranked results with source `url`, page `title`, `publish_date` (when known), and the most relevant excerpts.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-credits": 3,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebSearchRequest"
              },
              "examples": {
                "basic": {
                  "value": {
                    "search": "latest LNG export cuts in Qatar"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebSearchOk"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "503": {
            "$ref": "#/components/responses/WebResearchUnavailable"
          }
        }
      }
    },
    "/api/v1/web-extract": {
      "post": {
        "operationId": "webExtract",
        "tags": [
          "API Key"
        ],
        "summary": "Web extract",
        "description": "Fetches a single URL and returns its `title`, `publish_date` (when known), the most relevant `excerpts[]` (optionally biased by a natural-language `objective`), and the page's `full_content` as a bare object.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-credits": 1,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebExtractRequest"
              },
              "examples": {
                "basic": {
                  "value": {
                    "url": "https://example.com/article",
                    "objective": "summarize the key findings"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebExtractOk"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "503": {
            "$ref": "#/components/responses/WebResearchUnavailable"
          }
        }
      }
    },
    "/x402/v1/agents": {
      "get": {
        "operationId": "listAgentsX402",
        "tags": [
          "x402"
        ],
        "summary": "List agents",
        "description": "Same shape as `GET /api/v1/agents`, paid per call via x402.",
        "security": [
          {
            "X402Payment": []
          }
        ],
        "x-price-usd": "$0.0001",
        "parameters": [
          {
            "$ref": "#/components/parameters/SearchQuery"
          },
          {
            "$ref": "#/components/parameters/AgentsLimit"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/AgentsList"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          }
        }
      }
    },
    "/x402/v1/agents/{ref}/events": {
      "get": {
        "operationId": "listAgentEventsX402",
        "tags": [
          "x402"
        ],
        "summary": "List events",
        "description": "Same shape as `GET /api/v1/agents/{ref}/events`, paid per call via x402.",
        "security": [
          {
            "X402Payment": []
          }
        ],
        "x-price-usd": "$0.03",
        "parameters": [
          {
            "$ref": "#/components/parameters/AgentRef"
          },
          {
            "$ref": "#/components/parameters/EventsLimit"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/AgentEvents"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "404": {
            "$ref": "#/components/responses/AgentNotFound"
          }
        }
      }
    },
    "/x402/v1/agents/{ref}/reports": {
      "get": {
        "operationId": "listAgentReportsX402",
        "tags": [
          "x402"
        ],
        "summary": "List reports",
        "description": "Same shape as `GET /api/v1/agents/{ref}/reports`, paid per call via x402.",
        "security": [
          {
            "X402Payment": []
          }
        ],
        "x-price-usd": "$0.10",
        "parameters": [
          {
            "$ref": "#/components/parameters/AgentRef"
          },
          {
            "$ref": "#/components/parameters/ReportsLimit"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/AgentReports"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "404": {
            "$ref": "#/components/responses/AgentNotFound"
          }
        }
      }
    },
    "/x402/v1/events/{eventId}": {
      "get": {
        "operationId": "getEventX402",
        "tags": [
          "x402"
        ],
        "summary": "Get event",
        "description": "Same shape as `GET /api/v1/events/{eventId}`, paid per call via x402.",
        "security": [
          {
            "X402Payment": []
          }
        ],
        "x-price-usd": "$0.0001",
        "parameters": [
          {
            "$ref": "#/components/parameters/EventIdPath"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/EventEnvelope"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "404": {
            "$ref": "#/components/responses/EventNotFound"
          }
        }
      }
    },
    "/x402/v1/web-search": {
      "post": {
        "operationId": "webSearchX402",
        "tags": [
          "x402"
        ],
        "summary": "Web search",
        "description": "Same shape as `POST /api/v1/web-search`, paid per call via x402.",
        "security": [
          {
            "X402Payment": []
          }
        ],
        "x-price-usd": "$0.03",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebSearchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebSearchOk"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "503": {
            "$ref": "#/components/responses/WebResearchUnavailable"
          }
        }
      }
    },
    "/x402/v1/web-extract": {
      "post": {
        "operationId": "webExtractX402",
        "tags": [
          "x402"
        ],
        "summary": "Web extract",
        "description": "Same shape as `POST /api/v1/web-extract`, paid per call via x402.",
        "security": [
          {
            "X402Payment": []
          }
        ],
        "x-price-usd": "$0.01",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebExtractRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebExtractOk"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "503": {
            "$ref": "#/components/responses/WebResearchUnavailable"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "SAN-issued API key (`sk_…`) issued from the SAN Agents Dashboard\n(Settings → API Keys). Used by every `/api/v1/*` endpoint; usage\nis billed in credits against the owning account's active Stripe\nsubscription.\n"
      },
      "X402Payment": {
        "type": "apiKey",
        "in": "header",
        "name": "Payment-Signature",
        "description": "Base64-encoded signed payment payload as defined by the\n[x402 protocol](https://x402.org). Omit on the first attempt to\nreceive the `402` challenge in the `PAYMENT-REQUIRED` response\nheader; include it on the retry to settle payment and receive\nthe resource.\n\nThe legacy header name `X-PAYMENT` is also accepted by the\nserver for backward compatibility — clients may send either,\nbut `Payment-Signature` is preferred.\n\nSee [x402.org](https://x402.org) for the on-the-wire shape of\nthe `PaymentRequired` challenge and the settlement receipt\nreturned in the `PAYMENT-RESPONSE` response header.\n"
      }
    },
    "parameters": {
      "AgentRef": {
        "in": "path",
        "name": "ref",
        "required": true,
        "description": "Flexible agent identifier. Accepts any of:\n  * UUID — `488ed3ff-6a4d-42e5-8e24-44eeef77959c`\n  * Name (case-insensitive) — `Noah`, `noah`, `NOAH`\n  * Slug — lowercase name with spaces as underscores\n  * External ID — `017`, `17`, `069`, `69`\n    (`#` and zero-padding tolerated)\n",
        "schema": {
          "type": "string"
        },
        "examples": {
          "byName": {
            "value": "Noah"
          },
          "byExternalId": {
            "value": "017"
          },
          "byUuid": {
            "value": "488ed3ff-6a4d-42e5-8e24-44eeef77959c"
          }
        }
      },
      "EventIdPath": {
        "in": "path",
        "name": "eventId",
        "required": true,
        "description": "Stable canonical event id (e.g. `evt_d62a81a5e8b2366027fbaf6b`).",
        "schema": {
          "type": "string",
          "pattern": "^evt_[a-z0-9]{16,}$"
        },
        "examples": {
          "sample": {
            "value": "evt_d62a81a5e8b2366027fbaf6b"
          }
        }
      },
      "SearchQuery": {
        "in": "query",
        "name": "search",
        "required": false,
        "description": "Case-insensitive substring filter on name, domain, and description.",
        "schema": {
          "type": "string"
        },
        "examples": {
          "byTopic": {
            "value": "cyber"
          },
          "byName": {
            "value": "Noah"
          }
        }
      },
      "AgentsLimit": {
        "in": "query",
        "name": "limit",
        "required": false,
        "description": "Max number of agents to return.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 500,
          "default": 100
        }
      },
      "EventsLimit": {
        "in": "query",
        "name": "limit",
        "required": false,
        "description": "Max number of events to return.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 30,
          "default": 10
        }
      },
      "ReportsLimit": {
        "in": "query",
        "name": "limit",
        "required": false,
        "description": "Max number of reports to return.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 3,
          "default": 1
        }
      }
    },
    "responses": {
      "AgentsList": {
        "description": "OK — agent catalog.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AgentsListResponse"
            }
          }
        }
      },
      "AgentEvents": {
        "description": "OK — recent canonical events for the agent.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AgentEventsResponse"
            }
          }
        }
      },
      "AgentReports": {
        "description": "OK — recent generated reports for the agent.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AgentReportsResponse"
            }
          }
        }
      },
      "EventEnvelope": {
        "description": "OK — single canonical event envelope.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/EventResponse"
            }
          }
        }
      },
      "BadRequest": {
        "description": "Malformed input — typically a `limit` outside the documented\nbounds for the route, an unknown agent `ref`, or a malformed\n`evt_…` id. On `/x402/v1/*`, these guards run **before** payment,\nso the client is not charged.\n",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "limitOutOfRange": {
                "value": {
                  "error": "limit out of range",
                  "min": 1,
                  "max": 30
                }
              },
              "agentNotFound": {
                "value": {
                  "error": "agent not found",
                  "ref": "unknown-handle"
                }
              },
              "badEventId": {
                "value": {
                  "error": "invalid event id shape",
                  "eventId": "not-an-evt"
                }
              }
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing, invalid, or revoked API key (emitted by key-authenticated `/api/*` endpoints).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "missing": {
                "value": {
                  "error": "Missing or invalid x-api-key header"
                }
              },
              "invalid": {
                "value": {
                  "error": "Invalid API key"
                }
              }
            }
          }
        }
      },
      "Forbidden": {
        "description": "The API key is valid but its owning account has no active Stripe\nsubscription (status is not `active` or `trialing`). Only\nemitted by `/api/v1/*`.\n",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Active subscription required. Please set up billing at your dashboard."
            }
          }
        }
      },
      "PaymentRequired": {
        "description": "x402 payment challenge. The structured `PaymentRequired` payload\nis returned in the **`PAYMENT-REQUIRED`** response header as a\nbase64-encoded JSON object — see [x402.org](https://x402.org)\nfor the decoded shape (clients must accept either `x402Version: 1`\nor `x402Version: 2`).\n\nFor non-browser clients, the response body is also a JSON\n`PaymentRequired` payload. Browser clients (those whose `Accept`\nheader indicates `text/html`) instead receive a paywall HTML\npage in the body.\n",
        "headers": {
          "PAYMENT-REQUIRED": {
            "description": "Base64-encoded JSON `PaymentRequired` payload describing the\nx402 challenge the client must satisfy. See\n[x402.org](https://x402.org) for the decoded shape.\n",
            "schema": {
              "type": "string"
            }
          }
        }
      },
      "AgentNotFound": {
        "description": "No agent matched the supplied `ref`.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "agent not found",
              "ref": "unknown-handle"
            }
          }
        }
      },
      "EventNotFound": {
        "description": "No event matched the supplied id.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "event not found",
              "eventId": "evt_unknown"
            }
          }
        }
      },
      "WebSearchOk": {
        "description": "OK — ranked web search results.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/WebSearchResponse"
            }
          }
        }
      },
      "WebExtractOk": {
        "description": "OK — readable content extracted from the URL.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/WebExtractResult"
            }
          }
        }
      },
      "WebResearchUnavailable": {
        "description": "The web research provider is not configured for this server.\nOperationally this means the server is missing the credentials\nneeded to call the underlying research backend; it is not a\nclient error.\n",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Web research provider is not configured"
            }
          }
        }
      },
      "BalanceOk": {
        "description": "OK — current spendable balance for the calling key.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/BalanceResponse"
            }
          }
        }
      },
      "RegistrationOk": {
        "description": "OK — account registered and API key minted (key shown once).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/RegisterResponse"
            }
          }
        }
      },
      "TooManyRegistrations": {
        "description": "Too many registrations from this client IP. The endpoint allows a\nlimited number of registrations per hour and per day per IP; retry\nafter the window resets.\n",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Too many registrations from this IP. Please try again later."
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "ref": {
            "type": "string",
            "description": "Echoed back when an agent ref could not be resolved."
          },
          "eventId": {
            "type": "string",
            "description": "Echoed back when an event id could not be resolved."
          },
          "min": {
            "type": "integer",
            "description": "Echoed back on a `limit out of range` error."
          },
          "max": {
            "type": "integer",
            "description": "Echoed back on a `limit out of range` error."
          }
        }
      },
      "AgentSummary": {
        "type": "object",
        "required": [
          "id",
          "externalId",
          "name",
          "slug",
          "domain",
          "description"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "externalId": {
            "type": [
              "string",
              "null"
            ],
            "description": "Short human-readable code (e.g. \"017\")."
          },
          "name": {
            "type": "string",
            "description": "Display name / codename (e.g. \"Noah\")."
          },
          "slug": {
            "type": "string",
            "description": "Lowercase, underscore-separated form of the name."
          },
          "domain": {
            "type": "string",
            "description": "Broad subject area the agent monitors."
          },
          "description": {
            "type": "string",
            "description": "Free-text description of what the agent does and tracks."
          }
        }
      },
      "AgentsListResponse": {
        "type": "object",
        "required": [
          "count",
          "agents"
        ],
        "properties": {
          "count": {
            "type": "integer"
          },
          "agents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AgentSummary"
            }
          }
        }
      },
      "EventEntity": {
        "type": "object",
        "required": [
          "name",
          "type",
          "role"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "description": "e.g. `person`, `organization`, `concept`."
          },
          "role": {
            "type": "string",
            "description": "e.g. `primary`, `mentioned`."
          }
        }
      },
      "EventLocation": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "country": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "EventSource": {
        "type": "object",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "publication": {
            "type": [
              "string",
              "null"
            ]
          },
          "publishedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "PublicEvent": {
        "type": "object",
        "required": [
          "eventId",
          "title",
          "summary",
          "firstSeenAt",
          "lastUpdatedAt",
          "primaryAgent",
          "eventType",
          "status",
          "confidence",
          "tags",
          "sourceCount",
          "entities",
          "locations",
          "sources"
        ],
        "properties": {
          "eventId": {
            "type": "string",
            "description": "Stable canonical event identifier."
          },
          "title": {
            "type": "string",
            "description": "Canonical (deduplicated) headline."
          },
          "summary": {
            "type": "string"
          },
          "occurredAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the underlying event occurred, if known."
          },
          "firstSeenAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastUpdatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "primaryAgent": {
            "type": "string",
            "description": "Display name of the primary agent."
          },
          "eventType": {
            "type": "string",
            "description": "e.g. `statement`, `release`, `incident`."
          },
          "status": {
            "type": "string",
            "description": "e.g. `active`, `archived`."
          },
          "confidence": {
            "type": "string",
            "enum": [
              "low",
              "medium",
              "high"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sourceCount": {
            "type": "integer",
            "description": "Number of distinct source articles clustered into this event."
          },
          "entities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EventEntity"
            }
          },
          "locations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EventLocation"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EventSource"
            }
          }
        }
      },
      "AgentEventsResponse": {
        "type": "object",
        "required": [
          "agent",
          "count",
          "events"
        ],
        "properties": {
          "agent": {
            "$ref": "#/components/schemas/AgentSummary"
          },
          "count": {
            "type": "integer"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicEvent"
            }
          }
        }
      },
      "EventResponse": {
        "type": "object",
        "required": [
          "event"
        ],
        "properties": {
          "event": {
            "$ref": "#/components/schemas/PublicEvent"
          }
        }
      },
      "CoverageWindow": {
        "type": "object",
        "required": [
          "windowType",
          "start",
          "end"
        ],
        "properties": {
          "windowType": {
            "type": "string",
            "description": "e.g. `rolling_24h`, `rolling_7d`, `since_last`."
          },
          "start": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "end": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "Confidence": {
        "type": "object",
        "required": [
          "overall",
          "notes"
        ],
        "properties": {
          "overall": {
            "type": "string",
            "enum": [
              "low",
              "medium",
              "high"
            ]
          },
          "notes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "Situation": {
        "type": "object",
        "description": "Single narrative block describing the current state of the topic\nthe agent monitors. Audience-specific framing lives on\n`decisionAdvantage`, not here.\n",
        "required": [
          "headline",
          "what_happened",
          "what_changed",
          "why_it_matters"
        ],
        "properties": {
          "headline": {
            "type": "string",
            "description": "One-line characterization of the current state."
          },
          "what_happened": {
            "type": "string",
            "description": "Concrete observed events behind this report."
          },
          "what_changed": {
            "type": "string",
            "description": "How the picture differs from the prior report."
          },
          "why_it_matters": {
            "type": "string",
            "description": "Stakes and implications."
          }
        }
      },
      "DecisionAdvantageBlock": {
        "type": "object",
        "description": "Audience-specific take on what to do next.",
        "required": [
          "bottom_line",
          "recommended_posture",
          "time_horizon"
        ],
        "properties": {
          "bottom_line": {
            "type": "string",
            "description": "Single sentence answer for \"so what?\"."
          },
          "recommended_posture": {
            "type": "string",
            "description": "Suggested action or stance for this audience."
          },
          "time_horizon": {
            "type": "string",
            "description": "Short phrase such as `intraday`, `hours`, `days`, `weeks`."
          }
        }
      },
      "DecisionAdvantageByLens": {
        "type": "object",
        "description": "Per-audience decision-advantage payload, one block per lens.",
        "required": [
          "personal",
          "research",
          "business_operations",
          "trading_investments"
        ],
        "properties": {
          "personal": {
            "$ref": "#/components/schemas/DecisionAdvantageBlock"
          },
          "research": {
            "$ref": "#/components/schemas/DecisionAdvantageBlock"
          },
          "business_operations": {
            "$ref": "#/components/schemas/DecisionAdvantageBlock"
          },
          "trading_investments": {
            "$ref": "#/components/schemas/DecisionAdvantageBlock"
          }
        }
      },
      "Report": {
        "type": "object",
        "description": "A generated SAN intelligence report for an agent. The four\naudience lenses defined by the SAN brief — `personal`,\n`research`, `business_operations`, `trading_investments` — are\nsurfaced through the `situation` and `decisionAdvantage` blocks\nkeyed by lens name.\n",
        "required": [
          "reportId",
          "agentSlug",
          "agentCodename",
          "title",
          "summary",
          "analysis",
          "coverageWindow",
          "asOf",
          "generatedAt",
          "sourceEventIds",
          "region",
          "situation",
          "decisionAdvantage",
          "nextLikelyDevelopments",
          "confidence"
        ],
        "properties": {
          "reportId": {
            "type": "string"
          },
          "agentSlug": {
            "type": "string"
          },
          "agentCodename": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "summary": {
            "type": "string",
            "description": "Short executive summary."
          },
          "analysis": {
            "type": "string",
            "description": "Long-form Markdown analysis."
          },
          "trend": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "stable",
              "developing",
              "escalating",
              "de-escalating",
              "uncertain",
              null
            ],
            "description": "Direction of the situation since the prior report."
          },
          "coverageWindow": {
            "$ref": "#/components/schemas/CoverageWindow"
          },
          "asOf": {
            "type": "string",
            "format": "date-time"
          },
          "generatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "generationReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "triggerType": {
            "type": [
              "string",
              "null"
            ],
            "description": "e.g. `scheduled`, `manual`, `signal`."
          },
          "changeScore": {
            "type": [
              "number",
              "null"
            ]
          },
          "sourceEventIds": {
            "type": "array",
            "description": "Canonical event ids that justify this report's claims. Each\nid can be resolved to its full event envelope via\n`GET /api/v1/events/{eventId}` or\n`GET /x402/v1/events/{eventId}`.\n",
            "items": {
              "type": "string"
            }
          },
          "inboundSignalIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "region": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "situation": {
            "$ref": "#/components/schemas/Situation"
          },
          "decisionAdvantage": {
            "$ref": "#/components/schemas/DecisionAdvantageByLens"
          },
          "nextLikelyDevelopments": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "confidence": {
            "$ref": "#/components/schemas/Confidence"
          }
        }
      },
      "AgentReportsResponse": {
        "type": "object",
        "required": [
          "agent",
          "count",
          "reports"
        ],
        "properties": {
          "agent": {
            "$ref": "#/components/schemas/AgentSummary"
          },
          "count": {
            "type": "integer"
          },
          "reports": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Report"
            }
          }
        }
      },
      "WebSearchRequest": {
        "type": "object",
        "required": [
          "search"
        ],
        "properties": {
          "search": {
            "type": "string",
            "minLength": 1,
            "maxLength": 1000,
            "description": "Free-text search query."
          }
        }
      },
      "WebSearchResult": {
        "type": "object",
        "required": [
          "url",
          "title",
          "publish_date",
          "excerpts"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "title": {
            "type": "string"
          },
          "publish_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Publication date when the source exposes one, otherwise null."
          },
          "excerpts": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Excerpts the ranker scored as most relevant for the query."
          }
        }
      },
      "WebSearchResponse": {
        "type": "object",
        "required": [
          "results"
        ],
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebSearchResult"
            }
          }
        }
      },
      "WebExtractRequest": {
        "type": "object",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Absolute http(s) URL to fetch and extract."
          },
          "objective": {
            "type": "string",
            "maxLength": 1000,
            "description": "Optional natural-language objective used to bias the\nexcerpt selection toward the caller's interest.\n"
          }
        }
      },
      "WebExtractResult": {
        "type": "object",
        "required": [
          "url",
          "title",
          "publish_date",
          "excerpts"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "title": {
            "type": "string"
          },
          "publish_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "excerpts": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "full_content": {
            "type": "string",
            "description": "Full readable text of the page."
          }
        }
      },
      "BalanceResponse": {
        "type": "object",
        "required": [
          "balance"
        ],
        "properties": {
          "balance": {
            "type": "string",
            "description": "Remaining spendable balance in dollars (e.g. \"73.41\"). \"0.00\" when empty."
          }
        }
      },
      "RegisterResponse": {
        "type": "object",
        "required": [
          "apiKey",
          "balance"
        ],
        "properties": {
          "apiKey": {
            "type": "string",
            "description": "Plaintext API key (`sk_…`). Returned once and never retrievable\nagain — store it securely. Send as the `x-api-key` header on\n`/api/v1/*` requests.\n"
          },
          "balance": {
            "type": "string",
            "description": "Granted spendable balance in dollars (e.g. \"100.00\")."
          }
        }
      }
    }
  }
}