{"openapi":"3.1.0","info":{"title":"Fact Lot","version":"1.0.0","description":"Public read-only facts. Null means the source did not state the field. Parameter q on /agent/search.json maps to MCP tool search_facts argument query."},"servers":[{"url":"https://factlot.com"}],"paths":{"/agent/search.json":{"get":{"operationId":"search_facts","summary":"Search published facts","parameters":[{"name":"market","in":"query","schema":{"type":"string","enum":["houston","san-antonio"]}},{"name":"zip","in":"query","schema":{"type":"string"}},{"name":"use","in":"query","schema":{"type":"string","enum":["office","retail","industrial","flex","medical"]}},{"name":"q","in":"query","schema":{"type":"string"},"description":"Same filter as MCP search_facts argument query."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50},"description":"Maximum records to return. Default 20. The response field limit is that value after a non-integer is truncated and the result is clamped to 1–50. A missing or non-finite value uses 20."}],"responses":{"200":{"description":"Matching published records. matched is the count before the slice. limit is the cap that was applied. factLotBuilding is the Fact Lot building URL, or null when the record is not on a published building.","content":{"application/json":{"schema":{"type":"object","required":["asOf","asOfIso","matched","limit","results"],"properties":{"asOf":{"type":"string"},"asOfIso":{"type":"string"},"note":{"type":"string"},"matched":{"type":"integer","minimum":0,"description":"Published records that matched before limit was applied."},"limit":{"type":"integer","minimum":1,"maximum":50,"description":"The limit that was applied."},"results":{"type":"array","items":{"type":"object"}}}}}}}}}},"/agent/stats.json":{"get":{"operationId":"market_stats","parameters":[{"name":"market","in":"query","required":false,"schema":{"type":"string","enum":["houston","san-antonio"]},"description":"Limit the response to one market. Omit it for both markets."}],"responses":{"200":{"description":"Medians and counts. censusEstablishmentsSource carries the zbp23totals citation and URL once. Each byZip object includes censusEstablishments2023 as an integer or null. The count is not part of n, the median, or statedFacts.","content":{"application/json":{"schema":{"type":"object","properties":{"censusEstablishmentsSource":{"type":"object","properties":{"citation":{"type":"string"},"url":{"type":"string"}},"required":["citation","url"]},"markets":{"type":"array","items":{"type":"object","properties":{"byZip":{"type":"array","items":{"$ref":"#/components/schemas/ZipMarketStats"}}}}}}}}}}}}},"/agent/citations.json":{"get":{"operationId":"citation_urls","responses":{"200":{"description":"Citation URLs."}}}},"/agent/tools.json":{"get":{"operationId":"tool_catalog","responses":{"200":{"description":"Tool catalog."}}}},"/agent/scoreboard.json":{"get":{"operationId":"scoreboard","responses":{"200":{"description":"Inventory."}}}}},"components":{"schemas":{"ZipMarketStats":{"type":"object","properties":{"zip":{"type":"string"},"median":{"type":["number","null"]},"n":{"type":"integer","minimum":0},"indexable":{"type":"boolean"},"statedFacts":{"type":"integer","minimum":0},"censusEstablishments2023":{"type":["integer","null"],"description":"U.S. Census Bureau, \"zbp23totals\", 2023 County Business Patterns: ZIP Code Business Patterns, 2023, <https://www2.census.gov/programs-surveys/cbp/datasets/2023/>, accessed on October 5, 2026. Employer establishments in reference year 2023, counted at the USPS ZIP of the business mailing address. Not a ZCTA count, not a count of commercial buildings or listings, and excludes most government establishments and the self-employed. Null means the ZIP has no row. Not used in rent medians, n, or the index threshold."}},"required":["zip","median","n","indexable","statedFacts","censusEstablishments2023"]}}}}