{
  "openapi": "3.1.0",
  "info": {
    "title": "SS-31.com Content API",
    "version": "1.0.0",
    "summary": "Public read-only API for SS-31.com content about SS-31.",
    "description": "Public, read-only REST API for SS-31.com, an educational site about SS-31.\nIt exposes the site's medically reviewed content (topic pages, articles, legal and company pages) as structured JSON and Markdown so AI agents and applications can list, search, and read it.\n\n**Authentication:** none. All endpoints are public and read-only.\n**Rate limits:** responses are cacheable (`s-maxage=3600`); please cache aggressively. Abusive traffic may be throttled at the edge.\n**Errors:** every error is JSON shaped as `{ error: { status, code, message, hint, documentation, specification } }`.\n**Model Context Protocol:** a Streamable HTTP MCP server is available at https://ss-31.com/api/mcp (discovery at https://ss-31.com/.well-known/mcp).",
    "contact": {
      "name": "SS-31.com support",
      "url": "https://ss-31.com/contact"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://ss-31.com/legal/privacy-policy"
    }
  },
  "servers": [
    {
      "url": "https://ss-31.com/api/v1",
      "description": "Production"
    }
  ],
  "externalDocs": {
    "description": "Developer portal",
    "url": "https://ss-31.com/developers"
  },
  "tags": [
    {
      "name": "Content",
      "description": "Discover and retrieve SS-31.com content."
    }
  ],
  "paths": {
    "/pages": {
      "get": {
        "operationId": "listPages",
        "tags": [
          "Content"
        ],
        "summary": "List all content pages",
        "description": "Returns every content page (home, topic pillars, articles, legal, company, author) with its canonical URL, type, title, and description. Optionally filter by page type.",
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Filter results to a single page type.",
            "schema": {
              "$ref": "#/components/schemas/PageType"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A list of content pages.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageListResponse"
                }
              }
            }
          }
        }
      }
    },
    "/pages/{path}": {
      "get": {
        "operationId": "getPage",
        "tags": [
          "Content"
        ],
        "summary": "Get a single page as Markdown",
        "description": "Fetches one page by its site-relative path and returns its metadata plus full Markdown content. The path may contain slashes, e.g. `article/{slug}`. Use listPages to discover valid paths.",
        "parameters": [
          {
            "name": "path",
            "in": "path",
            "required": true,
            "description": "Site-relative path without a leading slash. Examples: `{pillar-slug}`, `article/{slug}`, `legal/privacy-policy`. Discover valid paths via the listPages operation.",
            "schema": {
              "type": "string"
            },
            "example": "about"
          }
        ],
        "responses": {
          "200": {
            "description": "The page metadata and Markdown content.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageDetailResponse"
                }
              }
            }
          },
          "404": {
            "description": "No page exists at the given path.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/search": {
      "get": {
        "operationId": "searchContent",
        "tags": [
          "Content"
        ],
        "summary": "Search content by keyword",
        "description": "Full-text keyword search across article and topic-page titles, categories, and summaries. Topic pages are ranked before articles.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Search keyword or phrase.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "ss-31"
          }
        ],
        "responses": {
          "200": {
            "description": "Search results.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResponse"
                }
              }
            }
          },
          "400": {
            "description": "The `q` parameter is missing or empty.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "PageType": {
        "type": "string",
        "description": "The kind of content page.",
        "enum": [
          "home",
          "pillar",
          "article",
          "legal",
          "author",
          "company"
        ]
      },
      "PageSummary": {
        "type": "object",
        "required": [
          "path",
          "url",
          "type",
          "title",
          "description"
        ],
        "properties": {
          "path": {
            "type": "string",
            "description": "Site-relative path.",
            "example": "/article/example-article"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Absolute canonical URL."
          },
          "type": {
            "$ref": "#/components/schemas/PageType"
          },
          "title": {
            "type": "string",
            "description": "Page title."
          },
          "description": {
            "type": "string",
            "description": "Short summary of the page."
          },
          "category": {
            "type": "string",
            "description": "Article category, when applicable."
          }
        }
      },
      "PageDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/PageSummary"
          },
          {
            "type": "object",
            "required": [
              "format",
              "content"
            ],
            "properties": {
              "format": {
                "type": "string",
                "enum": [
                  "markdown"
                ],
                "description": "Encoding of the content field."
              },
              "content": {
                "type": "string",
                "description": "Full page content rendered as Markdown."
              }
            }
          }
        ]
      },
      "PageListResponse": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PageSummary"
            }
          },
          "meta": {
            "type": "object",
            "required": [
              "count"
            ],
            "properties": {
              "count": {
                "type": "integer",
                "description": "Number of pages returned."
              }
            }
          }
        }
      },
      "PageDetailResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/PageDetail"
          }
        }
      },
      "SearchResponse": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PageSummary"
            }
          },
          "meta": {
            "type": "object",
            "required": [
              "query",
              "count"
            ],
            "properties": {
              "query": {
                "type": "string",
                "description": "The query that was searched."
              },
              "count": {
                "type": "integer",
                "description": "Number of matches."
              }
            }
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "status",
              "code",
              "message"
            ],
            "properties": {
              "status": {
                "type": "integer",
                "description": "HTTP status code.",
                "example": 404
              },
              "code": {
                "type": "string",
                "description": "Stable machine-readable error code.",
                "example": "page_not_found"
              },
              "message": {
                "type": "string",
                "description": "Human-readable explanation."
              },
              "hint": {
                "type": "string",
                "description": "Actionable suggestion for resolving the error."
              },
              "documentation": {
                "type": "string",
                "format": "uri",
                "description": "Link to the developer portal."
              },
              "specification": {
                "type": "string",
                "format": "uri",
                "description": "Link to this OpenAPI document."
              }
            }
          }
        }
      }
    }
  }
}