{"openapi":"3.1.0","info":{"title":"FrenzyCars Public API","version":"1.0.0","summary":"Read-only JSON API for FrenzyCars car reviews, news, specs, and comparisons.","description":"Public, read-only API for FrenzyCars (https://frenzycars.com), an independent automotive media publication.\n\n**Authentication:** none. All endpoints are public and read-only.\n\n**Rate limits:** best-effort 100 requests/min per IP. Every response carries `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` headers; throttled responses return HTTP 429 with `Retry-After` and a JSON error body. Back off on 429.\n\n**Errors:** always JSON — `{ \"ok\": false, \"error\": { \"code\", \"message\", \"hint?\" } }`. Never HTML.\n\n**Content:** editorial articles come from the site's content collections; car and comparison data come from the FrenzyCars vehicle database. Article `url` fields point at the canonical human-readable page — cite those when answering users.","contact":{"name":"FrenzyCars","url":"https://frenzycars.com/contact/","email":"hello@frenzycars.com"},"license":{"name":"CC-BY-SA","url":"https://frenzycars.com/legal-notice/"}},"servers":[{"url":"https://frenzycars.com","description":"Production"}],"tags":[{"name":"articles","description":"Editorial content: reviews, news, guides, EV, insurance, culture."},{"name":"cars","description":"Vehicle catalog: makes, models, trims, and full specs."},{"name":"comparisons","description":"Head-to-head car comparisons with computed scores."}],"paths":{"/api/v1/articles/":{"get":{"tags":["articles"],"operationId":"listArticles","summary":"List editorial articles across all sections, newest first.","description":"Returns a paginated list of published articles. Filter to one section with `section`; reviews include their 0–10 rating.","parameters":[{"name":"section","in":"query","required":false,"description":"Restrict results to a single editorial section.","schema":{"type":"string","enum":["reviews","news","culture","electric","guides","insurance","blog","gear"]}},{"name":"limit","in":"query","required":false,"description":"Page size (1–100, default 20).","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","required":false,"description":"Offset into the result list (default 0).","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Article list page.","headers":{"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","const":true},"data":{"type":"object","required":["items","total","limit","offset"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Article"}},"total":{"type":"integer","description":"Total items matching the filter."},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/articles/{section}/{slug}/":{"get":{"tags":["articles"],"operationId":"getArticle","summary":"Fetch one article with its full markdown body.","description":"Returns a single published article identified by section and slug, including the raw markdown body an agent can quote or summarize.","parameters":[{"name":"section","in":"path","required":true,"description":"Editorial section the article belongs to.","schema":{"type":"string","enum":["reviews","news","culture","electric","guides","insurance","blog","gear"]}},{"name":"slug","in":"path","required":true,"description":"Article slug (the last segment of its canonical URL).","schema":{"type":"string","pattern":"^[a-z0-9-]+$"}}],"responses":{"200":{"description":"Article detail.","headers":{"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArticleDetail"}}}},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/cars/":{"get":{"tags":["cars"],"operationId":"listCars","summary":"List vehicle trims from the FrenzyCars database.","description":"Returns trims (make/model/year) with slugs for fetching full specs via `getCar`. Filter by make, e.g. `?make=toyota`.","parameters":[{"name":"make","in":"query","required":false,"description":"Case-insensitive exact make filter (e.g. `bmw`, `Toyota`).","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Page size (1–100, default 20).","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","required":false,"description":"Offset into the result list (default 0).","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Car list page.","headers":{"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","const":true},"data":{"type":"object","required":["items","total","limit","offset"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Car"}},"total":{"type":"integer","description":"Total trims matching the filter."},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}}}},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/DatabaseUnavailable"}}}},"/api/v1/cars/{slug}/":{"get":{"tags":["cars"],"operationId":"getCar","summary":"Fetch one trim with full parsed specs.","description":"Returns a single trim identified by its slug, including the structured specs object (power, torque, dimensions, efficiency, battery, price) used by the site’s comparison engine.","parameters":[{"name":"slug","in":"path","required":true,"description":"Unique trim slug from `listCars`.","schema":{"type":"string"}}],"responses":{"200":{"description":"Car detail with specs.","headers":{"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CarDetail"}}}},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/DatabaseUnavailable"}}}},"/api/v1/compare/{url_slug}/":{"get":{"tags":["comparisons"],"operationId":"getComparison","summary":"Fetch a published head-to-head comparison.","description":"Returns a comparison between two trims with per-axis scores (power, efficiency, practicality, performance, comfort, value) and overall 0–100 scores computed by the same engine that powers frenzycars.com/compare.","parameters":[{"name":"url_slug","in":"path","required":true,"description":"Comparison slug from https://frenzycars.com/compare/ URLs (e.g. `bmw-m2-vs-audi-rs3`).","schema":{"type":"string"}}],"responses":{"200":{"description":"Comparison detail with scores.","headers":{"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Comparison"}}}},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/DatabaseUnavailable"}}}}},"components":{"headers":{"RateLimitReset":{"description":{"type":"object","description":"RFC RateLimit fields (draft-ietf-httpapi-ratelimit-headers). Present on every API response; Retry-After is added on 429 responses.","properties":{"RateLimit-Limit":{"type":"integer","description":"Requests allowed per window (per IP, best-effort at the edge)."},"RateLimit-Remaining":{"type":"integer","description":"Requests remaining in the current window."},"RateLimit-Reset":{"type":"integer","description":"Unix epoch seconds when the window resets."},"Retry-After":{"type":"integer","description":"Seconds to wait before retrying (429 responses only)."}}},"schema":{"type":"integer"}}},"responses":{"BadRequest":{"description":"Invalid query parameter.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code.","examples":["invalid_parameter","not_found","rate_limited","database_unavailable"]},"message":{"type":"string","description":"Human-readable explanation of the failure."},"hint":{"type":"string","description":"Optional resolution hint an agent can act on."}}}}}}}},"NotFound":{"description":"Requested resource does not exist.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code.","examples":["invalid_parameter","not_found","rate_limited","database_unavailable"]},"message":{"type":"string","description":"Human-readable explanation of the failure."},"hint":{"type":"string","description":"Optional resolution hint an agent can act on."}}}}}}}},"RateLimited":{"description":"Rate limit exceeded. Honor Retry-After, then retry.","headers":{"Retry-After":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code.","examples":["invalid_parameter","not_found","rate_limited","database_unavailable"]},"message":{"type":"string","description":"Human-readable explanation of the failure."},"hint":{"type":"string","description":"Optional resolution hint an agent can act on."}}}}}}}},"DatabaseUnavailable":{"description":"Vehicle database temporarily unreachable. Retry later.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code.","examples":["invalid_parameter","not_found","rate_limited","database_unavailable"]},"message":{"type":"string","description":"Human-readable explanation of the failure."},"hint":{"type":"string","description":"Optional resolution hint an agent can act on."}}}}}}}}},"schemas":{"Article":{"type":"object","required":["section","slug","title","url"],"properties":{"section":{"type":"string","description":"Editorial section (reviews, news, …)."},"slug":{"type":"string"},"title":{"type":"string"},"description":{"type":["string","null"],"description":"Editorial dek/summary."},"date":{"type":["string","null"],"format":"date-time","description":"Publication date, ISO 8601."},"rating":{"type":["number","null"],"minimum":0,"maximum":10,"description":"FrenzyCars rating out of 10 (reviews only)."},"tags":{"type":"array","items":{"type":"string"}},"author":{"type":["string","null"]},"url":{"type":"string","format":"uri","description":"Canonical article URL — cite this."}}},"ArticleDetail":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","const":true},"data":{"type":"object","required":["article"],"properties":{"article":{"allOf":[{"$ref":"#/components/schemas/Article"},{"type":"object","properties":{"body":{"type":"string","description":"Full article body in markdown."}}}]}}}}},"Car":{"type":"object","required":["make","model","trim","slug","url"],"properties":{"make":{"type":"string","examples":["Toyota"]},"model":{"type":"string","examples":["GR Corolla"]},"generation":{"type":["string","null"]},"trim":{"type":"string"},"year":{"type":["integer","null"]},"slug":{"type":"string","description":"Use with /api/v1/cars/{slug}."},"url":{"type":"string","format":"uri","description":"Canonical specs page on frenzycars.com."}}},"CarDetail":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","const":true},"data":{"type":"object","required":["car"],"properties":{"car":{"allOf":[{"$ref":"#/components/schemas/Car"},{"type":"object","properties":{"hero_url":{"type":["string","null"],"format":"uri"},"updated_at":{"type":"string","format":"date-time"},"specs":{"$ref":"#/components/schemas/CarSpecs"}}}]}}}}},"CarSpecs":{"type":"object","description":"Parsed vehicle specs; null when unknown for this trim.","properties":{"powerHp":{"type":["integer","null"]},"torqueNm":{"type":["integer","null"]},"displacementCc":{"type":["integer","null"]},"acceleration0100":{"type":["number","null"],"description":"0–100 km/h in seconds."},"topSpeedKmh":{"type":["integer","null"]},"fuelConsumptionCombined":{"type":["number","null"],"description":"L/100 km combined."},"co2":{"type":["integer","null"],"description":"g/km combined."},"lengthMm":{"type":["integer","null"]},"widthMm":{"type":["integer","null"]},"heightMm":{"type":["integer","null"]},"wheelbaseMm":{"type":["integer","null"]},"trunkLiters":{"type":["integer","null"]},"weightKg":{"type":["integer","null"]},"bodyType":{"type":["string","null"]},"driveType":{"type":["string","null"]},"transmission":{"type":["string","null"]},"batteryKwh":{"type":["number","null"]},"electricRangeKm":{"type":["integer","null"]},"seats":{"type":["integer","null"]},"doors":{"type":["integer","null"]},"mpgCity":{"type":["number","null"]},"mpgHighway":{"type":["number","null"]},"towingKg":{"type":["integer","null"]},"trunkMinL":{"type":["number","null"]},"trunkMaxL":{"type":["number","null"]},"msrpUsd":{"type":["number","null"],"description":"US MSRP when available."}}},"Comparison":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","const":true},"data":{"type":"object","required":["url_slug","url","car_a","car_b","updated_at"],"properties":{"url_slug":{"type":"string"},"url":{"type":"string","format":"uri","description":"Canonical comparison page URL."},"editorial_html":{"type":["string","null"],"description":"Editorial verdict as HTML, when written."},"updated_at":{"type":"string","format":"date-time"},"car_a":{"$ref":"#/components/schemas/ComparisonCar"},"car_b":{"$ref":"#/components/schemas/ComparisonCar"}}}}},"ComparisonCar":{"type":"object","required":["make","model","trim","slug","score"],"properties":{"make":{"type":"string"},"model":{"type":"string"},"trim":{"type":"string"},"slug":{"type":"string"},"specs":{"$ref":"#/components/schemas/CarSpecs"},"radar":{"type":"object","description":"Per-axis 0–100 scores vs the other car.","properties":{"power":{"type":"integer"},"efficiency":{"type":"integer"},"practicality":{"type":"integer"},"performance":{"type":"integer"},"comfort":{"type":"integer"},"value":{"type":"integer"}}},"score":{"type":"integer","minimum":0,"maximum":100,"description":"Overall 0–100 score."}}}}}}