{
  "openapi": "3.1.0",
  "info": {
    "title": "RedeCasas Search API",
    "version": "1.0.0",
    "description": "Public, unauthenticated search endpoints over the RedeCasas real-estate directory (5,500+ Brazilian city pages, states, topic guides, news, calculators). All endpoints are CORS-enabled (Access-Control-Allow-Origin: *) and return application/json. Served by the chat worker on the apex domain; the same paths also resolve on https://chat.redecasas.com.br.",
    "contact": {
      "name": "RedeCasas",
      "url": "https://redecasas.com.br/contato/"
    }
  },
  "servers": [
    {
      "url": "https://redecasas.com.br",
      "description": "Apex domain (primary)"
    },
    {
      "url": "https://chat.redecasas.com.br",
      "description": "Chat worker origin"
    }
  ],
  "paths": {
    "/api/search": {
      "get": {
        "summary": "Search site content",
        "description": "Keyword search across city pages, state pages, topic guides, news articles, calculators and static pages. Empty or missing q returns an empty result set (not an error).",
        "operationId": "searchSite",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Search query. Terms shorter than 2 characters are ignored.",
            "schema": { "type": "string" },
            "example": "financiamento imobiliário"
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "description": "Restrict results to one content category. Use /api/search/categories for the live list.",
            "schema": {
              "type": "string",
              "default": "all",
              "examples": ["all", "cities", "states", "scopes", "noticias", "calculators", "pages"]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of results. Values above 50 are capped at 50.",
            "schema": { "type": "integer", "minimum": 1, "maximum": 50, "default": 10 }
          }
        ],
        "responses": {
          "200": {
            "description": "Search result set.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "query": { "type": "string" },
                    "total": { "type": "integer" },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "title": { "type": "string" },
                          "url": { "type": "string", "format": "uri-reference" },
                          "snippet": { "type": "string" },
                          "category": { "type": "string" }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/bucket-search": {
      "get": {
        "summary": "Search the static asset bucket",
        "description": "Lists objects in the Cloudflare R2 asset bucket by key prefix, optionally filtered by file type.",
        "operationId": "searchBucket",
        "parameters": [
          {
            "name": "prefix",
            "in": "query",
            "required": false,
            "description": "Object key prefix (e.g. static/images/).",
            "schema": { "type": "string", "default": "" }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Filter by object type.",
            "schema": {
              "type": "string",
              "enum": ["all", "image", "document"],
              "default": "all"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of objects. Values above 200 are capped at 200.",
            "schema": { "type": "integer", "minimum": 1, "maximum": 200, "default": 50 }
          }
        ],
        "responses": {
          "200": {
            "description": "Bucket listing.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "objects": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "key": { "type": "string" },
                          "size": { "type": "integer" },
                          "lastModified": { "type": "string", "format": "date-time" },
                          "url": { "type": "string", "format": "uri" }
                        }
                      }
                    },
                    "prefix": { "type": "string" },
                    "total": { "type": "integer" },
                    "truncated": { "type": "boolean" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/page-content": {
      "get": {
        "summary": "Extract structured page content",
        "description": "Extracts title, description, canonical URL, headings, main text (first ~2000 characters) and internal links from any site page. Site-relative URLs are resolved against the site origin.",
        "operationId": "getPageContent",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "description": "Absolute URL or site-relative path of the page to extract.",
            "schema": { "type": "string" },
            "example": "/energia-solar/"
          }
        ],
        "responses": {
          "200": {
            "description": "Extracted page data.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "title": { "type": "string" },
                    "description": { "type": "string" },
                    "canonical": { "type": "string" },
                    "headings": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "level": { "type": "integer" },
                          "text": { "type": "string" }
                        }
                      }
                    },
                    "content": { "type": "string" },
                    "links": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "text": { "type": "string" },
                          "href": { "type": "string" }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing url parameter."
          }
        }
      }
    },
    "/api/search/categories": {
      "get": {
        "summary": "List search categories",
        "description": "Returns the content categories currently present in the search index, with per-category counts.",
        "operationId": "listSearchCategories",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Category list.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "categories": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": { "type": "string" },
                          "count": { "type": "integer" }
                        }
                      }
                    },
                    "total": { "type": "integer" }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
