{
  "openapi": "3.1.0",
  "info": {
    "title": "PlatformD public content API",
    "version": "1.0.0",
    "summary": "Machine-readable surface of platformd.io",
    "description": "The read-only, unauthenticated surface of platformd.io: site pages (negotiable between text/html and text/markdown), the llms.txt agent overview, the sitemap, and JSON metadata for Insights posts.\n\nPlatformD does not yet expose a public transactional API, API keys, or a self-service sandbox. PlatformD is an entrant in the joint Bank of England and FCA Digital Securities Sandbox; live issuance of digital securities begins once the Bank of England confirms the next sandbox gate, targeted for early 2027. No pricing, yield or volume figures are published. Requests under /api/ return a structured JSON 404 (see the Error schema). For platform access, contact info@platformd.io.",
    "contact": {
      "name": "PlatformD",
      "email": "info@platformd.io",
      "url": "https://platformd.io/developers"
    }
  },
  "servers": [{ "url": "https://platformd.io" }],
  "security": [{}],
  "paths": {
    "/": {
      "get": {
        "operationId": "getHomepage",
        "summary": "Homepage",
        "description": "What PlatformD is and how it works. Served as markdown when the request prefers text/markdown (also addressable at /md/home).",
        "responses": {
          "200": { "$ref": "#/components/responses/NegotiablePage" }
        }
      }
    },
    "/insights": {
      "get": {
        "operationId": "getInsightsIndex",
        "summary": "Insights index",
        "description": "Index of articles from the PlatformD team. Served as markdown when the request prefers text/markdown (also addressable at /md/insights).",
        "responses": {
          "200": { "$ref": "#/components/responses/NegotiablePage" }
        }
      }
    },
    "/developers": {
      "get": {
        "operationId": "getDevelopersPage",
        "summary": "Developer and agent resources",
        "description": "Reference for machine-readable access to platformd.io. Served as markdown when the request prefers text/markdown (also addressable at /md/developers).",
        "responses": {
          "200": { "$ref": "#/components/responses/NegotiablePage" }
        }
      }
    },
    "/post/{slug}": {
      "get": {
        "operationId": "getInsightsPost",
        "summary": "Insights post",
        "description": "A single Insights article. Served as markdown when the request prefers text/markdown (also addressable at /md/post/{slug}). Valid slugs are listed in /sitemap.xml and /insights/chunks/1.json.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9-]*$" }
          }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/NegotiablePage" },
          "404": { "$ref": "#/components/responses/NotFoundPage" }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "operationId": "getLlmsTxt",
        "summary": "Site overview and agent guidance",
        "description": "Markdown overview of PlatformD for AI agents, including when-to-use guidance. The recommended starting point.",
        "responses": {
          "200": {
            "description": "llms.txt document",
            "content": { "text/plain": { "schema": { "type": "string" } } }
          }
        }
      }
    },
    "/sitemap.xml": {
      "get": {
        "operationId": "getSitemap",
        "summary": "Sitemap",
        "responses": {
          "200": {
            "description": "XML sitemap of every indexable page",
            "content": { "application/xml": { "schema": { "type": "string" } } }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApi",
        "summary": "This document",
        "responses": {
          "200": {
            "description": "OpenAPI 3.1 description of the public surface",
            "content": { "application/json": { "schema": { "type": "object" } } }
          }
        }
      }
    },
    "/insights/chunks/{chunk}": {
      "get": {
        "operationId": "getInsightsChunk",
        "summary": "Insights post metadata (paginated JSON)",
        "description": "Metadata for Insights posts, nine per chunk, newest first. Chunks are numbered from 1 (chunk 0 is inlined in the /insights HTML). Example: /insights/chunks/1.json.",
        "parameters": [
          {
            "name": "chunk",
            "in": "path",
            "required": true,
            "description": "Chunk file name, e.g. 1.json",
            "schema": { "type": "string", "pattern": "^[0-9]+\\.json$" }
          }
        ],
        "responses": {
          "200": {
            "description": "Array of post metadata",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": { "$ref": "#/components/schemas/PostMeta" }
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/JsonError" }
        }
      }
    },
    "/api/{path}": {
      "get": {
        "operationId": "apiPlaceholder",
        "summary": "Reserved: no public transactional API yet",
        "description": "PlatformD does not yet expose a public transactional API. Every request under /api/ returns a structured JSON 404 with a resolution hint. This path is documented so that agents receive a machine-readable answer rather than an HTML page.",
        "parameters": [
          {
            "name": "path",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "404": { "$ref": "#/components/responses/JsonError" }
        }
      }
    }
  },
  "components": {
    "responses": {
      "NegotiablePage": {
        "description": "Page content, negotiated via the Accept header. Responses carry Vary: Accept. Requests whose Accept header excludes both text/html and text/markdown receive 406 with an Error body.",
        "content": {
          "text/html": { "schema": { "type": "string" } },
          "text/markdown": { "schema": { "type": "string" } }
        }
      },
      "NotFoundPage": {
        "description": "Real HTTP 404. HTML body with recovery links by default; markdown body when the request prefers text/markdown.",
        "content": {
          "text/html": { "schema": { "type": "string" } },
          "text/markdown": { "schema": { "type": "string" } }
        }
      },
      "JsonError": {
        "description": "Structured JSON error",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["status", "code", "message", "hint"],
            "properties": {
              "status": {
                "type": "integer",
                "description": "HTTP status code"
              },
              "code": {
                "type": "string",
                "description": "Stable machine-readable error code",
                "examples": ["not_found", "not_acceptable"]
              },
              "message": {
                "type": "string",
                "description": "Human-readable explanation"
              },
              "hint": {
                "type": "string",
                "description": "Where to look next to resolve the error"
              }
            }
          }
        }
      },
      "PostMeta": {
        "type": "object",
        "required": ["slug", "title", "description", "date", "author", "tags"],
        "properties": {
          "slug": {
            "type": "string",
            "description": "Post slug; the article lives at /post/{slug}"
          },
          "title": { "type": "string" },
          "description": { "type": "string" },
          "date": {
            "type": "string",
            "format": "date",
            "description": "Publication date, ISO yyyy-mm-dd"
          },
          "author": { "type": "string" },
          "tags": { "type": "array", "items": { "type": "string" } },
          "cover": {
            "type": "string",
            "description": "Site-relative cover image path, when present"
          }
        }
      }
    }
  }
}
