{
  "openapi": "3.0.3",
  "info": {
    "title": "MarketTimeline Data API",
    "version": "1.0.0",
    "description": "Real-estate valuations (AVM), price & tax history, market trends, appreciation, flips, distressed sales, tax-appeal signals, and agent/brokerage stats. Derived from public records and MarketTimeline's own analytics; no live MLS listings.",
    "contact": { "name": "MarketTimeline API", "email": "api@markettimeline.com", "url": "https://api.markettimeline.com" }
  },
  "servers": [ { "url": "https://api.markettimeline.com" } ],
  "security": [ { "bearerAuth": [] } ],
  "components": {
    "securitySchemes": {
      "bearerAuth": { "type": "http", "scheme": "bearer", "description": "Your API key, e.g. mt_live_..." },
      "apiKeyHeader": { "type": "apiKey", "in": "header", "name": "X-API-Key" }
    },
    "parameters": {
      "geoType": { "name": "geo_type", "in": "path", "required": true, "schema": { "type": "string", "enum": ["state","county","city","neighborhood","zip"] } },
      "geoId": { "name": "geo_id", "in": "path", "required": true, "schema": { "type": "integer" } },
      "page": { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } },
      "limit": { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 25 } }
    },
    "schemas": {
      "Envelope": {
        "type": "object",
        "properties": {
          "status": { "type": "string", "example": "ok" },
          "data": {},
          "meta": { "type": "object" }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "status": { "type": "string", "example": "error" },
          "error": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" } } }
        }
      }
    },
    "responses": {
      "Ok": { "description": "Success", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Envelope" } } } },
      "Err": { "description": "Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
    }
  },
  "paths": {
    "/health": { "get": { "summary": "Health check (no auth)", "security": [], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },

    "/v1/geo/states": { "get": { "tags": ["Geo"], "summary": "List states", "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },
    "/v1/geo/counties": { "get": { "tags": ["Geo"], "summary": "List counties", "parameters": [ { "name": "state_id", "in": "query", "schema": { "type": "integer" } }, { "$ref": "#/components/parameters/page" }, { "$ref": "#/components/parameters/limit" } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },
    "/v1/geo/cities": { "get": { "tags": ["Geo"], "summary": "List cities", "parameters": [ { "name": "state_id", "in": "query", "schema": { "type": "integer" } }, { "name": "county_id", "in": "query", "schema": { "type": "integer" } }, { "name": "q", "in": "query", "schema": { "type": "string" } } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },
    "/v1/geo/zips": { "get": { "tags": ["Geo"], "summary": "List zips", "parameters": [ { "name": "city_id", "in": "query", "schema": { "type": "integer" } }, { "name": "state_id", "in": "query", "schema": { "type": "integer" } }, { "name": "q", "in": "query", "schema": { "type": "string" } } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },
    "/v1/geo/search": { "get": { "tags": ["Geo"], "summary": "Autocomplete cities/zips/counties", "parameters": [ { "name": "q", "in": "query", "required": true, "schema": { "type": "string" } }, { "name": "type", "in": "query", "schema": { "type": "string", "enum": ["city","zip","county"] } } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },

    "/v1/property/{id}": { "get": { "tags": ["Property"], "summary": "Get a property", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "$ref": "#/components/responses/Ok" }, "404": { "$ref": "#/components/responses/Err" } } } },
    "/v1/property/search": { "get": { "tags": ["Property"], "summary": "Search properties (requires city_id or zip_id)", "parameters": [ { "name": "city_id", "in": "query", "schema": { "type": "integer" } }, { "name": "zip_id", "in": "query", "schema": { "type": "integer" } }, { "name": "beds_min", "in": "query", "schema": { "type": "integer" } }, { "name": "baths_min", "in": "query", "schema": { "type": "integer" } }, { "name": "sqft_min", "in": "query", "schema": { "type": "integer" } }, { "name": "sqft_max", "in": "query", "schema": { "type": "integer" } }, { "name": "year_min", "in": "query", "schema": { "type": "integer" } }, { "name": "property_type", "in": "query", "schema": { "type": "string" } } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },
    "/v1/property/{id}/history": { "get": { "tags": ["Property"], "summary": "Sale & listing history", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },
    "/v1/property/{id}/tax-history": { "get": { "tags": ["Property"], "summary": "Tax assessment history", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },

    "/v1/avm/{property_id}": { "get": { "tags": ["Valuation"], "summary": "Estimated value (AVM)", "parameters": [ { "name": "property_id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "$ref": "#/components/responses/Ok" }, "403": { "$ref": "#/components/responses/Err" } } } },
    "/v1/avm/bulk": { "post": { "tags": ["Valuation"], "summary": "Bulk AVM", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "property_ids": { "type": "array", "items": { "type": "integer" } } } } } } }, "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },
    "/v1/avm/comps": { "get": { "tags": ["Valuation"], "summary": "Comparable sales", "parameters": [ { "name": "property_id", "in": "query", "schema": { "type": "integer" } }, { "name": "zip_id", "in": "query", "schema": { "type": "integer" } }, { "name": "sqft", "in": "query", "schema": { "type": "integer" } } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },

    "/v1/market/{geo_type}/{geo_id}/stats": { "get": { "tags": ["Market"], "summary": "Price/volume time series", "parameters": [ { "$ref": "#/components/parameters/geoType" }, { "$ref": "#/components/parameters/geoId" }, { "name": "granularity", "in": "query", "schema": { "type": "string", "enum": ["year","month"] } } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },
    "/v1/market/{geo_type}/{geo_id}/appreciation": { "get": { "tags": ["Market"], "summary": "1/3/5/10yr appreciation", "parameters": [ { "$ref": "#/components/parameters/geoType" }, { "$ref": "#/components/parameters/geoId" } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },
    "/v1/market/{geo_type}/{geo_id}/dom": { "get": { "tags": ["Market"], "summary": "Days on market (state only)", "parameters": [ { "$ref": "#/components/parameters/geoType" }, { "$ref": "#/components/parameters/geoId" } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },
    "/v1/market/{geo_type}/{geo_id}/inventory": { "get": { "tags": ["Market"], "summary": "Inventory (zip only)", "parameters": [ { "$ref": "#/components/parameters/geoType" }, { "$ref": "#/components/parameters/geoId" } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },
    "/v1/market/{geo_type}/{geo_id}/rental": { "get": { "tags": ["Market"], "summary": "Rental medians", "parameters": [ { "$ref": "#/components/parameters/geoType" }, { "$ref": "#/components/parameters/geoId" } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },
    "/v1/market/{geo_type}/{geo_id}/best-month": { "get": { "tags": ["Market"], "summary": "Seasonality (state only)", "parameters": [ { "$ref": "#/components/parameters/geoType" }, { "$ref": "#/components/parameters/geoId" } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },
    "/v1/market/{geo_type}/{geo_id}/flood": { "get": { "tags": ["Market"], "summary": "Flood-risk summary", "parameters": [ { "$ref": "#/components/parameters/geoType" }, { "$ref": "#/components/parameters/geoId" } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },
    "/v1/market/{geo_type}/{geo_id}/permits": { "get": { "tags": ["Market"], "summary": "Building permits by year", "parameters": [ { "$ref": "#/components/parameters/geoType" }, { "$ref": "#/components/parameters/geoId" } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },

    "/v1/flips": { "get": { "tags": ["Investor"], "summary": "Flip transactions", "parameters": [ { "name": "state_id", "in": "query", "schema": { "type": "integer" } }, { "name": "city_id", "in": "query", "schema": { "type": "integer" } }, { "name": "zip_id", "in": "query", "schema": { "type": "integer" } }, { "name": "min_gain_pct", "in": "query", "schema": { "type": "integer" } } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },
    "/v1/flips/stats/{geo_type}/{geo_id}": { "get": { "tags": ["Investor"], "summary": "Flip stats by area", "parameters": [ { "$ref": "#/components/parameters/geoType" }, { "$ref": "#/components/parameters/geoId" } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },
    "/v1/distressed": { "get": { "tags": ["Investor"], "summary": "Distressed / below-assessment sales", "parameters": [ { "name": "state_id", "in": "query", "schema": { "type": "integer" } }, { "name": "city_id", "in": "query", "schema": { "type": "integer" } }, { "name": "zip_id", "in": "query", "schema": { "type": "integer" } }, { "name": "min_discount_pct", "in": "query", "schema": { "type": "integer" } } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },

    "/v1/tax/{property_id}/appeal": { "get": { "tags": ["Tax"], "summary": "Over-assessment check", "parameters": [ { "name": "property_id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },
    "/v1/tax/appeal-candidates": { "get": { "tags": ["Tax"], "summary": "Over-assessed candidates by area", "parameters": [ { "name": "state_id", "in": "query", "schema": { "type": "integer" } }, { "name": "city_id", "in": "query", "schema": { "type": "integer" } }, { "name": "zip_id", "in": "query", "schema": { "type": "integer" } }, { "name": "min_overassessment_pct", "in": "query", "schema": { "type": "integer" } } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },
    "/v1/tax/burden/{geo_type}/{geo_id}": { "get": { "tags": ["Tax"], "summary": "Effective tax rate", "parameters": [ { "$ref": "#/components/parameters/geoType" }, { "$ref": "#/components/parameters/geoId" } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },

    "/v1/agents": { "get": { "tags": ["Agents"], "summary": "Agent leaderboard", "parameters": [ { "name": "state_id", "in": "query", "required": true, "schema": { "type": "integer" } }, { "name": "city_id", "in": "query", "schema": { "type": "integer" } }, { "name": "year", "in": "query", "schema": { "type": "integer" } } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },
    "/v1/agent/{id}/stats": { "get": { "tags": ["Agents"], "summary": "Agent production history", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },
    "/v1/brokerages": { "get": { "tags": ["Agents"], "summary": "Brokerage leaderboard", "parameters": [ { "name": "state_id", "in": "query", "required": true, "schema": { "type": "integer" } }, { "name": "city_id", "in": "query", "schema": { "type": "integer" } }, { "name": "year", "in": "query", "schema": { "type": "integer" } } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } },
    "/v1/brokerage/{id}/stats": { "get": { "tags": ["Agents"], "summary": "Brokerage production history", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "$ref": "#/components/responses/Ok" } } } }
  }
}
