{
  "openapi": "3.0.3",
  "info": {
    "title": "ListingsAPI — Canadian Vehicle Listings",
    "version": "1.0.0",
    "description": "Live Canadian franchise-dealer vehicle listings, VIN lookup, dealer inventory, and market statistics. Factual data only (specs, price, mileage, dealer, location) — no photos, no copyrighted marketing text. Canada-first: not a bolt-on to a US dataset.\n\n**Agent-native:** the same data is available as a hosted MCP server at `https://mcp.omniaauto.ca/mcp` (Authorization: Bearer <API key>) — connect it straight into Claude, ChatGPT, or any MCP client.",
    "contact": { "name": "OmniaAuto", "url": "https://omniaauto.ca", "email": "hello@omniaauto.ca" }
  },
  "servers": [{ "url": "https://api.omniaauto.ca", "description": "production" }],
  "security": [{ "bearerAuth": [] }],
  "paths": {
    "/v1/health": {
      "get": {
        "summary": "Service health + top-line coverage",
        "security": [],
        "responses": { "200": { "description": "OK" } }
      }
    },
    "/v1/listings": {
      "get": {
        "summary": "Search listings",
        "parameters": [
          { "name": "make", "in": "query", "schema": { "type": "string" } },
          { "name": "model", "in": "query", "schema": { "type": "string" } },
          { "name": "trim", "in": "query", "schema": { "type": "string" } },
          { "name": "year", "in": "query", "schema": { "type": "integer" } },
          { "name": "year_min", "in": "query", "schema": { "type": "integer" } },
          { "name": "year_max", "in": "query", "schema": { "type": "integer" } },
          { "name": "condition", "in": "query", "schema": { "type": "string", "enum": ["New", "Used", "Certified", "Demo"] } },
          { "name": "body_type", "in": "query", "schema": { "type": "string" } },
          { "name": "drivetrain", "in": "query", "schema": { "type": "string" } },
          { "name": "fuel_type", "in": "query", "schema": { "type": "string" } },
          { "name": "province", "in": "query", "schema": { "type": "string" } },
          { "name": "city", "in": "query", "schema": { "type": "string" } },
          { "name": "dealer", "in": "query", "schema": { "type": "string" }, "description": "dealer website domain" },
          { "name": "oem", "in": "query", "schema": { "type": "string" } },
          { "name": "price_min", "in": "query", "schema": { "type": "number" } },
          { "name": "price_max", "in": "query", "schema": { "type": "number" } },
          { "name": "mileage_min", "in": "query", "schema": { "type": "number" } },
          { "name": "mileage_max", "in": "query", "schema": { "type": "number" } },
          { "name": "sort", "in": "query", "schema": { "type": "string", "enum": ["price", "mileage", "year", "last_seen", "first_seen"] } },
          { "name": "order", "in": "query", "schema": { "type": "string", "enum": ["asc", "desc"] } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 20, "maximum": 100 } },
          { "name": "offset", "in": "query", "schema": { "type": "integer", "default": 0 } },
          { "name": "expand", "in": "query", "schema": { "type": "string" }, "description": "Comma-separated inline enrichments: decode, valuation. Each is billed per result row (valuation capped to first 25 rows). e.g. expand=decode,valuation" }
        ],
        "responses": { "200": { "description": "Matching listings + total count" }, "401": { "description": "Missing/invalid key" }, "429": { "description": "Rate limited" } }
      }
    },
    "/v1/vin/{vin}": {
      "get": {
        "summary": "VIN lookup (with optional inline decode/valuation)",
        "parameters": [
          { "name": "vin", "in": "path", "required": true, "schema": { "type": "string" } },
          { "name": "expand", "in": "query", "schema": { "type": "string" }, "description": "Comma-separated inline enrichments: decode, valuation. Each billed separately. e.g. expand=decode,valuation" }
        ],
        "responses": { "200": { "description": "Latest active listing for the VIN" }, "404": { "description": "Not found" } }
      }
    },
    "/v1/dealers": {
      "get": {
        "summary": "Dealer directory",
        "parameters": [
          { "name": "province", "in": "query", "schema": { "type": "string" } },
          { "name": "city", "in": "query", "schema": { "type": "string" } },
          { "name": "oem", "in": "query", "schema": { "type": "string" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 100, "maximum": 1000 } }
        ],
        "responses": { "200": { "description": "Franchise dealers + live inventory counts" } }
      }
    },
    "/v1/dealers/{domain}/inventory": {
      "get": {
        "summary": "One dealer's active inventory",
        "parameters": [{ "name": "domain", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Active listings for the dealer" } }
      }
    },
    "/v1/market": {
      "get": {
        "summary": "Market statistics for a slice",
        "parameters": [
          { "name": "make", "in": "query", "schema": { "type": "string" } },
          { "name": "model", "in": "query", "schema": { "type": "string" } },
          { "name": "province", "in": "query", "schema": { "type": "string" } },
          { "name": "year_min", "in": "query", "schema": { "type": "integer" } },
          { "name": "year_max", "in": "query", "schema": { "type": "integer" } }
        ],
        "responses": { "200": { "description": "Counts, avg/median price, avg mileage, condition + province breakdowns" } }
      }
    },
    "/v1/decode/{vin}": {
      "get": {
        "summary": "Full-spec vPIC VIN decode (any VIN, not just ones in inventory)",
        "parameters": [{ "name": "vin", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Decoded specs: year, make, model, trim, body, drivetrain, engine, fuel, doors, seats" }, "400": { "description": "Invalid VIN" }, "404": { "description": "Undecodable" } }
      }
    },
    "/v1/valuation": {
      "get": {
        "summary": "Market valuation (low/avg/median/high) from 30-day Canadian comps",
        "parameters": [
          { "name": "year", "in": "query", "required": true, "schema": { "type": "integer" } },
          { "name": "make", "in": "query", "required": true, "schema": { "type": "string" } },
          { "name": "model", "in": "query", "required": true, "schema": { "type": "string" } },
          { "name": "trim", "in": "query", "schema": { "type": "string" } },
          { "name": "mileage", "in": "query", "schema": { "type": "integer" }, "description": "narrows to a mileage band; auto-widens if thin" }
        ],
        "responses": { "200": { "description": "low/average/median/high + sample size + confidence + province depth" }, "400": { "description": "Missing year/make/model" }, "403": { "description": "Requires a paid plan" } }
      }
    },
    "/v1/feed": {
      "get": {
        "summary": "Bulk syndication export (Feed/Enterprise tier)",
        "description": "Keyset-paginated bulk export for mirroring the dataset. Up to 1,500 rows/call; follow next_cursor until null. Gated to the Feed/Enterprise plan; typically sold as a flat monthly subscription rather than metered. FRESHNESS SLA: data is guaranteed current within 24-48 hours (refreshed continuously; the response's data_refreshed_at is the last serving-layer rebuild timestamp).",
        "parameters": [
          { "name": "province", "in": "query", "schema": { "type": "string" } },
          { "name": "oem", "in": "query", "schema": { "type": "string" } },
          { "name": "dealer", "in": "query", "schema": { "type": "string" } },
          { "name": "condition", "in": "query", "schema": { "type": "string" } },
          { "name": "make", "in": "query", "schema": { "type": "string" } },
          { "name": "cursor", "in": "query", "schema": { "type": "string" }, "description": "opaque next_cursor from the previous page" },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 1000, "maximum": 1500 } }
        ],
        "responses": { "200": { "description": "count, next_cursor, results[]" }, "403": { "description": "Requires the Feed/Enterprise plan" } }
      }
    },
    "/v1/usage": {
      "get": {
        "summary": "Your account: this billing period's usage + expected next charge",
        "description": "Returns this calendar month's call count and per-endpoint breakdown (real-time, from the usage meter), the free-tier quota remaining (free plan), and the upcoming invoice amount + date from Stripe (metered/subscription plans). Not billed and never quota-blocked.",
        "responses": { "200": { "description": "usage + free_quota + next_invoice" }, "401": { "description": "Missing/invalid key" } }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": { "type": "http", "scheme": "bearer", "description": "API key as 'Authorization: Bearer <key>'" }
    }
  }
}
