{
  "openapi": "3.0.3",
  "info": {
    "title": "benmilne.com Developer API",
    "description": "Public read-only multilingual API for benmilne.com content. Supports 14 languages via ?lang= query parameter. English is the default and source of truth. SSE streaming available for real-time search.",
    "version": "2.0.0",
    "contact": {
      "name": "Ben Milne",
      "url": "https://benmilne.com/api"
    },
    "x-cli": {
      "name": "benmilne-api",
      "install": "npm install -g benmilne-api",
      "registry": "https://www.npmjs.com/package/benmilne-api"
    },
    "x-source": {
      "url": "https://github.com/benmilne-com/agents",
      "type": "github"
    },
    "x-ratelimit": {
      "strategy": "edge-cache",
      "description": "Cloudflare edge caching serves most reads. No application-level rate limit enforced. Headers included on every JSON response.",
      "headers": [
        "X-RateLimit-Limit",
        "X-RateLimit-Remaining",
        "X-RateLimit-Reset"
      ]
    },
    "x-graphql": {
      "endpoint": "https://benmilne.com/graphql",
      "introspection": true,
      "description": "Read-only GraphQL API with Relay cursor pagination, typed errors, and full schema descriptions. POST queries to /graphql."
    }
  },
  "externalDocs": {
    "description": "benmilne.com developer portal",
    "url": "https://benmilne.com/developers"
  },
  "servers": [
    {
      "url": "https://benmilne.com",
      "description": "Production"
    },
    {
      "url": "https://benmilne.com/sandbox",
      "description": "Sandbox (canned test data)"
    }
  ],
  "paths": {
    "/api/languages": {
      "get": {
        "operationId": "listLanguages",
        "summary": "List supported languages",
        "description": "Returns all supported languages with feed URLs, API URLs, and metadata.",
        "responses": {
          "200": {
            "description": "Language configuration",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LanguagesResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/site": {
      "get": {
        "operationId": "getSiteInfo",
        "summary": "Site metadata",
        "parameters": [
          {
            "name": "lang",
            "in": "query",
            "description": "Language code for translated response",
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "zh",
                "ar",
                "pt-br",
                "fr",
                "ja",
                "de",
                "ru",
                "id",
                "hi",
                "ko",
                "tr",
                "vi"
              ],
              "default": "en"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Site metadata and post count",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SiteInfoResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/posts": {
      "get": {
        "operationId": "listPosts",
        "summary": "Paginated post list",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 10,
              "maximum": 100
            }
          },
          {
            "name": "lang",
            "in": "query",
            "description": "Language code for translated response",
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "zh",
                "ar",
                "pt-br",
                "fr",
                "ja",
                "de",
                "ru",
                "id",
                "hi",
                "ko",
                "tr",
                "vi"
              ],
              "default": "en"
            }
          },
          {
            "name": "fallback",
            "in": "query",
            "description": "Set to 'en' to receive English content when translation is unavailable",
            "schema": {
              "type": "string",
              "enum": [
                "en"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated post list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedPostsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Unsupported language",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/posts/{slug}": {
      "get": {
        "operationId": "getPostBySlug",
        "summary": "Single post with full content",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "in": "query",
            "description": "Language code for translated response",
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "zh",
                "ar",
                "pt-br",
                "fr",
                "ja",
                "de",
                "ru",
                "id",
                "hi",
                "ko",
                "tr",
                "vi"
              ],
              "default": "en"
            }
          },
          {
            "name": "fallback",
            "in": "query",
            "description": "Set to 'en' to receive English content when translation is unavailable",
            "schema": {
              "type": "string",
              "enum": [
                "en"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Post detail with translated content",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostResponse"
                }
              }
            }
          },
          "400": {
            "description": "Unsupported language",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Post or translation not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TranslationUnavailableError"
                }
              }
            }
          }
        }
      }
    },
    "/api/search": {
      "get": {
        "operationId": "searchPosts",
        "summary": "Full-text search",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Search query (preferred)"
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Alias for q"
          },
          {
            "name": "lang",
            "in": "query",
            "description": "Language code for translated response",
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "zh",
                "ar",
                "pt-br",
                "fr",
                "ja",
                "de",
                "ru",
                "id",
                "hi",
                "ko",
                "tr",
                "vi"
              ],
              "default": "en"
            }
          },
          {
            "name": "fallback",
            "in": "query",
            "description": "Set to 'en' to receive English content when translation is unavailable",
            "schema": {
              "type": "string",
              "enum": [
                "en"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Search results",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedPostsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing query or unsupported language",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/categories": {
      "get": {
        "operationId": "listCategories",
        "summary": "All categories with post counts",
        "parameters": [
          {
            "name": "lang",
            "in": "query",
            "description": "Language code for translated response",
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "zh",
                "ar",
                "pt-br",
                "fr",
                "ja",
                "de",
                "ru",
                "id",
                "hi",
                "ko",
                "tr",
                "vi"
              ],
              "default": "en"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Category list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaxonomyListResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/categories/{slug}": {
      "get": {
        "operationId": "listPostsByCategory",
        "summary": "Posts filtered by category",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 10
            }
          },
          {
            "name": "lang",
            "in": "query",
            "description": "Language code for translated response",
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "zh",
                "ar",
                "pt-br",
                "fr",
                "ja",
                "de",
                "ru",
                "id",
                "hi",
                "ko",
                "tr",
                "vi"
              ],
              "default": "en"
            }
          },
          {
            "name": "fallback",
            "in": "query",
            "description": "Set to 'en' to receive English content when translation is unavailable",
            "schema": {
              "type": "string",
              "enum": [
                "en"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Category-filtered posts",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedPostsResponse"
                }
              }
            }
          },
          "404": {
            "description": "Category not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/tags": {
      "get": {
        "operationId": "listTags",
        "summary": "All tags with post counts",
        "parameters": [
          {
            "name": "lang",
            "in": "query",
            "description": "Language code for translated response",
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "zh",
                "ar",
                "pt-br",
                "fr",
                "ja",
                "de",
                "ru",
                "id",
                "hi",
                "ko",
                "tr",
                "vi"
              ],
              "default": "en"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tag list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaxonomyListResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/tags/{slug}": {
      "get": {
        "operationId": "listPostsByTag",
        "summary": "Posts filtered by tag",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 10
            }
          },
          {
            "name": "lang",
            "in": "query",
            "description": "Language code for translated response",
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "zh",
                "ar",
                "pt-br",
                "fr",
                "ja",
                "de",
                "ru",
                "id",
                "hi",
                "ko",
                "tr",
                "vi"
              ],
              "default": "en"
            }
          },
          {
            "name": "fallback",
            "in": "query",
            "description": "Set to 'en' to receive English content when translation is unavailable",
            "schema": {
              "type": "string",
              "enum": [
                "en"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tag-filtered posts",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedPostsResponse"
                }
              }
            }
          },
          "404": {
            "description": "Tag not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/mcp/v1/posts": {
      "get": {
        "operationId": "mcpListPosts",
        "summary": "MCP — List posts",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 10
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated post list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedPostsResponse"
                }
              }
            }
          }
        }
      }
    },
    "/mcp/v1/search": {
      "get": {
        "operationId": "mcpSearchPosts",
        "summary": "MCP — Search posts (legacy REST alias; prefer /api/search?q=)",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Search query"
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Alias for query"
          }
        ],
        "responses": {
          "200": {
            "description": "Matching posts",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedPostsResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/products/the-value-layer": {
      "get": {
        "operationId": "getValueLayerProduct",
        "summary": "Product metadata — The Value Layer PDF",
        "responses": {
          "200": {
            "description": "Structured product + commerce discovery URLs",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/stream/search": {
      "get": {
        "operationId": "streamSearch",
        "summary": "Real-time search via Server-Sent Events",
        "description": "Returns search results as an SSE stream. Events: 'status' (search phase), 'result' (individual post match), 'done' (completion summary), 'error' (failure). Each event data field is JSON.",
        "x-streaming": true,
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Search query"
          }
        ],
        "responses": {
          "200": {
            "description": "SSE event stream",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "Server-Sent Events stream with JSON data payloads"
                }
              }
            }
          },
          "400": {
            "description": "Missing query parameter",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/ask": {
      "post": {
        "operationId": "nlwebAsk",
        "summary": "NLWeb natural-language query",
        "description": "Accepts a natural-language question and returns matching content. Supports JSON or SSE streaming response.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "query": {
                    "type": "string",
                    "description": "Natural-language question"
                  },
                  "site": {
                    "type": "string",
                    "description": "Target site (default: benmilne.com)"
                  },
                  "streaming": {
                    "type": "boolean",
                    "description": "If true, return SSE stream instead of JSON",
                    "default": false
                  }
                },
                "required": [
                  "query"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Search results in NLWeb format or SSE stream",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NLWebResponse"
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Missing query",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/status": {
      "get": {
        "operationId": "getStatus",
        "summary": "Service health check",
        "responses": {
          "200": {
            "description": "Service status object",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatusResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/batch": {
      "post": {
        "operationId": "batchApiCalls",
        "summary": "Batch multiple API calls in one request",
        "description": "Execute up to 20 API calls in a single request. Each sub-request is executed in parallel and results are returned in order.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "requests": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "path": {
                          "type": "string",
                          "description": "API path starting with /api/"
                        },
                        "method": {
                          "type": "string",
                          "default": "GET"
                        }
                      },
                      "required": [
                        "path"
                      ]
                    },
                    "maxItems": 20
                  }
                },
                "required": [
                  "requests"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Batch results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          },
                          "body": {
                            "type": "object"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid batch request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/contact/send": {
      "post": {
        "operationId": "sendContactMessage",
        "summary": "Send a paid message via x402",
        "description": "Agent-to-human contact gated by x402 stablecoin payment. First request returns 402 with payment requirements and field schema. Retry with PAYMENT-SIGNATURE header after signing an ERC-2612 permit.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "sender": {
                    "type": "string",
                    "description": "Agent or service identifier"
                  },
                  "body": {
                    "type": "string",
                    "description": "Message content"
                  },
                  "reply_to": {
                    "type": "string",
                    "format": "email",
                    "description": "Email address for replies"
                  },
                  "callback": {
                    "type": "string",
                    "format": "uri",
                    "description": "Webhook endpoint for responses"
                  }
                },
                "required": [
                  "sender",
                  "body"
                ]
              }
            }
          }
        },
        "parameters": [
          {
            "name": "PAYMENT-SIGNATURE",
            "in": "header",
            "description": "Base64-encoded x402 payment payload (ERC-2612 permit)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Message delivered with payment receipt",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "txHash": {
                      "type": "string"
                    },
                    "receipt": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Payment required — includes price, accepted assets, and field schema",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    },
                    "price": {
                      "type": "string"
                    },
                    "accepts": {
                      "type": "array"
                    },
                    "fields": {
                      "type": "array"
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Required fields missing",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Contact endpoint disabled or not configured"
          }
        }
      }
    },
    "/graphql": {
      "post": {
        "operationId": "graphqlQuery",
        "summary": "GraphQL query endpoint",
        "description": "Execute GraphQL queries against the benmilne.com content schema. Supports Relay cursor pagination, typed errors (extensions.code), and introspection.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "query": {
                    "type": "string",
                    "description": "GraphQL query string"
                  },
                  "variables": {
                    "type": "object",
                    "description": "Query variables"
                  },
                  "operationName": {
                    "type": "string",
                    "description": "Operation name for multi-operation documents"
                  }
                },
                "required": [
                  "query"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "GraphQL response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object"
                    },
                    "errors": {
                      "type": "array"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "graphqlIntrospection",
        "summary": "GraphQL schema introspection",
        "description": "Returns the full GraphQL schema in SDL format (text/plain) or JSON introspection (Accept: application/json).",
        "responses": {
          "200": {
            "description": "GraphQL schema",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              },
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "supported_languages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "error"
        ]
      },
      "TranslationUnavailableError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "language": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "missing",
              "stale"
            ]
          },
          "english_url": {
            "type": "string"
          },
          "fallback_url": {
            "type": "string"
          }
        },
        "required": [
          "error",
          "slug",
          "language"
        ]
      },
      "TranslationMeta": {
        "type": "object",
        "properties": {
          "automated": {
            "type": "boolean"
          },
          "provider": {
            "type": "string",
            "nullable": true
          },
          "source_language": {
            "type": "string"
          },
          "target_language": {
            "type": "string"
          },
          "verified": {
            "type": "boolean"
          },
          "stale": {
            "type": "boolean"
          },
          "fallback_used": {
            "type": "boolean"
          }
        }
      },
      "ResponseMeta": {
        "type": "object",
        "properties": {
          "language": {
            "type": "string"
          },
          "source_language": {
            "type": "string"
          },
          "is_translation": {
            "type": "boolean"
          },
          "automated_translation": {
            "type": "boolean"
          },
          "disclaimer": {
            "type": "string"
          },
          "available_languages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "language",
          "source_language",
          "is_translation",
          "available_languages"
        ]
      },
      "PostSummary": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "date": {
            "type": "string"
          },
          "modified": {
            "type": "string"
          },
          "author": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "language": {
            "type": "string"
          },
          "is_translation": {
            "type": "boolean"
          },
          "english_url": {
            "type": "string"
          },
          "translation": {
            "$ref": "#/components/schemas/TranslationMeta"
          }
        },
        "required": [
          "slug",
          "title",
          "date",
          "author",
          "url",
          "language"
        ]
      },
      "PaginatedPostsResponse": {
        "type": "object",
        "properties": {
          "attribution": {
            "type": "string"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PostSummary"
            }
          },
          "pagination": {
            "type": "object",
            "properties": {
              "page": {
                "type": "integer"
              },
              "per_page": {
                "type": "integer"
              },
              "total": {
                "type": "integer"
              },
              "total_pages": {
                "type": "integer"
              }
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        },
        "required": [
          "attribution",
          "data"
        ]
      },
      "PostResponse": {
        "type": "object",
        "properties": {
          "attribution": {
            "type": "string"
          },
          "data": {
            "type": "object"
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        },
        "required": [
          "attribution",
          "data"
        ]
      },
      "LanguagesResponse": {
        "type": "object",
        "properties": {
          "default_language": {
            "type": "string"
          },
          "total_languages": {
            "type": "integer"
          },
          "translated_languages": {
            "type": "integer"
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string"
                },
                "native_name": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "dir": {
                  "type": "string"
                },
                "html_lang": {
                  "type": "string"
                },
                "hreflang": {
                  "type": "string"
                },
                "site_url": {
                  "type": "string"
                },
                "api_url": {
                  "type": "string"
                },
                "feed_url": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "StatusResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string"
          },
          "service": {
            "type": "string"
          },
          "timestamp": {
            "type": "string"
          },
          "host": {
            "type": "string"
          },
          "version": {
            "type": "string"
          }
        },
        "required": [
          "status",
          "service",
          "timestamp",
          "host"
        ]
      },
      "SiteInfoResponse": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "author": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "post_count": {
            "type": "integer"
          },
          "attribution": {
            "type": "string"
          }
        }
      },
      "TaxonomyListResponse": {
        "type": "object",
        "properties": {
          "attribution": {
            "type": "string"
          },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "slug": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "count": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "ProductResponse": {
        "type": "object",
        "properties": {
          "attribution": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "format": {
            "type": "string"
          },
          "price_usd": {
            "type": "number"
          },
          "currency": {
            "type": "string"
          },
          "landing_url": {
            "type": "string"
          },
          "download_url": {
            "type": "string"
          },
          "api_url": {
            "type": "string"
          }
        }
      },
      "NLWebResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "success",
              "error"
            ]
          },
          "query": {
            "type": "string"
          },
          "site": {
            "type": "string"
          },
          "response": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "url": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                },
                "date": {
                  "type": "string"
                }
              }
            }
          }
        },
        "required": [
          "status",
          "query",
          "response"
        ]
      }
    },
    "securitySchemes": {
      "public": {
        "type": "http",
        "scheme": "bearer",
        "description": "All read endpoints are public and unauthenticated. No API key or token is required."
      }
    }
  },
  "security": [
    {
      "public": []
    }
  ],
  "x-webhooks": {
    "stream-event": {
      "post": {
        "summary": "SSE stream event delivery",
        "description": "Events delivered via Server-Sent Events streams (/api/stream/search, /ask). Each event data payload includes an HMAC-SHA256 signature for integrity verification.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "event": {
                    "type": "string",
                    "description": "Event type (status, result, done, error)"
                  },
                  "data": {
                    "type": "object",
                    "description": "Event payload"
                  },
                  "signature": {
                    "type": "string",
                    "description": "HMAC-SHA256 signature: sha256=<hex>"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Event acknowledged"
          }
        },
        "security": [
          {
            "webhookSignature": []
          }
        ]
      }
    }
  }
}