{
  "openapi": "3.0.3",
  "info": {
    "title": "Cobroker Agent API",
    "description": "REST API providing commercial real estate tools for AI agents. Create projects, manage properties, enrich with demographics, search places, and run AI research — all via HTTP.\n",
    "version": "1.0.0",
    "contact": {
      "name": "Cobroker",
      "url": "https://cobroker.ai",
      "email": "isaac@cobroker.ai"
    }
  },
  "servers": [
    {
      "url": "https://app.cobroker.ai/api/agent/openclaw",
      "description": "Production"
    }
  ],
  "security": [
    {
      "agentAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "agentAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Agent-Secret",
        "description": "Agent secret key. Also requires X-Agent-User-Id header."
      }
    },
    "schemas": {
      "Property": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string",
            "description": "Full address with at least 3 comma-separated parts (street, city, state+zip)",
            "example": "123 Main St, Dallas, TX 75201"
          },
          "latitude": {
            "type": "number",
            "example": 32.78
          },
          "longitude": {
            "type": "number",
            "example": -96.8
          },
          "fields": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "example": {
              "Price": "$500,000",
              "Size": "10,000 SF",
              "Type": "Warehouse"
            }
          }
        }
      },
      "ProjectSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "public": {
            "type": "boolean"
          },
          "propertyCount": {
            "type": "integer"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "projectUrl": {
            "type": "string"
          },
          "publicUrl": {
            "type": "string"
          }
        }
      },
      "ProjectDetails": {
        "type": "object",
        "properties": {
          "project": {
            "$ref": "#/components/schemas/ProjectSummary"
          },
          "columns": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                }
              }
            }
          },
          "properties": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "address": {
                  "type": "string"
                },
                "latitude": {
                  "type": "number"
                },
                "longitude": {
                  "type": "number"
                },
                "fields": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "propertyCount": {
            "type": "integer"
          }
        }
      }
    }
  },
  "paths": {
    "/projects": {
      "get": {
        "summary": "List all projects",
        "operationId": "listProjects",
        "responses": {
          "200": {
            "description": "List of projects",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "projects": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ProjectSummary"
                      }
                    },
                    "count": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create a project with properties",
        "operationId": "createProject",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "example": "Dallas Warehouses"
                  },
                  "description": {
                    "type": "string",
                    "example": "Q1 industrial survey"
                  },
                  "source": {
                    "type": "string",
                    "example": "openclaw"
                  },
                  "public": {
                    "type": "boolean",
                    "default": true
                  },
                  "properties": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/Property"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Project created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "projectId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "projectUrl": {
                      "type": "string"
                    },
                    "publicUrl": {
                      "type": "string"
                    },
                    "propertyCount": {
                      "type": "integer"
                    },
                    "columnCount": {
                      "type": "integer"
                    },
                    "geocodedCount": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{projectId}": {
      "parameters": [
        {
          "name": "projectId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "summary": "Get project details",
        "operationId": "getProject",
        "responses": {
          "200": {
            "description": "Project details with properties",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectDetails"
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Update project",
        "operationId": "updateProject",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "public": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Project updated"
          }
        }
      },
      "delete": {
        "summary": "Delete project and all associated data",
        "operationId": "deleteProject",
        "responses": {
          "200": {
            "description": "Project deleted"
          }
        }
      }
    },
    "/projects/{projectId}/properties": {
      "parameters": [
        {
          "name": "projectId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "post": {
        "summary": "Add properties to project",
        "operationId": "addProperties",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "properties"
                ],
                "properties": {
                  "properties": {
                    "type": "array",
                    "maxItems": 50,
                    "items": {
                      "$ref": "#/components/schemas/Property"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Properties added"
          }
        }
      },
      "patch": {
        "summary": "Update properties",
        "operationId": "updateProperties",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "updates"
                ],
                "properties": {
                  "updates": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "id"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "address": {
                          "type": "string"
                        },
                        "fields": {
                          "type": "object",
                          "additionalProperties": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Properties updated"
          }
        }
      },
      "delete": {
        "summary": "Delete properties",
        "operationId": "deleteProperties",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "propertyIds"
                ],
                "properties": {
                  "propertyIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Properties deleted"
          }
        }
      }
    },
    "/projects/{projectId}/demographics": {
      "parameters": [
        {
          "name": "projectId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "summary": "List all 58 available demographic types",
        "operationId": "listDemographicTypes",
        "responses": {
          "200": {
            "description": "Demographic types grouped by category"
          }
        }
      },
      "post": {
        "summary": "Add ESRI demographic data to properties",
        "operationId": "addDemographics",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "dataType",
                  "radius"
                ],
                "properties": {
                  "dataType": {
                    "type": "string",
                    "description": "ESRI GeoEnrichment data type. 15+ categories: Core Demographics, Income, Employment, Housing, Age, Race/Ethnicity, Tapestry Psychographics, Consumer Spending, Market Potential Index, Business Data, Crime Indexes, Retail Marketplace, Commute, Education, Health Insurance.",
                    "enum": [
                      "population",
                      "median_age",
                      "households",
                      "population_density",
                      "household_size",
                      "daytime_population",
                      "income",
                      "per_capita_income",
                      "avg_household_income",
                      "disposable_income",
                      "income_under_25k",
                      "income_25k_50k",
                      "income_50k_75k",
                      "income_75k_100k",
                      "income_100k_150k",
                      "income_150k_250k",
                      "income_250k_plus",
                      "total_employment",
                      "retail_jobs",
                      "healthcare_jobs",
                      "office_jobs",
                      "food_service_jobs",
                      "manufacturing_jobs",
                      "construction_jobs",
                      "education_jobs",
                      "unemployment_rate",
                      "median_home_value",
                      "median_rent",
                      "owner_occupied",
                      "renter_occupied",
                      "vacant_housing",
                      "housing_after_2010",
                      "avg_home_value",
                      "median_year_built",
                      "age_0_4",
                      "age_5_17",
                      "age_18_24",
                      "age_25_34",
                      "age_35_44",
                      "age_45_54",
                      "age_55_64",
                      "age_65_74",
                      "age_75_plus",
                      "working_age",
                      "white_population",
                      "black_population",
                      "hispanic_population",
                      "asian_population",
                      "two_or_more_races",
                      "diversity_index",
                      "tapestry_segment",
                      "tapestry_top3",
                      "lifemode_group",
                      "restaurant_spending",
                      "retail_spending",
                      "entertainment_spending",
                      "grocery_spending",
                      "spending_potential_index",
                      "dining_propensity",
                      "shopping_propensity",
                      "fitness_propensity",
                      "business_count",
                      "employee_count",
                      "retail_trade_businesses",
                      "food_service_businesses",
                      "total_crime_index",
                      "property_crime_index",
                      "personal_crime_index",
                      "retail_demand",
                      "retail_supply_gap",
                      "food_service_demand",
                      "avg_commute_time",
                      "work_from_home_pct",
                      "public_transit_pct",
                      "bachelors_degree_pct",
                      "graduate_degree_pct",
                      "uninsured_rate"
                    ],
                    "example": "population"
                  },
                  "radius": {
                    "type": "number",
                    "minimum": 0.1,
                    "maximum": 100,
                    "description": "Miles for radius mode, minutes for drive/walk",
                    "example": 1
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "radius",
                      "drive",
                      "walk"
                    ],
                    "default": "radius"
                  },
                  "columnName": {
                    "type": "string",
                    "description": "Auto-generated if omitted"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Demographics added"
          }
        }
      }
    },
    "/projects/{projectId}/enrichment": {
      "parameters": [
        {
          "name": "projectId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "summary": "Check enrichment status",
        "operationId": "getEnrichmentStatus",
        "parameters": [
          {
            "name": "columnId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Enrichment status"
          }
        }
      },
      "post": {
        "summary": "Submit AI research enrichment (async)",
        "operationId": "submitEnrichment",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "prompt"
                ],
                "properties": {
                  "prompt": {
                    "type": "string",
                    "description": "Question to research for each property",
                    "example": "What is the zoning classification for this property?"
                  },
                  "columnName": {
                    "type": "string",
                    "description": "Auto-generated from prompt if omitted"
                  },
                  "processor": {
                    "type": "string",
                    "enum": [
                      "base",
                      "core",
                      "pro",
                      "ultra"
                    ],
                    "default": "core",
                    "description": "base ~15-100s, core ~1-5min, pro ~3-9min, ultra ~5-25min"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Enrichment submitted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "projectId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "columnId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "columnName": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "processing"
                      ]
                    },
                    "propertiesSubmitted": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{projectId}/traffic": {
      "parameters": [
        {
          "name": "projectId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "post": {
        "summary": "Get foot traffic and visitor analytics for properties",
        "operationId": "getTrafficData",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "dataType"
                ],
                "properties": {
                  "dataType": {
                    "type": "string",
                    "description": "Traffic data type: visits, visit_trends, visits_by_hour, visits_by_day, dwell_time, visit_frequency, trade_area, drive_time_trade_area, rankings, competitive_benchmark, nearby_activity, transaction_volume, avg_ticket_size, sales_trends, daily_sales, visitor_origins, cross_shopping, favorite_chains",
                    "enum": [
                      "visits",
                      "visit_trends",
                      "visits_by_hour",
                      "visits_by_day",
                      "dwell_time",
                      "visit_frequency",
                      "trade_area",
                      "drive_time_trade_area",
                      "rankings",
                      "competitive_benchmark",
                      "nearby_activity",
                      "transaction_volume",
                      "avg_ticket_size",
                      "sales_trends",
                      "daily_sales",
                      "visitor_origins",
                      "cross_shopping",
                      "favorite_chains"
                    ],
                    "example": "visits"
                  },
                  "period": {
                    "type": "string",
                    "description": "Time period for data",
                    "enum": [
                      "last_month",
                      "last_3_months",
                      "last_6_months",
                      "last_12_months"
                    ],
                    "default": "last_12_months"
                  },
                  "granularity": {
                    "type": "string",
                    "enum": [
                      "daily",
                      "weekly",
                      "monthly"
                    ],
                    "default": "monthly"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Traffic data added to properties"
          }
        }
      }
    },
    "/projects/{projectId}/places/search": {
      "parameters": [
        {
          "name": "projectId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "description": "Project ID or 'new' to auto-create"
          }
        }
      ],
      "post": {
        "summary": "Search Google Places and save results",
        "operationId": "searchPlaces",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "query"
                ],
                "properties": {
                  "query": {
                    "type": "string",
                    "example": "Starbucks in Dallas"
                  },
                  "preview": {
                    "type": "boolean",
                    "default": false,
                    "description": "If true, returns places without saving"
                  },
                  "maxResults": {
                    "type": "integer",
                    "default": 50,
                    "maximum": 400
                  },
                  "regionSearch": {
                    "type": "boolean",
                    "default": false,
                    "description": "Search across 7 US regions for nationwide coverage"
                  },
                  "projectName": {
                    "type": "string",
                    "description": "Name for auto-created project (only when projectId is 'new')"
                  },
                  "destination": {
                    "type": "string",
                    "enum": [
                      "properties",
                      "layer"
                    ],
                    "default": "properties"
                  },
                  "layerName": {
                    "type": "string",
                    "description": "Required when destination is 'layer'"
                  },
                  "markerColor": {
                    "type": "string",
                    "default": "#4285F4"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Preview results (when preview=true)"
          },
          "201": {
            "description": "Places saved to project"
          }
        }
      }
    },
    "/projects/{projectId}/places/nearby": {
      "parameters": [
        {
          "name": "projectId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "post": {
        "summary": "Analyze nearby places for each property",
        "operationId": "nearbyAnalysis",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "mode",
                  "radiusMiles"
                ],
                "properties": {
                  "mode": {
                    "type": "string",
                    "enum": [
                      "nearest",
                      "count"
                    ]
                  },
                  "query": {
                    "type": "string",
                    "description": "Required for 'nearest' mode",
                    "example": "grocery store"
                  },
                  "placeTypes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Required for 'count' mode",
                    "example": [
                      "restaurant",
                      "cafe"
                    ]
                  },
                  "radiusMiles": {
                    "type": "number",
                    "minimum": 0.1,
                    "maximum": 50,
                    "example": 2
                  },
                  "columnName": {
                    "type": "string",
                    "description": "Auto-generated if omitted"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Analysis complete",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "columnName": {
                      "type": "string"
                    },
                    "propertiesProcessed": {
                      "type": "integer"
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "propertyId": {
                            "type": "string"
                          },
                          "address": {
                            "type": "string"
                          },
                          "nearestPlace": {
                            "type": "string"
                          },
                          "distanceMiles": {
                            "type": "number"
                          },
                          "totalFound": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}