{
  "openapi": "3.1.0",
  "info": {
    "title": "Before Your Next Car",
    "version": "0.4.0",
    "description": "Public, read-only lease data. Coverage is incomplete. Monetary values use CAD cents; APR uses basis points. Comparisons include verified manufacturer quotes and labelled calculations with complete fee treatment. Fee-unverified manufacturer estimates remain separate and have null comparison payments."
  },
  "paths": {
    "/api/v1/settings": {
      "get": {
        "summary": "Comparison rules and scenarios",
        "parameters": [],
        "responses": {
          "200": {
            "description": "JSON data. Missing quotes are null, never zero.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Invalid scenario or pagination"
          },
          "503": {
            "description": "Data service unavailable"
          }
        }
      }
    },
    "/api/v1/coverage": {
      "get": {
        "summary": "Per-brand collection status",
        "parameters": [],
        "responses": {
          "200": {
            "description": "JSON data. Missing quotes are null, never zero.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Invalid scenario or pagination"
          },
          "503": {
            "description": "Data service unavailable"
          }
        }
      }
    },
    "/api/v1/vehicles": {
      "get": {
        "summary": "Discovered catalog entries",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "brand",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "bodyStyle",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "powertrain",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "drivetrain",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "JSON data. Missing quotes are null, never zero.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Invalid scenario or pagination"
          },
          "503": {
            "description": "Data service unavailable"
          }
        }
      }
    },
    "/api/v1/compare": {
      "get": {
        "summary": "Exact and higher-mileage comparisons",
        "parameters": [
          {
            "name": "term",
            "in": "query",
            "schema": {
              "type": "integer",
              "enum": [
                24,
                36,
                39,
                48
              ],
              "default": 48
            }
          },
          {
            "name": "km",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 12000,
              "maximum": 25000,
              "multipleOf": 1000,
              "default": 16000
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "brand",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "bodyStyle",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "powertrain",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "drivetrain",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "JSON data. Missing quotes are null, never zero.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Invalid scenario or pagination"
          },
          "503": {
            "description": "Data service unavailable"
          }
        }
      }
    },
    "/api/v1/vehicles/{id}/matrix": {
      "get": {
        "summary": "Supported scenarios for a vehicle with current lease pricing",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "JSON data. Missing quotes are null, never zero.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Invalid scenario or pagination"
          },
          "503": {
            "description": "Data service unavailable"
          }
        }
      }
    },
    "/api/v1/vehicles/{id}/history": {
      "get": {
        "summary": "Paginated historical observations",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "JSON data. Missing quotes are null, never zero.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Invalid scenario or pagination"
          },
          "503": {
            "description": "Data service unavailable"
          }
        }
      }
    },
    "/api/v1/offers": {
      "get": {
        "summary": "Fresh, priced leases with global sorting and budget filtering",
        "description": "The manufacturerEstimates field is separate from matching results: its amounts have unverified fees, do not count toward total, and are not filtered by budget or price ranking.",
        "parameters": [
          {
            "name": "term",
            "in": "query",
            "schema": {
              "type": "integer",
              "enum": [
                24,
                36,
                39,
                48
              ],
              "default": 48
            }
          },
          {
            "name": "km",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 12000,
              "maximum": 25000,
              "multipleOf": 1000,
              "default": 16000
            }
          },
          {
            "name": "brand",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Select one or more values with repeated parameters or comma-separated values. Choices within this group use OR; separate groups use AND."
          },
          {
            "name": "type",
            "in": "query",
            "description": "Select one or more values with repeated parameters or comma-separated values. Choices within this group use OR; separate groups use AND.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "suv",
                  "sedan",
                  "hatchback",
                  "truck",
                  "minivan",
                  "coupe",
                  "convertible",
                  "wagon"
                ]
              }
            },
            "style": "form",
            "explode": true
          },
          {
            "name": "budget",
            "in": "query",
            "style": "form",
            "explode": true,
            "description": "One or more monthly price bands. Repeated parameters or comma-separated values. Lower bounds included, upper bounds excluded. Legacy max-<cents> tokens preserve an inclusive maximum.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "examples": [
                  "under-400",
                  "400-500",
                  "500-600",
                  "600-700",
                  "700-800",
                  "800-1000",
                  "1000-1250",
                  "1250-1500",
                  "1500-2000",
                  "2000-plus"
                ]
              }
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "max",
            "in": "query",
            "schema": {
              "type": "number",
              "exclusiveMinimum": 0
            },
            "description": "Legacy inclusive monthly maximum in CAD. Used only when budget ranges are absent; normalized to a max-<cents> budget selection in the response.",
            "deprecated": true
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "price",
                "price_desc",
                "name"
              ],
              "default": "price"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "JSON data. Missing quotes are null, never zero.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Invalid scenario or pagination"
          },
          "503": {
            "description": "Data service unavailable"
          }
        }
      }
    },
    "/api/v1/manufacturer-estimates": {
      "get": {
        "summary": "Separate manufacturer estimates with mandatory fees not fully verified",
        "description": "Filter by brand, type, model search, term and nearest supported higher mileage. Budget and price sorting do not apply. Latest observations only, maximum eight days old. Returns up to 100 items alphabetically, with quote.details.manufacturerEstimate; quote.paymentCents remains null. Not eligible for comparisons.",
        "parameters": [
          {
            "name": "term",
            "in": "query",
            "schema": {
              "type": "integer",
              "enum": [
                24,
                36,
                39,
                48
              ],
              "default": 48
            }
          },
          {
            "name": "km",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 12000,
              "maximum": 25000,
              "multipleOf": 1000,
              "default": 16000
            }
          },
          {
            "name": "brand",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Select one or more values with repeated parameters or comma-separated values. Choices within this group use OR; separate groups use AND."
          },
          {
            "name": "type",
            "in": "query",
            "description": "Select one or more values with repeated parameters or comma-separated values. Choices within this group use OR; separate groups use AND.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "suv",
                  "sedan",
                  "hatchback",
                  "truck",
                  "minivan",
                  "coupe",
                  "convertible",
                  "wagon"
                ]
              }
            },
            "style": "form",
            "explode": true
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "JSON data. Missing quotes are null, never zero.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Invalid scenario or pagination"
          },
          "503": {
            "description": "Data service unavailable"
          }
        }
      }
    }
  }
}
