{
  "openapi": "3.1.0",
  "info": {
    "title": "CleanVins Public API",
    "version": "1.0.0",
    "summary": "Free, read-only VIN decoding, NHTSA recall lookup and CleanVins product catalog for agents and developers.",
    "description": "The CleanVins Public API is a read-only HTTP API for used-car research. Use it to decode a 17-character US-market VIN against the NHTSA vPIC database, list open NHTSA safety recall campaigns for a year/make/model, and read the CleanVins product and pricing catalog. No authentication and no API key are required. All responses, including errors, are JSON. Human documentation: https://www.cleanvins.com/developers",
    "termsOfService": "https://www.cleanvins.com/privacy",
    "contact": {
      "name": "CleanVins",
      "url": "https://www.cleanvins.com/contact"
    },
    "license": {
      "name": "Free for non-commercial and commercial agent use, with attribution to CleanVins",
      "url": "https://www.cleanvins.com/about"
    }
  },
  "servers": [
    {
      "url": "https://npsltgwdjigigymthnee.supabase.co/functions/v1/public-api",
      "description": "CleanVins production API"
    }
  ],
  "externalDocs": {
    "description": "CleanVins developer & agent documentation",
    "url": "https://www.cleanvins.com/developers"
  },
  "tags": [
    { "name": "vin", "description": "VIN decoding from the NHTSA vPIC database." },
    { "name": "recalls", "description": "NHTSA safety recall campaigns by year, make and model." },
    { "name": "catalog", "description": "CleanVins products, pricing and coverage." }
  ],
  "paths": {
    "/v1/vin/{vin}": {
      "get": {
        "operationId": "decodeVin",
        "summary": "Decode a 17-character VIN",
        "description": "Decodes a US-market 17-character Vehicle Identification Number using the NHTSA vPIC database and returns the factory build sheet: model year, make, model, trim, body class, drivetrain, transmission, fuel type, engine and plant of assembly. Free, unauthenticated and cacheable for 24 hours. Title brands, salvage records, odometer history and ownership history are not included and require a paid CleanVins report.",
        "tags": ["vin"],
        "parameters": [
          {
            "name": "vin",
            "in": "path",
            "required": true,
            "description": "17-character VIN. Case-insensitive. Never contains the letters I, O or Q.",
            "schema": { "type": "string", "minLength": 17, "maxLength": 17, "pattern": "^[A-HJ-NPR-Za-hj-npr-z0-9]{17}$" },
            "example": "1FTEW1EF0GFC60218"
          }
        ],
        "responses": {
          "200": {
            "description": "Decoded vehicle build data.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/VinDecodeResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "500": { "$ref": "#/components/responses/InternalError" },
          "502": { "$ref": "#/components/responses/UpstreamUnavailable" }
        }
      }
    },
    "/v1/recalls": {
      "get": {
        "operationId": "listRecalls",
        "summary": "List NHTSA recall campaigns for a vehicle",
        "description": "Returns every NHTSA safety recall campaign recorded for a given model year, make and model, including the campaign number, component, defect summary, consequence and remedy. Data comes directly from the NHTSA Recalls API. Recall remedies are performed free of charge by franchised dealers regardless of vehicle ownership history.",
        "tags": ["recalls"],
        "parameters": [
          {
            "name": "make",
            "in": "query",
            "required": true,
            "description": "Vehicle make, for example Toyota.",
            "schema": { "type": "string" },
            "example": "Toyota"
          },
          {
            "name": "model",
            "in": "query",
            "required": true,
            "description": "Vehicle model, for example Camry.",
            "schema": { "type": "string" },
            "example": "Camry"
          },
          {
            "name": "year",
            "in": "query",
            "required": true,
            "description": "Four-digit model year.",
            "schema": { "type": "integer", "minimum": 1949, "maximum": 2100 },
            "example": 2019
          }
        ],
        "responses": {
          "200": {
            "description": "Recall campaigns matching the query. An empty array means no campaigns are recorded.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/RecallListResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "500": { "$ref": "#/components/responses/InternalError" },
          "502": { "$ref": "#/components/responses/UpstreamUnavailable" }
        }
      }
    },
    "/v1/catalog": {
      "get": {
        "operationId": "getCatalog",
        "summary": "Get the CleanVins product and pricing catalog",
        "description": "Returns the canonical CleanVins catalog: report packages and prices (single report $9.99, 3-report pack $14.99, 10-report pack $24.99), what each package includes, what is free versus paid, data sources and delivery times. Use this instead of scraping the pricing page.",
        "tags": ["catalog"],
        "responses": {
          "200": {
            "description": "The CleanVins product catalog.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Catalog" }
              }
            }
          },
          "500": { "$ref": "#/components/responses/InternalError" },
          "502": { "$ref": "#/components/responses/UpstreamUnavailable" }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApiSpec",
        "summary": "Get this OpenAPI specification",
        "description": "Redirects (HTTP 302) to the canonical CleanVins OpenAPI 3.1 document at https://www.cleanvins.com/openapi.json.",
        "tags": ["catalog"],
        "responses": {
          "302": {
            "description": "Redirect to the canonical specification document.",
            "headers": {
              "Location": {
                "description": "Canonical specification URL.",
                "schema": { "type": "string" }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "responses": {
      "BadRequest": {
        "description": "The request parameters were missing or malformed.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "NotFound": {
        "description": "No record matches the request, or the route does not exist.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "MethodNotAllowed": {
        "description": "The API is read-only; only GET, HEAD and OPTIONS are accepted.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "InternalError": {
        "description": "Unexpected CleanVins error.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "UpstreamUnavailable": {
        "description": "An upstream government data source (NHTSA) was unavailable. Retry with backoff.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "description": "Structured error envelope returned by every failing CleanVins API request.",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["code", "message", "status"],
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine-readable error code.",
                "enum": [
                  "invalid_vin",
                  "vin_not_found",
                  "missing_parameters",
                  "route_not_found",
                  "method_not_allowed",
                  "upstream_unavailable",
                  "internal_error"
                ]
              },
              "message": { "type": "string", "description": "Human-readable description of what went wrong." },
              "hint": { "type": "string", "description": "How to resolve or retry the request." },
              "status": { "type": "integer", "description": "HTTP status code, repeated in the body for convenience." },
              "documentation_url": { "type": "string", "description": "Link to the CleanVins developer documentation." }
            }
          }
        }
      },
      "Vehicle": {
        "type": "object",
        "description": "Factory build data decoded from the VIN. Any field may be null when NHTSA vPIC has no value for it.",
        "properties": {
          "year": { "type": ["string", "null"], "description": "Model year." },
          "make": { "type": ["string", "null"], "description": "Manufacturer brand." },
          "model": { "type": ["string", "null"], "description": "Model name." },
          "trim": { "type": ["string", "null"], "description": "Trim or series, when encoded in the VIN." },
          "body_class": { "type": ["string", "null"], "description": "Body style, e.g. Sedan or Pickup." },
          "vehicle_type": { "type": ["string", "null"], "description": "NHTSA vehicle type classification." },
          "drive_type": { "type": ["string", "null"], "description": "Drivetrain, e.g. AWD or 4x2." },
          "transmission": { "type": ["string", "null"], "description": "Transmission style." },
          "fuel_type": { "type": ["string", "null"], "description": "Primary fuel type." },
          "engine_cylinders": { "type": ["string", "null"], "description": "Number of engine cylinders." },
          "engine_displacement_l": { "type": ["string", "null"], "description": "Engine displacement in liters." },
          "engine_hp": { "type": ["string", "null"], "description": "Engine brake horsepower as reported to NHTSA." },
          "plant": { "type": ["string", "null"], "description": "Plant of assembly: city, state, country." }
        }
      },
      "VinDecodeResponse": {
        "type": "object",
        "description": "Successful VIN decode.",
        "required": ["vin", "vehicle", "source"],
        "properties": {
          "vin": { "type": "string", "description": "Normalized uppercase 17-character VIN." },
          "source": { "type": "string", "description": "Name of the originating data source." },
          "source_url": { "type": "string", "description": "URL of the originating data source." },
          "retrieved_at": { "type": "string", "description": "ISO 8601 timestamp of retrieval." },
          "vehicle": { "$ref": "#/components/schemas/Vehicle" },
          "full_report_url": { "type": "string", "description": "CleanVins URL where a paid full history report can be unlocked for this VIN." },
          "notes": { "type": "string", "description": "Scope note describing what the free decode does and does not include." }
        }
      },
      "Recall": {
        "type": "object",
        "description": "A single NHTSA recall campaign, passed through from the NHTSA Recalls API.",
        "properties": {
          "NHTSACampaignNumber": { "type": "string", "description": "NHTSA campaign identifier." },
          "Manufacturer": { "type": "string", "description": "Manufacturer that filed the campaign." },
          "ReportReceivedDate": { "type": "string", "description": "Date NHTSA received the campaign report." },
          "Component": { "type": "string", "description": "Affected vehicle component." },
          "Summary": { "type": "string", "description": "Defect summary." },
          "Consequence": { "type": "string", "description": "Safety consequence of the defect." },
          "Remedy": { "type": "string", "description": "Manufacturer remedy, performed free of charge." },
          "Notes": { "type": "string", "description": "Owner notes from NHTSA." }
        }
      },
      "RecallListResponse": {
        "type": "object",
        "description": "Recall campaigns for one year/make/model.",
        "required": ["count", "recalls"],
        "properties": {
          "query": {
            "type": "object",
            "description": "Echo of the normalized query.",
            "properties": {
              "make": { "type": "string", "description": "Queried make." },
              "model": { "type": "string", "description": "Queried model." },
              "year": { "type": "integer", "description": "Queried model year." }
            }
          },
          "source": { "type": "string", "description": "Name of the originating data source." },
          "source_url": { "type": "string", "description": "URL of the originating data source." },
          "retrieved_at": { "type": "string", "description": "ISO 8601 timestamp of retrieval." },
          "count": { "type": "integer", "description": "Number of recall campaigns returned." },
          "recalls": {
            "type": "array",
            "description": "Recall campaigns, newest first as returned by NHTSA.",
            "items": { "$ref": "#/components/schemas/Recall" }
          }
        }
      },
      "Catalog": {
        "type": "object",
        "description": "CleanVins product catalog: packages, prices, inclusions, data sources and delivery times.",
        "properties": {
          "products": {
            "type": "array",
            "description": "Purchasable CleanVins report packages.",
            "items": {
              "type": "object",
              "properties": {
                "name": { "type": "string", "description": "Package name." },
                "price_usd": { "type": "number", "description": "One-time price in US dollars." },
                "reports": { "type": "integer", "description": "Number of full reports included." }
              }
            }
          }
        }
      }
    }
  },
  "x-rate-limit": {
    "description": "Soft limit of 60 requests per minute per IP. Responses are cacheable for 24 hours; cache decodes rather than re-requesting.",
    "requests_per_minute": 60
  },
  "x-mcp-server": {
    "description": "CleanVins also exposes an MCP server with decode_vin, lookup_recalls, list_my_reports and get_report tools.",
    "url": "https://npsltgwdjigigymthnee.supabase.co/functions/v1/mcp",
    "transport": "streamable-http",
    "auth": "OAuth 2.1 for account-scoped tools; public tools require no auth."
  }
}
