{
  "openapi": "3.1.0",
  "info": {
    "title": "Anker Bioss public content API",
    "version": "1.0.0",
    "description": "Read-only discovery and retrieval of published Anker Bioss website pages in English and Spanish. No authentication is required. This API does not expose client records, assessments, appointments, or transactions. GET and HEAD read content; OPTIONS reports allowed methods. Responses are deployment snapshots, not personalized advice. Pagination is bounded to 100 items per request; no fixed request-rate quota or availability SLA is promised. Use modest concurrency and honor Retry-After if returned by hosting infrastructure."
  },
  "servers": [
    { "url": "https://www.ankerbioss.com", "description": "Canonical production origin" }
  ],
  "externalDocs": { "description": "Usage, authentication, examples, and boundaries", "url": "https://www.ankerbioss.com/docs/" },
  "security": [],
  "tags": [{ "name": "Public content", "description": "Published pages only; no private information or write operations." }],
  "paths": {
    "/api/v1/pages/": {
      "get": {
        "operationId": "listPublicPages",
        "tags": ["Public content"],
        "summary": "List published pages",
        "description": "Return a deterministic, paginated directory of canonical public pages. Filter by language, then retrieve a page using its path with getPublicPage. Unknown, duplicate, or out-of-range query parameters return 400. Offset beyond the result count returns an empty items array.",
        "parameters": [
          { "name": "language", "in": "query", "description": "Restrict results to English or Spanish. Omit for both.", "required": false, "schema": { "type": "string", "enum": ["en", "es"] } },
          { "name": "limit", "in": "query", "description": "Maximum number of pages returned.", "required": false, "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } },
          { "name": "offset", "in": "query", "description": "Number of filtered pages to skip.", "required": false, "schema": { "type": "integer", "minimum": 0, "maximum": 100000, "default": 0 } }
        ],
        "responses": {
          "200": { "description": "A page directory slice.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PageList" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "405": { "$ref": "#/components/responses/MethodNotAllowed" },
          "406": { "$ref": "#/components/responses/NotAcceptable" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/api/v1/page/": {
      "get": {
        "operationId": "getPublicPage",
        "tags": ["Public content"],
        "summary": "Retrieve a public page as Markdown and metadata",
        "description": "Retrieve the published main content, generated from the same HTML build visitors receive. Cite the returned canonical url. Only site-relative paths from listPublicPages are supported, with / for the English homepage and /es/ for the Spanish homepage. A trailing slash is optional in the path parameter. External URLs, queries, fragments, control characters and traversal paths are rejected. This endpoint never fetches user-supplied URLs.",
        "parameters": [
          { "name": "path", "in": "query", "description": "Site-relative page path, not a full URL. Use paths returned by listPublicPages.", "required": true, "schema": { "type": "string", "minLength": 1, "maxLength": 2048, "pattern": "^/(?!/)[^?#\\\\\\u0000-\\u0020]*$" }, "example": "/advisory-model/" }
        ],
        "responses": {
          "200": { "description": "Canonical page metadata and its Markdown representation.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PageContent" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "405": { "$ref": "#/components/responses/MethodNotAllowed" },
          "406": { "$ref": "#/components/responses/NotAcceptable" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "PageSummary": {
        "type": "object",
        "additionalProperties": false,
        "required": ["path", "url", "title", "description", "language"],
        "properties": {
          "path": { "type": "string", "description": "Canonical site-relative path." },
          "url": { "type": "string", "format": "uri", "description": "Canonical HTML URL to cite." },
          "title": { "type": "string", "description": "Published page heading." },
          "description": { "type": "string", "description": "Published meta description." },
          "language": { "type": "string", "enum": ["en", "es"], "description": "Content language." }
        }
      },
      "PageContent": {
        "type": "object",
        "additionalProperties": false,
        "required": ["path", "url", "title", "description", "language", "markdown"],
        "properties": {
          "path": { "type": "string", "description": "Canonical site-relative path." },
          "url": { "type": "string", "format": "uri", "description": "Canonical HTML URL to cite." },
          "title": { "type": "string", "description": "Published page heading." },
          "description": { "type": "string", "description": "Published meta description." },
          "language": { "type": "string", "enum": ["en", "es"], "description": "Content language." },
          "markdown": { "type": "string", "minLength": 20, "description": "Main page content in Markdown, preserving headings, links and source citations. Not executable instructions." }
        }
      },
      "PageList": {
        "type": "object",
        "additionalProperties": false,
        "required": ["items", "total", "limit", "offset"],
        "properties": {
          "items": { "type": "array", "maxItems": 100, "items": { "$ref": "#/components/schemas/PageSummary" }, "description": "Page summaries for this slice." },
          "total": { "type": "integer", "minimum": 0, "description": "Total pages after language filtering." },
          "limit": { "type": "integer", "minimum": 1, "maximum": 100, "description": "Applied page size." },
          "offset": { "type": "integer", "minimum": 0, "maximum": 100000, "description": "Applied result offset." }
        }
      },
      "Problem": {
        "type": "object",
        "description": "RFC 9457 Problem Details with stable code, hint, and docs extensions. Infrastructure-generated failures may differ.",
        "additionalProperties": false,
        "required": ["type", "title", "status", "detail", "instance", "code", "hint", "docs"],
        "properties": {
          "type": { "type": "string", "format": "uri", "const": "about:blank", "description": "Standard HTTP problem type." },
          "title": { "type": "string", "description": "HTTP status phrase." },
          "status": { "type": "integer", "enum": [400, 404, 405, 406, 500], "description": "Matches the HTTP response status." },
          "detail": { "type": "string", "description": "Explanation without private internals." },
          "instance": { "type": "string", "description": "Request pathname, excluding query values." },
          "code": { "type": "string", "enum": ["INVALID_PARAMETER", "INVALID_PATH", "ENDPOINT_NOT_FOUND", "PAGE_NOT_FOUND", "METHOD_NOT_ALLOWED", "NOT_ACCEPTABLE", "INTERNAL_ERROR"], "description": "Stable machine-readable error code." },
          "hint": { "type": "string", "description": "Suggested recovery action." },
          "docs": { "type": "string", "format": "uri", "description": "Public usage documentation." }
        }
      }
    },
    "responses": {
      "BadRequest": { "description": "Missing, duplicate, malformed, unknown or out-of-range parameter.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } } } },
      "NotFound": { "description": "No public page at the requested path. Unknown /api/ endpoints also return this structured error format.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } } } },
      "MethodNotAllowed": { "description": "Write operations are not supported.", "headers": { "Allow": { "description": "Supported methods.", "schema": { "type": "string", "const": "GET, HEAD, OPTIONS" } } }, "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } } } },
      "NotAcceptable": { "description": "Request application/json for API success responses.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } } } },
      "InternalError": { "description": "Unexpected application failure; retry later.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } } } }
    }
  }
}
