openapi: 3.0.0 info: title: Ben Milne API description: Official API for benmilne.com content version: 1.0.0 contact: name: Ben Milne url: https://benmilne.com servers: - url: https://benmilne.com/wp-json/mcp/v1 description: Production API tags: - name: posts description: Operations for retrieving blog posts - name: search description: Search operations - name: taxonomies description: Category and tag operations paths: /post/{id}: get: summary: Get a single post by ID description: Retrieve detailed metadata for a specific post including full content, media, links, taxonomies, structured sections, and relationships tags: - posts parameters: - name: id in: path description: Post ID required: true schema: type: integer example: 111693 responses: '200': description: Detailed post information content: application/json: schema: $ref: '#/components/schemas/PostDetailed' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/ServerError' /posts: get: summary: List posts with pagination description: Get a paginated list of posts along with their summaries and essential metadata tags: - posts parameters: - name: per_page in: query description: Number of posts per page required: false schema: type: integer default: 10 minimum: 1 maximum: 100 - name: page in: query description: Page number required: false schema: type: integer default: 1 minimum: 1 responses: '200': description: Paginated list of posts content: application/json: schema: $ref: '#/components/schemas/PostList' '400': $ref: '#/components/responses/BadRequest' '500': $ref: '#/components/responses/ServerError' /search: get: summary: Search posts description: Retrieve up to 100 posts that match a given search query tags: - search parameters: - name: query in: query description: Search keyword required: true schema: type: string example: stablecoin responses: '200': description: Search results content: application/json: schema: $ref: '#/components/schemas/SearchResults' '400': $ref: '#/components/responses/BadRequest' '500': $ref: '#/components/responses/ServerError' /category/{category-slug}: get: summary: Get posts by category description: Filter posts by a specific category tags: - taxonomies parameters: - name: category-slug in: path description: Category slug required: true schema: type: string example: brale - name: per_page in: query description: Number of posts per page required: false schema: type: integer default: 10 minimum: 1 maximum: 100 - name: page in: query description: Page number required: false schema: type: integer default: 1 minimum: 1 responses: '200': description: Posts in the specified category content: application/json: schema: $ref: '#/components/schemas/PostList' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/ServerError' /tag/{tag-slug}: get: summary: Get posts by tag description: Filter posts by a specific tag tags: - taxonomies parameters: - name: tag-slug in: path description: Tag slug required: true schema: type: string example: stablecoin - name: per_page in: query description: Number of posts per page required: false schema: type: integer default: 10 minimum: 1 maximum: 100 - name: page in: query description: Page number required: false schema: type: integer default: 1 minimum: 1 responses: '200': description: Posts with the specified tag content: application/json: schema: $ref: '#/components/schemas/PostList' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/ServerError' components: responses: BadRequest: description: Bad request content: application/json: schema: type: object properties: code: type: string message: type: string example: code: "invalid_request" message: "Invalid request parameters" NotFound: description: Resource not found content: application/json: schema: type: object properties: code: type: string message: type: string example: code: "not_found" message: "Resource not found" ServerError: description: Internal server error content: application/json: schema: type: object properties: code: type: string message: type: string example: code: "server_error" message: "An unexpected error occurred" schemas: PostBasic: type: object properties: id: type: integer description: The post ID title: type: string description: The post title slug: type: string description: URL-friendly slug excerpt: type: string description: Short summary of the post date: type: string format: date-time description: Publication date modified: type: string format: date-time description: Last modification date featured_image: type: object properties: url: type: string format: uri alt: type: string description: Featured image for the post PostDetailed: allOf: - $ref: '#/components/schemas/PostBasic' - type: object properties: content: type: string description: Full post content (decoded and cleaned) media: type: array items: type: object properties: id: type: integer url: type: string format: uri type: type: string alt: type: string description: Media items embedded in the post links: type: array items: type: object properties: url: type: string format: uri text: type: string external: type: boolean description: Links found in the post content taxonomies: type: object properties: categories: type: array items: $ref: '#/components/schemas/Taxonomy' tags: type: array items: $ref: '#/components/schemas/Taxonomy' description: Post categories and tags sections: type: array items: type: object properties: level: type: integer description: Heading level (h1-h6) text: type: string description: Heading text id: type: string description: Generated ID for the heading description: Structured sections (headings) relationships: type: object properties: previous: $ref: '#/components/schemas/PostBasic' description: Previous post in chronological order next: $ref: '#/components/schemas/PostBasic' description: Next post in chronological order description: Related posts attribution: type: string description: Attribution notice PostList: type: object properties: data: type: array items: $ref: '#/components/schemas/PostBasic' meta: type: object properties: current_page: type: integer per_page: type: integer total: type: integer total_pages: type: integer links: type: object properties: prev_page_url: type: string format: uri nullable: true next_page_url: type: string format: uri nullable: true SearchResults: type: object properties: query: type: string description: The search query results: type: array items: $ref: '#/components/schemas/PostBasic' count: type: integer description: Number of results found Taxonomy: type: object properties: id: type: integer name: type: string slug: type: string url: type: string format: uri