Cost of Ownership
What a car actually costs to run — depreciation, fuel, insurance, maintenance and taxes over a holding period
Endpoint
GET https://api.carapi.dev/v1/cost-of-ownershipThe third question in the set: Vehicle Valuation answers what is it worth, Time to Sell answers how fast will it move, and this answers what will it cost me to keep.
Read the breakdown, not just the total
Every component carries its own confidence, and they are not equal within a single answer. Collapsing the response to one number throws away the only signal that separates a figure backed by a published dataset from one backed by an authored constant.
| Value | What it means | Typically |
|---|---|---|
| measured | A published dataset covers this exact vehicle — EEA or EPA consumption for the model, year and kW band, an official fuel-price series, a depreciation curve fitted across live comparable listings. | depreciation, fuel |
| estimated | Authored constants, or data stretched to fit the cohort. Still useful for comparing cars against each other; weaker as an absolute figure. | insurance, maintenance, taxesAndFees |
The same component can flip between the two across vehicles: fuel is measured for a mainstream diesel with an EEA record and estimated for a rare import that only matched on a neighbouring model year. sampleSize and modelYearUsed on the fuel component tell you which happened.
What's included, what's excluded
| Component | Included | Not included |
|---|---|---|
| depreciation | Value lost between today’s market price and the resale price at the end of the horizon, fitted across live comparable listings. | Any assumption that you sell at trade-in or auction rather than privately. |
| fuel | Energy for the resolved drivetrain at the annual distance, priced from a published series and held flat. | Price inflation or forecast movement — see fuelPriceFlat. |
| insurance | The mandatory cover only: MTPL in CZ/SK/PL, liability at state minimums in the US. | Collision, comprehensive, GAP, and any driver-specific loading or no-claims discount. |
| maintenance | Scheduled servicing, wear parts and tyres, rising with age and distance. | Accident repairs, unscheduled failures, and warranty work. |
| taxesAndFees | Statutory charges, itemised: vignettes and roadworthiness tests in CZ/SK/PL; sales tax, registration and title in the US. | City entry and congestion charges, tolls, and parking. |
Financing interest is never included, in any market. A car bought on credit costs more than this endpoint says, and by an amount only you know.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| make | string | Required | Vehicle manufacturer, 1-50 characters (case-insensitive). Common aliases are resolved for you (volkswagen → vw). |
| model | string | Required | Vehicle model, 1-100 characters. Matched as a base model; trim codes are folded to their series (320d → 3-series). |
| year | integer | Required | Model year, 1990 to next year. Required — depreciation is a function of the car’s age, so there is no cohort-wide answer to fall back on. |
| country | enum | Required | CZ, SK, PL or US (case-insensitive). |
| fuel | enum | Optional | petrol, diesel, electric, hybrid, phev or lpg. Omit it and the drivetrain is inferred from what the market sells for this model and year. lpg is rejected for US. |
| kw | integer | Optional | Engine power in kW, 1-2000. Narrows the depreciation cohort and picks the CZ/SK/PL insurance band. Ignored for US insurance. |
| kmPerYear | integer | Optional | Annual distance in km, 1,000-200,000. Defaults to 15,000 (CZ/SK/PL) or 19,300 (US, i.e. 12,000 miles). |
| years | integer | Optional | Holding period in whole years, 1-15. Default 5. |
| currency | enum | Optional | EUR, CZK, PLN or USD. Defaults to EUR for CZ/SK/PL and USD for US. Not constrained by country. |
| token | string | Required | API authentication token. |
Every rule above is enforced before the upstream call, so a malformed request fails fast rather than after a round trip.
Request Examples
cURL
curl -X GET \
"https://api.carapi.dev/v1/cost-of-ownership?make=skoda&model=octavia&year=2019&country=CZ&kw=110&token=YOUR_API_KEY"JavaScript
const params = new URLSearchParams({
token: 'YOUR_API_KEY',
make: 'skoda',
model: 'octavia',
year: '2019',
country: 'CZ',
fuel: 'diesel',
kw: '110',
kmPerYear: '20000',
years: '3',
currency: 'CZK'
});
const response = await fetch(
`https://api.carapi.dev/v1/cost-of-ownership?${params.toString()}`
);
const data = await response.json();
const { currency } = data.assumptions;
console.log(`${data.totals.perMonth} ${currency}/month over ${data.assumptions.years} years`);
// Show the components, not just the total — each carries its own confidence.
for (const [name, part] of Object.entries(data.breakdown)) {
console.log(` ${name}: ${part.total} ${currency} (${part.confidence})`);
}Python
import requests
response = requests.get(
"https://api.carapi.dev/v1/cost-of-ownership",
params={
"token": "YOUR_API_KEY",
"make": "toyota",
"model": "camry",
"year": 2021,
"country": "US",
"kmPerYear": 19300,
"years": 5,
},
)
data = response.json()
print(f"{data['totals']['total']} {data['assumptions']['currency']} over 5 years")
for name, part in data["breakdown"].items():
print(f" {name:15} {part['total']:>7} ({part['confidence']})")Response Examples
2019 Skoda Octavia in CZ, 5 years (200)
The EU shape: MTPL insurance banded on kW, EEA consumption, no annual passenger-car road tax.
{
"vehicle": {
"make": "Skoda",
"model": "Octavia",
"year": 2019,
"fuel": "diesel",
"kw": 110,
"requested": { "make": "skoda", "model": "octavia" }
},
"country": "CZ",
"assumptions": {
"kmPerYear": 15000,
"years": 5,
"currentValue": 12800,
"currency": "EUR",
"fuelPriceFlat": true
},
"totals": { "total": 18092, "perYear": 3618, "perMonth": 302, "perKm": 0.241 },
"breakdown": {
"depreciation": {
"total": 6400,
"confidence": "measured",
"method": "market-cross-section",
"valueBasis": "median",
"notes": ["Fitted across 1,180 CZ listings of this model aged 4-13 years."]
},
"fuel": {
"total": 5112,
"confidence": "measured",
"consumptionL100km": 4.8,
"consumptionKwh100km": null,
"provider": "eea",
"fuelKey": "diesel",
"modelYearUsed": 2019,
"kwBand": [100, 120],
"sampleSize": 42,
"pricePerUnit": 1.42,
"priceUnit": "litre",
"priceCurrency": "EUR",
"notes": ["Type-approval consumption; real-world use typically runs 10-20% higher."]
},
"insurance": {
"total": 2100,
"confidence": "estimated",
"annualPremium": 420,
"kwBand": [92, 120],
"notes": ["A comprehensive policy typically runs 2-3x this."]
},
"maintenance": {
"total": 3900,
"confidence": "estimated",
"notes": ["Servicing, wear parts and tyres, rising with age. Excludes accident repairs."]
},
"taxesAndFees": {
"total": 580,
"confidence": "estimated",
"items": [
{ "label": "Motorway vignette", "total": 460, "recurring": true },
{ "label": "Technical + emissions inspection", "total": 120, "recurring": true }
],
"notes": ["Passenger cars have paid no annual road tax in CZ since 2022."]
}
},
"perYear": [
{ "year": 1, "calendarYear": 2026, "vehicleAge": 7, "depreciation": 1700, "fuel": 1022, "insurance": 420, "maintenance": 620, "taxesAndFees": 116, "total": 3878 },
{ "year": 2, "calendarYear": 2027, "vehicleAge": 8, "depreciation": 1450, "fuel": 1022, "insurance": 420, "maintenance": 700, "taxesAndFees": 116, "total": 3708 },
{ "year": 3, "calendarYear": 2028, "vehicleAge": 9, "depreciation": 1250, "fuel": 1023, "insurance": 420, "maintenance": 780, "taxesAndFees": 116, "total": 3589 },
{ "year": 4, "calendarYear": 2029, "vehicleAge": 10, "depreciation": 1050, "fuel": 1022, "insurance": 420, "maintenance": 880, "taxesAndFees": 116, "total": 3488 },
{ "year": 5, "calendarYear": 2030, "vehicleAge": 11, "depreciation": 950, "fuel": 1023, "insurance": 420, "maintenance": 920, "taxesAndFees": 116, "total": 3429 }
]
}2021 Toyota Camry in US, 5 years (200)
Same shape, different regime — abbreviated to the parts that change. EPA consumption, liability-only insurance that ignores kw, and sales tax landing entirely in year 1.
{
"vehicle": { "make": "Toyota", "model": "Camry", "year": 2021, "fuel": "petrol", "kw": 151, "requested": { "make": "toyota", "model": "camry" } },
"country": "US",
"assumptions": { "kmPerYear": 19300, "years": 5, "currentValue": 21500, "currency": "USD", "fuelPriceFlat": true },
"totals": { "total": 27490, "perYear": 5498, "perMonth": 458, "perKm": 0.285 },
"breakdown": {
"insurance": {
"total": 3900,
"confidence": "estimated",
"annualPremium": 780,
"kwBand": null,
"notes": ["US premiums are not power-rated, so kw does not affect this component."]
},
"taxesAndFees": {
"total": 2090,
"confidence": "estimated",
"items": [
{ "label": "Sales tax on vehicle value (~6%)", "total": 1290, "recurring": false },
{ "label": "Registration and title", "total": 800, "recurring": true }
],
"notes": [
"National expected values across 50 state regimes — not a bill for any one state.",
"Sales tax falls entirely in year 1, following the Edmunds True Cost to Own convention."
]
}
}
}A component could not be estimated (404)
missing names which one, and is one of make, model, consumption, fuelPrice, depreciation or insurance.
{
"error": "Insufficient data to estimate cost of ownership for this vehicle",
"missing": "consumption",
"hint": "No EEA consumption record for this model, year and kW band. Omit kw, or try an adjacent model year."
}Response Fields
| Field | Type | Description |
|---|---|---|
| vehicle | object | The car the figures describe as the upstream resolved it (make, model, year, fuel, kw), plus requested — the make and model as you sent them, after case and alias normalization (volkswagen → vw) but before the upstream’s own resolution. Match against requested, not vehicle.make |
| country | string | Market the figures describe |
| assumptions | object | What the numbers were computed against: kmPerYear, years, currentValue, currency, and fuelPriceFlat. Enough to reproduce or re-scale them |
| totals | object | total, perYear, perMonth and perKm. Integers except perKm, which carries 3 decimals. total is the sum of the five components and of the perYear rows |
| breakdown | object | The five components — depreciation, fuel, insurance, maintenance, taxesAndFees — each with its own total, confidence and notes |
| perYear | array | One row per requested year, with the five components and the row total. Not the average repeated: depreciation is steepest early, and one-off charges land in year 1 |
All money values are integers in assumptions.currency, with one exception: totals.perKm carries 3 decimals.
Market Coverage (4 countries)
Narrower than Time to Sell's 13 markets, and far narrower than Vehicle Valuation's 24. A total needs all five components to exist locally — a fuel-price series, an insurance premium model and the tax regime encoded — not just enough listings to fit a curve.
| Markets | Insurance scope | Taxes and fees | Consumption |
|---|---|---|---|
| CZ, SK, PL | MTPL (third-party liability), banded on engine power — so kw moves this figure | Vignettes and roadworthiness tests. No annual passenger-car road tax | EEA |
| US | Liability-only at state minimums. Not power-rated, so kw is ignored here | ~6% sales tax on the car's value plus registration and title | EPA |
US tax and fee figures are national expected values across 50 state regimes, following the Edmunds True Cost to Own convention — including roughly 6% sales tax on the car's value, charged once in year 1. Sales tax actually ranges from 0% (Oregon, Montana, New Hampshire, Delaware) to over 7%, and registration varies just as widely. Treat the US total as a basis for comparing cars, not as a bill for your state.
Error Codes
Bad Request
Missing make/model/year/country, an unsupported country, fuel type or currency, a fuel type the market does not support (lpg in US), or a numeric parameter out of range
Forbidden
Invalid or missing API token
Insufficient data
A whole component could not be estimated. Act on missing and hint — the answer is cached per query, so retrying the same request unchanged returns the same 404
Bad Gateway
The upstream cost-data service answered with an unexpected status or payload
Service Unavailable
The upstream cost-data service was unreachable or timed out
Important Notes
- •These are estimates, not quotes. Nothing here is priced for a specific vehicle, driver or policy — insurance in particular assumes a clean record and mandatory cover only, and a real quote will differ.
- •Render
confidenceper component. A total whose depreciation is measured and whose insurance is estimated is not the same object as one where both are measured, and only the breakdown says which you have. - •
perYearis nottotals.perYearrepeated. Depreciation is steepest in the first years and one-off charges (US sales tax, registration) land in year 1, so a 1-year horizon is never one fifth of a 5-year one. Use the rows for a cash-flow view andtotalsfor a headline. - •
fuelPriceFlatis always true today: the pump price is held at its observed value for the whole horizon rather than forecast. A rising-price scenario is yours to model, andpricePerUnitgives you the base to model it from. - •Consumption figures are type-approval (EEA) or combined-cycle (EPA) ratings. Real-world use typically runs 10-20% higher, so the fuel component is a floor rather than a mid-point.
- •Prices are quoted per litre even in the US, so markets stay directly comparable. Divide by 3.785 to sanity-check against a per-gallon price.
- •
vehicle.requestedechoes the make and model you sent in canonical form — lowercased, aliases resolved (volkswagen → vw), trim codes folded (320d → 3-series) — whilevehicle.make/vehicle.modelcarry the car the upstream resolved. Match your own records againstrequested, allowing for that normalization. - •Each request consumes 1 API credit from your monthly allowance, including the 404s and the 400s. Validation happens before the upstream call, so a bad request fails in milliseconds — but it still counts.