{
  "openapi": "3.1.0",
  "info": {
    "title": "Kilnwood Public API",
    "version": "1.0.0",
    "description": "Public read-only API for Kilnwood, a marketplace for handmade and vintage goods. No API key is required for read endpoints. Prices are integer cents in USD.",
    "contact": { "name": "Kilnwood", "url": "https://market-share-joy.lovable.app" },
    "license": { "name": "Proprietary" }
  },
  "servers": [{ "url": "https://market-share-joy.lovable.app", "description": "Production" }],
  "tags": [{ "name": "listings" }, { "name": "search" }],
  "paths": {
    "/api/public/v1/listings": {
      "get": {
        "tags": ["listings"],
        "operationId": "listListings",
        "summary": "Search and list marketplace listings",
        "description": "Returns a paginated collection of listings, optionally filtered by free-text query and category.",
        "parameters": [
          { "name": "q", "in": "query", "required": false, "description": "Free-text search over title and description.", "schema": { "type": "string" } },
          { "name": "category", "in": "query", "required": false, "description": "Filter by category.", "schema": { "type": "string", "enum": ["ceramics", "textiles", "woodwork", "jewelry", "vintage", "art", "other"] } },
          { "name": "limit", "in": "query", "required": false, "description": "Maximum items to return (1-100).", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } },
          { "name": "offset", "in": "query", "required": false, "description": "Number of items to skip.", "schema": { "type": "integer", "minimum": 0, "default": 0 } },
          { "name": "sandbox", "in": "query", "required": false, "description": "Return deterministic fixture data instead of live rows.", "schema": { "type": "boolean", "default": false } }
        ],
        "responses": {
          "200": {
            "description": "A page of listings.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data", "pagination"],
                  "properties": {
                    "data": { "type": "array", "items": { "$ref": "#/components/schemas/Listing" } },
                    "pagination": { "$ref": "#/components/schemas/Pagination" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/Error" },
          "500": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/api/public/v1/listings/{id}": {
      "get": {
        "tags": ["listings"],
        "operationId": "getListing",
        "summary": "Get a single listing by id",
        "description": "Returns one listing including its public seller profile.",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "description": "Listing UUID.", "schema": { "type": "string", "format": "uuid" } },
          { "name": "sandbox", "in": "query", "required": false, "description": "Return deterministic fixture data instead of live rows.", "schema": { "type": "boolean", "default": false } }
        ],
        "responses": {
          "200": {
            "description": "The listing.",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Listing" } } } } }
          },
          "404": { "$ref": "#/components/responses/Error" },
          "500": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/api/public/v1/categories": {
      "get": {
        "tags": ["listings"],
        "operationId": "listCategories",
        "summary": "List available listing categories",
        "description": "Returns the fixed set of category codes used by listings.",
        "responses": {
          "200": {
            "description": "Category codes.",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "type": "string" } } } } } }
          }
        }
      }
    },
    "/api/public/ask": {
      "post": {
        "tags": ["search"],
        "operationId": "askNlweb",
        "summary": "Natural-language query over listings (NLWeb)",
        "description": "Accepts a natural-language query and returns matching listings as schema.org Product items. Supports SSE streaming when prefer.streaming is true.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["query"],
                "properties": {
                  "query": { "type": "string", "description": "Natural-language question, e.g. 'blue ceramic mugs under $40'." },
                  "streaming": { "type": "boolean", "description": "Request Server-Sent Events streaming.", "default": false }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "NLWeb result set.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "_meta": { "type": "object", "properties": { "response_type": { "type": "string" }, "version": { "type": "string" } } },
                    "query_id": { "type": "string" },
                    "results": { "type": "array", "items": { "type": "object" } }
                  }
                }
              },
              "text/event-stream": { "schema": { "type": "string" } }
            }
          },
          "400": { "$ref": "#/components/responses/Error" }
        }
      }
    }
  },
  "components": {
    "responses": {
      "Error": {
        "description": "Structured JSON error.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "User-delegated access token, required only for write operations."
      },
      "oauth2": {
        "type": "oauth2",
        "description": "User-delegated OAuth 2.0 access with scoped permissions.",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://market-share-joy.lovable.app/auth",
            "tokenUrl": "https://tpwvdxiatgtdbifbcszf.supabase.co/auth/v1/token",
            "scopes": {
              "listings:read": "Read listings",
              "listings:write": "Create and update the user's own listings",
              "profile:read": "Read the user's public profile"
            }
          }
        }
      }
    },
    "schemas": {
      "Listing": {
        "type": "object",
        "required": ["id", "title", "price_cents", "category"],
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "title": { "type": "string" },
          "description": { "type": "string" },
          "price_cents": { "type": "integer", "description": "Price in USD cents." },
          "currency": { "type": "string", "default": "USD" },
          "category": { "type": "string", "enum": ["ceramics", "textiles", "woodwork", "jewelry", "vintage", "art", "other"] },
          "condition": { "type": "string" },
          "image_url": { "type": "string", "format": "uri", "nullable": true },
          "is_sold": { "type": "boolean", "description": "True when the seller marked the item sold." },
          "created_at": { "type": "string", "format": "date-time" },
          "url": { "type": "string", "format": "uri" }
        }
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "limit": { "type": "integer" },
          "offset": { "type": "integer" },
          "count": { "type": "integer" }
        }
      },
      "Error": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["code", "message"],
            "properties": {
              "code": { "type": "string", "enum": ["bad_request", "unauthorized", "forbidden", "not_found", "rate_limited", "internal_error"] },
              "message": { "type": "string" },
              "hint": { "type": "string" }
            }
          }
        }
      }
    }
  }
}
