{
    "openapi": "3.1.0",
    "info": {
        "title": "MiriamSchwab.me API",
        "version": "1.22.3",
        "summary": "Read this site's content as JSON or Markdown, without parsing HTML.",
        "description": "Miriam's Site\n\nEverything documented here is public and requires no authentication.\n\n**Which endpoint to use:**\n\n- To read one page, append `.md` to its normal URL — `https://miriamschwab.me/about.md`. That returns clean Markdown and is cheaper than fetching the HTML and stripping tags.\n- To see what content exists, fetch `/llms.txt` — one line per page, in one request.\n- To read the entire site at once, fetch `/llms-full.txt`.\n- To search or filter, use the JSON routes under `/wp-json/wp/v2/`.\n\n**Errors** are always JSON, never an HTML page. Every failing request returns an object with `code`, `message` and `data.status` — see the `Error` schema. Send `Accept: application/json` to get that shape from any URL on this site, including one that is not a documented route.\n\n**Authentication:** none, anywhere. The root `security: []` says so formally; [`/auth.md`](https://miriamschwab.me/auth.md) says so in prose, including what to do about the one endpoint that uses a single-use token.\n\n**Rate limits:** only the MCP endpoint is limited. It returns `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` on every response, and `Retry-After` on a 429, so you can pace yourself rather than discover the limit by hitting it. The plain HTTP routes are unlimited.\n\n**Versioning:** this description is regenerated from the live site, so it always matches what is deployed. Paths under `/wp-json/` carry their own version segment. Nothing here is scheduled for removal; if that changes, retiring routes will carry `Deprecation` and `Sunset` headers (RFC 9745 / RFC 8594) before they stop working.\n\n**Writing:** one endpoint takes an action — `POST /wp-json/miriamschwab/v1/contact` sends Miriam a message. It is rate limited (10 per IP per hour, 25 site-wide per day), it needs a single-use token from a GET on the same URL, and it accepts an `Idempotency-Key` header so a retry cannot deliver twice."
    },
    "servers": [
        {
            "url": "https://miriamschwab.me",
            "description": "MiriamSchwab.me"
        }
    ],
    "security": [],
    "paths": {
        "/llms.txt": {
            "get": {
                "operationId": "llms",
                "summary": "Content index for language models",
                "description": "A curated, one-line-per-page index of this site, in the llms.txt format. The cheapest way to find out what exists here.",
                "responses": {
                    "200": {
                        "description": "The document.",
                        "content": {
                            "text/plain": {
                                "schema": {
                                    "type": "string"
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    },
                    "5XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "default": {
                        "$ref": "#/components/responses/Error"
                    }
                }
            }
        },
        "/llms-full.txt": {
            "get": {
                "operationId": "llmsFull",
                "summary": "Every page as one document",
                "description": "The full Markdown text of every published post and page, concatenated, each entry separated by `---` with its title and URL. One request for the whole corpus.",
                "responses": {
                    "200": {
                        "description": "The document.",
                        "content": {
                            "text/plain": {
                                "schema": {
                                    "type": "string"
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    },
                    "5XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "default": {
                        "$ref": "#/components/responses/Error"
                    }
                }
            }
        },
        "/.well-known/api-catalog": {
            "get": {
                "operationId": "apiCatalog",
                "summary": "Machine-readable endpoint catalog",
                "description": "This site's endpoints as an RFC 9264 linkset (RFC 9727).",
                "responses": {
                    "200": {
                        "description": "The document.",
                        "content": {
                            "application/linkset+json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    },
                    "5XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "default": {
                        "$ref": "#/components/responses/Error"
                    }
                }
            }
        },
        "/.well-known/agent-skills/index.json": {
            "get": {
                "operationId": "agentSkills",
                "summary": "Agent Skills discovery index",
                "description": "Lists the skills this site publishes, each pointing at a SKILL.md describing how to work with the site.",
                "responses": {
                    "200": {
                        "description": "The document.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    },
                    "5XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "default": {
                        "$ref": "#/components/responses/Error"
                    }
                }
            }
        },
        "/.well-known/security.txt": {
            "get": {
                "operationId": "securityTxt",
                "summary": "Security contact",
                "description": "How to report a security issue with this site (RFC 9116).",
                "responses": {
                    "200": {
                        "description": "The document.",
                        "content": {
                            "text/plain": {
                                "schema": {
                                    "type": "string"
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    },
                    "5XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "default": {
                        "$ref": "#/components/responses/Error"
                    }
                }
            }
        },
        "/wp-json/mmsar/v1/mcp": {
            "post": {
                "operationId": "mcp",
                "summary": "Model Context Protocol endpoint",
                "description": "A read-only MCP server over Streamable HTTP, exposing this site's content as MCP tools. Requires no authentication. If your client speaks MCP, connect to this URL directly instead of using the routes above.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "description": "A JSON-RPC 2.0 request, as defined by the Model Context Protocol."
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "A JSON-RPC 2.0 response.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "202": {
                        "description": "The request was a JSON-RPC notification, which has no response."
                    },
                    "400": {
                        "description": "The body was not valid JSON. Returned as a JSON-RPC error object with code -32700."
                    },
                    "429": {
                        "description": "Rate limit exceeded. Returned as a JSON-RPC error object with code -32000. Read `RateLimit-Reset` and `Retry-After` before retrying."
                    },
                    "5XX": {
                        "$ref": "#/components/responses/Error"
                    }
                }
            }
        },
        "/{slug}.md": {
            "get": {
                "operationId": "getPageMarkdown",
                "summary": "Read one page as Markdown",
                "description": "Returns the Markdown source of a single published post or page. The path mirrors the page's normal URL with `.md` appended, so `https://miriamschwab.me/about/` is available at `https://miriamschwab.me/about.md`. The homepage is at `/index.md`. Prefer this over fetching and parsing the HTML.",
                "parameters": [
                    {
                        "name": "slug",
                        "in": "path",
                        "required": true,
                        "description": "The page's path without leading or trailing slashes, exactly as it appears in its canonical URL. Use `index` for the homepage.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "about"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The page as Markdown.",
                        "content": {
                            "text/markdown": {
                                "schema": {
                                    "type": "string"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "The page is password protected. Returned as Markdown, not JSON.",
                        "content": {
                            "text/markdown": {
                                "schema": {
                                    "type": "string"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No published page at that path, or Markdown is not available for its post type. Returned as Markdown, not JSON, with links to where the content might be instead.",
                        "content": {
                            "text/markdown": {
                                "schema": {
                                    "type": "string"
                                }
                            }
                        }
                    },
                    "5XX": {
                        "$ref": "#/components/responses/Error"
                    }
                }
            }
        },
        "/wp-json/wp/v2/posts": {
            "get": {
                "operationId": "listPosts",
                "summary": "List posts",
                "description": "Published posts, newest first. Supports search, pagination and filtering by category or tag.",
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "type": "object"
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/Error"
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    },
                    "429": {
                        "$ref": "#/components/responses/Error"
                    },
                    "4XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "5XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "default": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "parameters": [
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Limit results to those matching this search term.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "description": "Page of results to return. Default 1.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Results per page, 1-100. Default 10.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "categories",
                        "in": "query",
                        "required": false,
                        "description": "Comma-separated category ids.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "tags",
                        "in": "query",
                        "required": false,
                        "description": "Comma-separated tag ids.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "slug",
                        "in": "query",
                        "required": false,
                        "description": "Limit results to the item with this slug.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ]
            }
        },
        "/wp-json/wp/v2/posts/{id}": {
            "get": {
                "operationId": "getPosts",
                "summary": "Get a single post",
                "description": "One post by numeric id.",
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/Error"
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    },
                    "429": {
                        "$ref": "#/components/responses/Error"
                    },
                    "4XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "5XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "default": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            }
        },
        "/wp-json/wp/v2/pages": {
            "get": {
                "operationId": "listPages",
                "summary": "List pages",
                "description": "Published pages. Supports search, pagination and filtering by slug or parent.",
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "type": "object"
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/Error"
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    },
                    "429": {
                        "$ref": "#/components/responses/Error"
                    },
                    "4XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "5XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "default": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "parameters": [
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Limit results to those matching this search term.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "description": "Page of results to return. Default 1.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Results per page, 1-100. Default 10.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "slug",
                        "in": "query",
                        "required": false,
                        "description": "Limit results to the item with this slug.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "parent",
                        "in": "query",
                        "required": false,
                        "description": "Limit results to children of this page id.",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            }
        },
        "/wp-json/wp/v2/pages/{id}": {
            "get": {
                "operationId": "getPages",
                "summary": "Get a single page",
                "description": "One page by numeric id.",
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/Error"
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    },
                    "429": {
                        "$ref": "#/components/responses/Error"
                    },
                    "4XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "5XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "default": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            }
        },
        "/wp-json/wp/v2/search": {
            "get": {
                "operationId": "listSearch",
                "summary": "Search the site",
                "description": "Search across every searchable post type at once. Returns id, title, url and type for each hit — fetch the full text from the url with a .md suffix.",
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "type": "object"
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/Error"
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    },
                    "429": {
                        "$ref": "#/components/responses/Error"
                    },
                    "4XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "5XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "default": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "parameters": [
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Limit results to those matching this search term.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "description": "Page of results to return. Default 1.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Results per page, 1-100. Default 10.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "type",
                        "in": "query",
                        "required": false,
                        "description": "Object type to search: `post`, `term` or `post-format`.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "subtype",
                        "in": "query",
                        "required": false,
                        "description": "Narrow the search to one post type, e.g. `post` or `page`.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ]
            }
        },
        "/wp-json/wp/v2/categories": {
            "get": {
                "operationId": "listCategories",
                "summary": "List categories",
                "description": "Every category with its slug and post count.",
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "type": "object"
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/Error"
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    },
                    "429": {
                        "$ref": "#/components/responses/Error"
                    },
                    "4XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "5XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "default": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "parameters": [
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Limit results to those matching this search term.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "description": "Page of results to return. Default 1.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Results per page, 1-100. Default 10.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "slug",
                        "in": "query",
                        "required": false,
                        "description": "Limit results to the item with this slug.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ]
            }
        },
        "/wp-json/wp/v2/tags": {
            "get": {
                "operationId": "listTags",
                "summary": "List tags",
                "description": "Every tag with its slug and post count.",
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "type": "object"
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/Error"
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    },
                    "429": {
                        "$ref": "#/components/responses/Error"
                    },
                    "4XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "5XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "default": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "parameters": [
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Limit results to those matching this search term.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "description": "Page of results to return. Default 1.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Results per page, 1-100. Default 10.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "slug",
                        "in": "query",
                        "required": false,
                        "description": "Limit results to the item with this slug.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ]
            }
        },
        "/wp-json/miriamschwab/v1/contact": {
            "get": {
                "operationId": "contact_miriam_schwabGet",
                "summary": "Send Miriam Schwab a message",
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "4XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "5XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "default": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "description": "Returns the input schema for the POST, the rate limits, and a single-use `submit_token` valid for 15 minutes. Call this first: the POST is rejected without a token from here. The response is never cached, because every call issues a fresh token."
            },
            "post": {
                "operationId": "contact_miriam_schwabPost",
                "summary": "Send Miriam Schwab a message",
                "responses": {
                    "200": {
                        "description": "Delivered — or, if `replayed` is true, already delivered by an earlier request with the same Idempotency-Key.",
                        "headers": {
                            "Idempotency-Replayed": {
                                "description": "`true` when this response came from the idempotency record rather than a fresh send. Absent when no Idempotency-Key was supplied.",
                                "schema": {
                                    "type": "string",
                                    "enum": [
                                        "true",
                                        "false"
                                    ]
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "sent",
                                        "message"
                                    ],
                                    "properties": {
                                        "sent": {
                                            "type": "boolean",
                                            "description": "Always true on a 200."
                                        },
                                        "message": {
                                            "type": "string",
                                            "description": "Human-readable confirmation."
                                        },
                                        "replayed": {
                                            "type": "boolean",
                                            "description": "Present and true only on an idempotent replay. Nothing was sent for this request."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/Error"
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    },
                    "409": {
                        "$ref": "#/components/responses/Error"
                    },
                    "422": {
                        "$ref": "#/components/responses/Error"
                    },
                    "429": {
                        "$ref": "#/components/responses/Error"
                    },
                    "5XX": {
                        "$ref": "#/components/responses/Error"
                    },
                    "default": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "description": "Sends a message to Miriam Schwab. It lands in a real inbox that a human reads, and it cannot be unsent — confirm the wording with your user before calling this. Requires a `submit_token` from a GET on this same URL. Send an `Idempotency-Key` header so that a retry after a network failure returns the original result instead of delivering a second copy.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "name",
                                    "email",
                                    "message",
                                    "submit_token"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "maxLength": 100,
                                        "description": "Name of the person the message is from. If you are an agent acting for someone, use their name, not yours."
                                    },
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "maxLength": 254,
                                        "description": "A real reply-to address for the person named above. Replies go here."
                                    },
                                    "subject": {
                                        "type": "string",
                                        "maxLength": 200,
                                        "description": "Short subject line, e.g. \"speaking invite\" or \"podcast\"."
                                    },
                                    "message": {
                                        "type": "string",
                                        "maxLength": 5000,
                                        "description": "The message body, in plain text."
                                    },
                                    "agent": {
                                        "type": "string",
                                        "maxLength": 80,
                                        "description": "Optional. Identify yourself if you are an agent, e.g. \"Claude\". Shown to Miriam; it does not affect delivery."
                                    },
                                    "submit_token": {
                                        "type": "string",
                                        "description": "Single-use token from a GET on this same URL. Valid 15 minutes."
                                    }
                                }
                            },
                            "example": {
                                "name": "Ada Lovelace",
                                "email": "ada@example.com",
                                "subject": "Podcast invitation",
                                "message": "Would you come on our show to talk about WordPress and agents?",
                                "agent": "Claude",
                                "submit_token": "from-the-GET-on-this-url"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "description": "A unique key for this message — a UUID. The outcome of the first POST carrying a given key is recorded for 24 hours; any later POST with the same key is answered from that record without sending a second message, and comes back with `Idempotency-Replayed: true`. This is the only safe way to retry, because the `submit_token` is single-use: without a key, a retry after a lost response is either a duplicate message or a 401 you cannot interpret. Same key with a different body is refused with 422. An attempt that failed records nothing, so you may retry it with the same key.",
                        "schema": {
                            "type": "string",
                            "minLength": 16,
                            "maxLength": 255,
                            "pattern": "^[\\x21-\\x7E]+$",
                            "examples": [
                                "4f6c2f2a-9a1e-4a2b-9c0f-2a7b1d3e5f80"
                            ]
                        }
                    }
                ]
            }
        }
    },
    "components": {
        "schemas": {
            "Error": {
                "type": "object",
                "title": "Error",
                "description": "Every error from this site has this shape, including a 404 on a URL that is not part of any documented route — ask for `application/json` and that is what comes back. Errors are never returned as HTML to a client that asked for JSON.",
                "required": [
                    "code",
                    "message",
                    "data"
                ],
                "properties": {
                    "code": {
                        "type": "string",
                        "description": "Stable machine-readable error code, e.g. `rest_post_invalid_id`. Match on this, not on the message.",
                        "examples": [
                            "rest_no_route",
                            "rest_post_invalid_id"
                        ]
                    },
                    "message": {
                        "type": "string",
                        "description": "Human-readable explanation of what went wrong.",
                        "examples": [
                            "Invalid post ID."
                        ]
                    },
                    "data": {
                        "type": "object",
                        "description": "Additional context.",
                        "properties": {
                            "status": {
                                "type": "integer",
                                "description": "The HTTP status code, repeated here so it survives transports that drop it.",
                                "examples": [
                                    404
                                ]
                            },
                            "params": {
                                "type": "object",
                                "description": "Present on validation failures: which parameters were rejected, and why."
                            }
                        }
                    },
                    "links": {
                        "type": "array",
                        "description": "Present on 404s: where to look instead. The same destinations the response carries as `Link` headers, repeated in the body for clients that do not read headers.",
                        "items": {
                            "type": "object",
                            "properties": {
                                "href": {
                                    "type": "string"
                                },
                                "rel": {
                                    "type": "string"
                                },
                                "type": {
                                    "type": "string"
                                },
                                "title": {
                                    "type": "string"
                                }
                            }
                        }
                    }
                }
            }
        },
        "responses": {
            "Error": {
                "description": "A structured JSON error. Read `code` to decide what to do next.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            }
        }
    },
    "externalDocs": {
        "description": "Plain-text index of this site's content, written for language models.",
        "url": "https://miriamschwab.me/llms.txt"
    }
}