{
  "openapi": "3.1.0",
  "info": {
    "title": "SEEK Public API",
    "description": "Public, read-only access to SEEK approved office spaces and operators. No authentication required. Designed to be consumed by LLM agents (ChatGPT Custom GPTs, Claude tools, Gemini, etc.).",
    "version": "1.0.0",
    "contact": {
      "name": "SEEK",
      "url": "https://seek-re.com"
    }
  },
  "servers": [
    { "url": "https://seek-re.com", "description": "Production" }
  ],
  "security": [],
  "paths": {
    "/v1/space": {
      "get": {
        "operationId": "searchSpaces",
        "summary": "Search approved office spaces by coordinates.",
        "description": "Returns approved office spaces sorted by distance (km) from numeric `lat`/`lon`. This endpoint ONLY accepts coordinates — never place names, addresses, or postcodes. Resolve the user's location to `lat` and `lon` before calling.",
        "parameters": [
          { "name": "lat", "in": "query", "description": "Latitude in decimal degrees. MUST be a number (e.g. 51.5074). Pair with `lon` for proximity sorting.", "schema": { "type": "number" }, "example": 51.5074 },
          { "name": "lon", "in": "query", "description": "Longitude in decimal degrees. MUST be a number (e.g. -0.1278). Pair with `lat` for proximity sorting.", "schema": { "type": "number" }, "example": -0.1278 },
          { "name": "name", "in": "query", "description": "Substring match on office/building name (NOT a location). Use only when the user names a specific building.", "schema": { "type": "string" } },
          { "name": "operator", "in": "query", "description": "Substring match on operator/brand name (e.g. \"fora\", \"wework\").", "schema": { "type": "string" } },
          { "name": "amenities", "in": "query", "description": "Comma-separated amenity keywords (e.g. \"wifi,gym,showers\").", "schema": { "type": "string" } },
          { "name": "desk_count", "in": "query", "description": "Digit substring matched against any value in the office's desk_count array.", "schema": { "type": "string" } },
          { "name": "space_count", "in": "query", "description": "Minimum number of suites.", "schema": { "type": "integer", "minimum": 0 } },
          { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1, "minimum": 1 } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 10, "minimum": 1, "maximum": 50 } }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of approved spaces, sorted by distance ascending when lat+lon supplied, otherwise alphabetically by name.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    { "$ref": "#/components/schemas/Pagination" },
                    {
                      "type": "object",
                      "properties": {
                        "data": { "type": "array", "items": { "$ref": "#/components/schemas/Space" } }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v1/operator": {
      "get": {
        "operationId": "searchOperators",
        "summary": "Search operators by name.",
        "parameters": [
          { "name": "name", "in": "query", "description": "Substring match on operator name (case-insensitive).", "schema": { "type": "string" } },
          { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1, "minimum": 1 } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 100, "minimum": 1, "maximum": 500 } }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of operators.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    { "$ref": "#/components/schemas/Pagination" },
                    {
                      "type": "object",
                      "properties": {
                        "data": { "type": "array", "items": { "$ref": "#/components/schemas/Operator" } }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Pagination": {
        "type": "object",
        "properties": {
          "page": { "type": "integer" },
          "limit": { "type": "integer" },
          "total": { "type": "integer" },
          "total_pages": { "type": "integer" }
        }
      },
      "Space": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "address": { "type": "string" },
          "latitude": { "type": "number" },
          "longitude": { "type": "number" },
          "operator": { "type": "string" },
          "amenities": { "type": "array", "items": { "type": "string" } },
          "desk_count": { "type": "array", "items": { "type": "integer" } },
          "suit_count": { "type": "string" },
          "suit_types": { "type": "array", "items": { "type": "string" } },
          "image_url": { "type": "string", "format": "uri" },
          "isapproved": { "type": "boolean" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "Operator": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "logo": { "type": "string", "format": "uri" },
          "mappin": { "type": "string", "format": "uri" },
          "website": { "type": "string", "format": "uri" },
          "office_count": { "type": "integer" },
          "ispayingcustomer": { "type": "boolean" },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      }
    }
  }
}
