{
    "openapi": "3.0.3",
    "info": {
        "title": "BenMilne.com public APIs",
        "description": "Read-mostly HTTP APIs for agents and integrations: MCP-style post metadata (`mcp/v1`), site discovery (`bmar/v1`), theme search (`bm/v1`), and optional x402 micropayment gates (`x402/v1`). OAuth metadata here is discovery-oriented; not all flows are implemented for third-party clients. **Read order for humans and shallow crawlers:** (1) human overview at `/api/`, (2) this OpenAPI document, (3) `/llms.txt` and `/agents.md`, (4) `/.well-known/api-catalog` and MCP server card.",
        "version": "1.0.0",
        "contact": {
            "name": "Ben Milne",
            "url": "https://benmilne.com"
        }
    },
    "externalDocs": {
        "description": "Human-readable API overview, example URLs, and usage notes.",
        "url": "https://benmilne.com/api/"
    },
    "servers": [
        {
            "url": "https://benmilne.com"
        }
    ],
    "tags": [
        {
            "name": "mcp",
            "description": "Public MCP-style metadata API (posts, search, taxonomies)."
        },
        {
            "name": "bmar",
            "description": "Agent discovery: API Linkset, OAuth/OIDC-style metadata, MCP server card, Agent Skills index."
        },
        {
            "name": "bm",
            "description": "Theme search API used by the site UI (title match)."
        },
        {
            "name": "x402",
            "description": "HTTP 402 / x402 micropayment content gate (optional)."
        }
    ],
    "paths": {
        "/wp-json/mcp/v1/post/{id}": {
            "get": {
                "tags": [
                    "mcp"
                ],
                "summary": "Get post by ID",
                "description": "Full post HTML content, media, taxonomies, outbound links, H2 sections, and prev/next relationships.",
                "operationId": "mcpGetPost",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        },
                        "description": "WordPress post ID"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Wrapped post metadata",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/McpEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Unknown post ID",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RestError"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/wp-json/mcp/v1/search": {
            "get": {
                "tags": [
                    "mcp"
                ],
                "summary": "Search posts",
                "description": "Full-text style search over published posts; returns up to 100 matches.",
                "operationId": "mcpSearch",
                "parameters": [
                    {
                        "name": "query",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "minLength": 1
                        },
                        "description": "Search string"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "List of matching posts (envelope)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/McpEnvelope"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Missing query",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RestError"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No posts matched",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RestError"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/wp-json/mcp/v1/posts": {
            "get": {
                "tags": [
                    "mcp"
                ],
                "summary": "List posts (paginated)",
                "operationId": "mcpListPosts",
                "parameters": [
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 10,
                            "minimum": 1
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 1,
                            "minimum": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Posts array plus pagination fields",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/McpEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No published posts",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RestError"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/wp-json/mcp/v1/category/{slug}": {
            "get": {
                "tags": [
                    "mcp"
                ],
                "summary": "Posts in category",
                "operationId": "mcpCategory",
                "parameters": [
                    {
                        "name": "slug",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Category slug"
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 10,
                            "minimum": 1
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 1,
                            "minimum": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Category archive (envelope)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/McpEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No posts in category",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RestError"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/wp-json/mcp/v1/tag/{slug}": {
            "get": {
                "tags": [
                    "mcp"
                ],
                "summary": "Posts with tag",
                "operationId": "mcpTag",
                "parameters": [
                    {
                        "name": "slug",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Tag slug"
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 10,
                            "minimum": 1
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 1,
                            "minimum": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Tag archive (envelope)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/McpEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No posts with tag",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RestError"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/wp-json/bmar/v1/api-catalog": {
            "get": {
                "tags": [
                    "bmar"
                ],
                "summary": "RFC 9727 API Linkset",
                "description": "Machine-readable catalog of primary service anchors.",
                "operationId": "bmarApiCatalog",
                "responses": {
                    "200": {
                        "description": "application/linkset+json",
                        "content": {
                            "application/linkset+json": {
                                "schema": {
                                    "type": "object"
                                }
                            },
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/wp-json/bmar/v1/openid-configuration": {
            "get": {
                "tags": [
                    "bmar"
                ],
                "summary": "OpenID Provider metadata (discovery)",
                "operationId": "bmarOpenIdConfiguration",
                "responses": {
                    "200": {
                        "description": "OIDC-style discovery document",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/wp-json/bmar/v1/oauth-protected-resource": {
            "get": {
                "tags": [
                    "bmar"
                ],
                "summary": "RFC 9728 OAuth protected resource metadata",
                "operationId": "bmarOAuthProtectedResource",
                "responses": {
                    "200": {
                        "description": "Resource metadata",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/wp-json/bmar/v1/mcp-server-card": {
            "get": {
                "tags": [
                    "bmar"
                ],
                "summary": "MCP server card (SEP-style)",
                "operationId": "bmarMcpServerCard",
                "responses": {
                    "200": {
                        "description": "Server info, transport, tools, resources",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/wp-json/bmar/v1/agent-skills": {
            "get": {
                "tags": [
                    "bmar"
                ],
                "summary": "Agent Skills discovery index",
                "operationId": "bmarAgentSkillsIndex",
                "responses": {
                    "200": {
                        "description": "Skills index JSON",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/wp-json/bmar/v1/agent-skills/{skill}": {
            "get": {
                "tags": [
                    "bmar"
                ],
                "summary": "Single Agent Skill (markdown)",
                "description": "Allowed values: `mcp-api`, `content-search`.",
                "operationId": "bmarAgentSkillFile",
                "parameters": [
                    {
                        "name": "skill",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "mcp-api",
                                "content-search"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "SKILL.md body",
                        "content": {
                            "text/markdown": {
                                "schema": {
                                    "type": "string"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Unknown skill",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RestError"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/wp-json/bm/v1/search": {
            "get": {
                "tags": [
                    "bm"
                ],
                "summary": "Title search (posts, pages, images)",
                "description": "Returns a flat JSON array of hits (not the MCP envelope). Empty array if query missing or shorter than 2 characters.",
                "operationId": "bmSearch",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "minLength": 2
                        },
                        "description": "Search string (AND across words)"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Array of result objects with type, title, url, optional date",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "type": "object"
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/wp-json/x402/v1/settings": {
            "get": {
                "tags": [
                    "x402"
                ],
                "summary": "Public x402 gate settings",
                "operationId": "x402Settings",
                "responses": {
                    "200": {
                        "description": "Public configuration",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/wp-json/x402/v1/verify": {
            "post": {
                "tags": [
                    "x402"
                ],
                "summary": "Verify payment",
                "operationId": "x402Verify",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "transaction_hash"
                                ],
                                "properties": {
                                    "transaction_hash": {
                                        "type": "string"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Verification outcome"
                    },
                    "400": {
                        "description": "Invalid request",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RestError"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/wp-json/x402/v1/content/{post_id}": {
            "post": {
                "tags": [
                    "x402"
                ],
                "summary": "Retrieve gated content after payment",
                "operationId": "x402Content",
                "parameters": [
                    {
                        "name": "post_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        },
                        "description": "Post ID"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "gate_id",
                                    "payment_receipt"
                                ],
                                "properties": {
                                    "gate_id": {
                                        "type": "string"
                                    },
                                    "payment_receipt": {
                                        "type": "object"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Gated content payload"
                    },
                    "402": {
                        "description": "Payment required / invalid receipt",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RestError"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Post or gate not found",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RestError"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "none": {
                "type": "http",
                "scheme": "bearer",
                "description": "Public read endpoints require **no authentication**. Bearer scheme is declared for tooling compatibility; omit the header for normal use. Discovery-only OAuth/OIDC metadata is at `/.well-known/openid-configuration`."
            }
        },
        "schemas": {
            "McpEnvelope": {
                "type": "object",
                "description": "All successful `mcp/v1` JSON responses use this envelope.",
                "required": [
                    "attribution",
                    "data"
                ],
                "properties": {
                    "attribution": {
                        "type": "string"
                    },
                    "data": {
                        "description": "Endpoint-specific payload (object or array)."
                    }
                }
            },
            "RestError": {
                "type": "object",
                "description": "WordPress REST API error shape. Returned for all 4xx/5xx responses.",
                "required": [
                    "code",
                    "message",
                    "data"
                ],
                "properties": {
                    "code": {
                        "type": "string",
                        "example": "no_post"
                    },
                    "message": {
                        "type": "string",
                        "example": "Invalid post ID"
                    },
                    "data": {
                        "type": "object",
                        "properties": {
                            "status": {
                                "type": "integer",
                                "example": 404
                            }
                        }
                    }
                }
            }
        }
    },
    "security": [
        []
    ]
}