Sold Vehicles Summary

Get monthly sold-vehicle statistics for US dealer sales since January 2021, grouped by geography and vehicle attributes and ranked by any measure.

Use the Sold Vehicles Summary API to see how many vehicles sold in a market, at what price, with what mileage, and how long they were for sale. One call returns ranked rows with the sold count, price, mileage, and days-on-market statistics (including percentiles), and MSRP averages, grouped by month, geography, and the vehicle attributes you choose.

The Sold Vehicles Summary API aggregates US dealer sales by month. You can summarize at state, city, or national level, filter by vehicle, dealer, and website attributes, and rank groups by any measure in the response.

This enables dealers, dealership groups, manufacturers, lenders, insurers, and market analysts to see which vehicles sell where, at what price, and how quickly.

Overview

  • Statistics on US dealer sales from January 2021 through the latest complete month, refreshed monthly
  • Sales are inferred from listings that disappear from dealer websites. Read more about Inferred Sales
  • Prices are advertised asking prices at the time of sale, not negotiated transaction prices
  • Results are aggregated rows only, never individual listings or VINs. Auction and private-seller listings are excluded

Measures & Definitions:

  • Counts: Each statistic covers only vehicles with a value, shown in its count field
  • Days on Site: dos_active counts days on the website domain the vehicle sold on
  • MSRP on Used Vehicles: Compare prices with mc_msrp, not the listing msrp
  • Mileage: Excludes readings over 500,000, kilometer readings, and readings of 0 on used vehicles

How It Works

Each row in the response is one group: a month, a geography, the inventory type (unless inventory_type=all combines new and used), and the values of the ranking dimensions you request. A ranking dimension is a field that defines a group, such as make or model. A measure is a statistic in a row, such as sold_count, price.mean, or miles.p50.

Percentile measures are named pNN in parameters and read from percentiles in the row, so price.p50 is price.percentiles["50.0"]. Other measure names match their path in the row, such as price.mean.

Within each month and geography, the API ranks the groups by ranking_measure and returns the top top_n ranks.

  • Month is part of every group, including at the national level. A twelve-month request returns up to one row per month for each group
  • Rows with no value for the geography or a requested dimension are excluded. Use ranking_dimensions=none to get one totals row per month and geography, with no rows excluded

Filters work at two stages. Row filters, such as make, state, and year_range, act on vehicles. Measure filters, such as price.mean and sold_count, act on whole groups:

BehaviorRow FiltersMeasure Filters
AppliedBefore statistics are computedAfter statistics are computed
RemovesVehiclesWhole groups
Effect on statistics in a remaining rowChanges themLeaves them unchanged

Base Path

GET https://api.marketcheck.com/v2/sold-vehicles/summary

The following example demonstrates a basic request that returns statistics for used Toyota RAV4s sold in Rhode Island in the latest complete month:

request.js
import axios from 'axios';

const options = {
method: 'GET',
url: 'https://api.marketcheck.com/v2/sold-vehicles/summary',
params: {
api_key: 'YOUR_API_KEY',
state: 'RI',
make: 'Toyota',
model: 'RAV4',
inventory_type: 'used',
ranking_dimensions: 'make,model',
top_n: '1'
},
headers: {Accept: 'application/json'}
};

try {
const { data } = await axios.request(options);
console.log(data);
} catch (error) {
console.error(error);
}

Explore the full range of parameters available for filtering, grouping, and ranking results in the Parameters section below.

Request

The Sold Vehicles Summary API requires api_key and inventory_type on every request. All other parameters are optional and let you narrow, group, and rank the results.

inventory_type has no default, and a request without it returns 422. An invalid value (including a differently cased value such as Used), or an unknown, repeated, or empty parameter, also returns 422.

Send multiple values for a parameter as a comma-separated list (e.g., make=Ford,Toyota), and send each parameter only once. Parameters such as inventory_type, summary_by, dealer_type, ranking_order, year_range, and miles_range accept only one value. Values from a fixed list, such as those for inventory_type, dealer_type, summary_by, ranking_order, and fuel_type_category, must be lowercase.

Other filter values are matched case-insensitively and literally, without wildcards or negation. Free-text values are not validated, so a misspelled value (e.g., state=Californ) returns 200 with an empty data array. Check applied in the response to see how the API interpreted the request. dealership_group_name is also matched case-insensitively, but it is validated: an unrecognized name returns 422.

To see the values the API uses for a field, request it as a ranking dimension with a high top_n (e.g., inventory_type=used&summary_by=national&make=Kia&ranking_dimensions=model&top_n=500). Only values with sales in the date window are returned.

Parameters

Available parameters for filtering, grouping, and ranking results:

61 Params
api_key
string required

Your MarketCheck API authentication key. Required for every request, unless OAuth is used.

base_exterior_color
string

Filters sold vehicles by base exterior color (e.g., White, Black, Gray, Silver). Accepts multiple values separated by commas.

base_interior_color
string

Filters sold vehicles by base interior color (e.g., Black, Gray, Beige, Brown). Accepts multiple values separated by commas.

body_subtype
string

Filters sold vehicles by pickup cab configuration (e.g., Crew, Extended, Regular). Accepts multiple values separated by commas.

body_type
string

Filters sold vehicles by body type (e.g., SUV, Pickup). Accepts multiple values separated by commas.

city
string

Filters sold vehicles by city name (e.g., Austin, Los Angeles). Accepts multiple values separated by commas. Send with state.

date_from
string

Start of the sale-date window, as the first day of a month. Specify as YYYY-MM-DD (e.g., 2026-01-01) and send with date_to. Default — first day of the latest complete month.

date_to
string

End of the sale-date window, as the last day of a month. Specify as YYYY-MM-DD (e.g., 2026-06-30) and send with date_from. Default — last day of the latest complete month.

dealer_type
string

Filters sold vehicles by dealer type. Allowed values — all, franchise, independent. Default — all.

dealership_group_name
string

Filters sold vehicles by dealership group name (e.g., AutoNation Inc.), matched case-insensitively. Accepts multiple values separated by commas. Get accepted names from the Sold Vehicles Dealership Groups API.

dom_active.count
string

Filters groups by the number of vehicles with a dom_active value, with an optional comparison operator (e.g., >=10).

dom_active.mean
string

Filters groups by mean days on market, with an optional comparison operator (e.g., <30).

dom_active.p50
string

Filters groups by median days on market, with an optional comparison operator (e.g., <30).

dos_active.count
string

Filters groups by the number of vehicles with a dos_active value, with an optional comparison operator (e.g., >=10).

dos_active.mean
string

Filters groups by mean days on site, with an optional comparison operator (e.g., <30).

dos_active.p50
string

Filters groups by median days on site, with an optional comparison operator (e.g., <30).

drivetrain
string

Filters sold vehicles by drivetrain (4WD, FWD, RWD). Accepts multiple values separated by commas.

fuel_type_category
string

Filters sold vehicles by fuel type category. Allowed values — ice, ev, hybrid, unknown, other. Accepts multiple values separated by commas.

inventory_type
string required

Inventory type of the sold vehicles. Allowed values — new, used, certified, all. used includes certified pre-owned vehicles, certified returns them only, and all combines new and used (certified included) into one row unless ranking_dimensions includes inventory_type. Accepts one value. Required.

limit
integer

Maximum number of rows to return. Default — 20000. Maximum — 20000.

make
string

Filters sold vehicles by make (e.g., Toyota, Ford). Accepts multiple values separated by commas.

mc_msrp.count
string

Filters groups by the number of vehicles with a MarketCheck MSRP, with an optional comparison operator (e.g., >=10).

mc_msrp.mean
string

Filters groups by mean MarketCheck MSRP, with an optional comparison operator (e.g., >40000).

miles.count
string

Filters groups by the number of vehicles with a valid odometer reading, with an optional comparison operator (e.g., >=10).

miles.mean
string

Filters groups by mean mileage, with an optional comparison operator (e.g., <30000).

miles.p25
string

Filters groups by 25th percentile mileage, with an optional comparison operator (e.g., <30000).

miles.p50
string

Filters groups by median mileage, with an optional comparison operator (e.g., <30000).

miles.p75
string

Filters groups by 75th percentile mileage, with an optional comparison operator (e.g., <60000).

miles.p95
string

Filters groups by 95th percentile mileage, with an optional comparison operator (e.g., <100000).

miles_range
string

Filters sold vehicles by odometer reading. Specify as min-max miles (e.g., 30000-60000).

min_sold_count
integer

Filters groups by a minimum number of vehicles sold (e.g., 30). Shorthand for sold_count=>=n. Cannot be combined with sold_count.

model
string

Filters sold vehicles by model (e.g., RAV4, F-150). Accepts multiple values separated by commas.

msrp.count
string

Filters groups by the number of vehicles with a listing MSRP, with an optional comparison operator (e.g., >=10).

msrp.mean
string

Filters groups by mean listing MSRP, with an optional comparison operator (e.g., >40000).

msrp_label
string

Filters sold vehicles by the source of the MarketCheck MSRP (e.g., oem_msrp, build_specs_msrp). Accepts multiple values separated by commas.

powertrain_type
string

Filters sold vehicles by powertrain type (e.g., Combustion, BEV, HEV, PHEV). Accepts multiple values separated by commas.

price.count
string

Filters groups by the number of vehicles with a price, with an optional comparison operator (e.g., >=10).

price.max
string

Filters groups by highest price, with an optional comparison operator (e.g., <50000).

price.mean
string

Filters groups by mean price, with an optional comparison operator (e.g., >20000).

price.min
string

Filters groups by lowest price, with an optional comparison operator (e.g., >5000).

price.p25
string

Filters groups by 25th percentile price, with an optional comparison operator (e.g., >20000).

price.p50
string

Filters groups by median price, with an optional comparison operator (e.g., <=35000).

price.p75
string

Filters groups by 75th percentile price, with an optional comparison operator (e.g., >20000).

price.p95
string

Filters groups by 95th percentile price, with an optional comparison operator (e.g., >20000).

price.stddev
string

Filters groups by the standard deviation of price, with an optional comparison operator (e.g., <5000).

price.sum
string

Filters groups by the total of all prices, with an optional comparison operator (e.g., >1000000).

price_over_mc_msrp_percentage
string

Filters groups by the percentage difference between mean price and mean MarketCheck MSRP, with an optional comparison operator (e.g., <-5).

price_over_msrp_percentage
string

Filters groups by the percentage difference between mean price and mean MSRP, with an optional comparison operator (e.g., <0).

rank_after_filters
boolean

If true, applies measure filters before ranking, so removed groups leave no gaps in the ranks. Default — false.

ranking_dimensions
string

Comma-separated list of fields to group and rank by (e.g., make,model), or none for totals. Default — make,model,body_type.

ranking_measure
string

Measure to rank groups by: sold_count, price_over_msrp_percentage, price_over_mc_msrp_percentage, or a dotted measure name (e.g., price.mean). min_sold_count is not a ranking measure. Default — sold_count.

ranking_order
string

Specifies ranking order. Allowed values — asc or desc. Default — desc.

sold_count
string

Filters groups by the number of vehicles sold, with an optional comparison operator (e.g., >100). Cannot be combined with min_sold_count.

source
string

Filters sold vehicles by website domain (e.g., carmax.com). Accepts multiple values separated by commas.

state
string

Filters sold vehicles by US state code, including DC and US territories (e.g., CA, TX). Accepts multiple codes separated by commas.

summary_by
string

Geographic level of the result rows. Allowed values — state, city_state, national. Default — state.

top_n
integer

Number of ranks to return within each month and geography. Default — 10.

transmission
string

Filters sold vehicles by transmission (Automatic, CVT, Manual). Accepts multiple values separated by commas.

trim
string

Filters sold vehicles by trim (e.g., XLE, EX). Accepts multiple values separated by commas.

year
string

Filters sold vehicles by model year (e.g., 2022). Accepts multiple years separated by commas. Cannot be combined with year_range.

year_range
string

Filters sold vehicles by model year range. Specify as min-max (e.g., 2020-2024), with either end optional (e.g., 2020-). Cannot be combined with year.

Defaults

ParameterDefault ValueDescription
date_from, date_toLatest complete monthThe request covers one month. Send both to set a window of up to 365 days
dealer_typeallFranchise and independent dealers are both counted
limit20000Maximum total rows in the response
rank_after_filtersfalseGroups are ranked before measure filters are applied
ranking_dimensionsmake,model,body_typeEach group is one make, model, and body type
ranking_measuresold_countGroups are ranked by units sold
ranking_orderdescHighest value ranks first
summary_bystateRows are returned per state
top_n10Ten ranks within each month and geography

Check top_n_source and date_window_source in the response's applied object to see whether top_n and the date window came from your request ("request") or a default ("default").

Required Parameters

inventory_type

  • Required parameter that sets which sold vehicles are counted. Accepts one value
  • Supported values: new, used (includes certified pre-owned vehicles), certified (certified pre-owned only), and all (new and used combined, so certified vehicles are included)
  • Any other value, including a differently cased one such as Used, returns 422
  • Example: inventory_type=used
inventory_type=all combines new and used vehicles into one row per group, with no inventory_type key, and returns a pooled_populations warning. Counts and sums (sold_count, price.sum, and each count) stay exact, but means and percentiles mix the two populations. To get separate new and used rows, add inventory_type to ranking_dimensions (e.g., inventory_type=all&ranking_dimensions=inventory_type,make); new and used groups are then ranked together, so top_n applies across both.

Rows report the inventory type as new or used only. With inventory_type=certified, each row shows "used", and applied.inventory_type shows "certified".

Geographic Parameters

summary_by

  • Use summary_by to set the level of the result rows: state, city_state, or national
  • state and city filter the rows. For example, summary_by=city_state&state=TX returns every city in Texas, and adding city=Austin returns Austin only
  • Example: summary_by=national

city

  • Use city to filter by city name at any summary_by level
  • Send state with city. Without it, cities with the same name in different states are combined, and the API returns a city_filter_without_state warning
  • Example: summary_by=city_state&state=TX&city=Austin
City is the finest geography available. Metro, DMA, and ZIP code levels are not supported.

Special Parameters

date_from & date_to

  • Use date_from (the first day of a month) and date_to (the last day of a month) in YYYY-MM-DD format to set the sale-date window
  • Send both or neither. Without them, the request covers the latest complete month
  • The window can span up to 365 days, and any single calendar year is accepted. A longer window returns 422, and a window outside the available history returns a window_outside_available_history warning
  • Example: date_from=2026-01-01&date_to=2026-06-30

year_range

  • Use year_range to filter by model year range in min-max format. Both ends are inclusive
  • Leave either end open: year_range=2020- (or 2020-*) means 2020 and later, and year_range=-2024 (or *-2024) means 2024 and earlier
  • year_range=-, year_range=*-*, and a minimum above the maximum return 422. Do not combine year_range with year
  • Example: year_range=2020-2023

miles_range

  • Use miles_range to filter by odometer reading in min-max format. Both ends are inclusive
  • Leave either end open, as in miles_range=30000-
  • Example: miles_range=30000-60000

Sorting & Ranking

The Sold Vehicles Summary API ranks groups within each month and geography, and returns rows in a fixed order.

Ranking Parameters:

  • ranking_dimensions - Fields that define each group (e.g., make,model), or none for one totals row per month and geography. Do not combine none with other fields
  • ranking_measure - Measure to rank by: sold_count, price_over_msrp_percentage, price_over_mc_msrp_percentage, or a dotted measure such as price.p50, all listed in Parameters. min_sold_count is not a ranking measure
  • ranking_order - Ranking direction (asc or desc)
  • top_n - Number of ranks returned within each month and geography

Default Behavior:

  • Within each month and geography, each group is one make, model, and body type, groups are ranked by sold_count in descending order, and the top 10 ranks are returned
  • Groups that tie share a rank and are all returned. A response can contain more rows than top_n suggests
  • Rows are sorted by month and geography in descending order, then by rank

Available Ranking Dimensions

Fields are listed in the order they appear in each row.

FieldDescription
inventory_typeInventory type of the row: new or used (certified vehicles show as used). Use it to split rows when inventory_type=all
yearModel year
makeVehicle make
modelVehicle model, in the source's spelling (casing can differ, e.g., Forte and FORTE)
trimTrim level
body_typeBody type
body_subtypePickup cab configuration
drivetrainDrivetrain
transmissionTransmission
powertrain_typePowertrain type, recommended for electrification analysis
fuel_type_categoryFuel type category (can classify mild hybrids as ice)
base_exterior_colorBase exterior color
base_interior_colorBase interior color
msrp_labelSource of the MarketCheck MSRP
dealership_group_nameDealership group name
sourceWebsite domain the vehicle sold on

body_subtype, powertrain_type, base_exterior_color, base_interior_color, and dealership_group_name have no value on many rows. Requesting any of them returns a sparse_dimension_rows_excluded warning.

Limits:

  • limit caps the total rows in the response, up to 20,000. When rows are removed, truncated is true
  • Rows are removed from the end of the sort order: the earliest months first and, within a month, the alphabetically first states (or cities, at city_state level)
  • There is no pagination. To get the removed rows, narrow the filters or the date window
With ranking_order=asc, groups whose ranking measure is null rank first. To keep them out of the ranking, set a minimum on the matching count and rank_after_filters=true (e.g., ranking_measure=price.mean&ranking_order=asc&price.count=%3E%3D1&rank_after_filters=true).

Measure Filters

Measure filters remove whole groups after the statistics are computed (e.g., groups with fewer than 30 sales), and do not change the numbers inside a remaining group. The measure filter parameters are sold_count, the two price_over_*_percentage parameters, and the dotted parameters such as price.mean, all listed in Parameters.

Parameters and Syntax

  • Each measure filter accepts an optional operator (>, <, >=, <=, =) followed by a number. A bare number means =, and negative and decimal numbers are accepted
    • Example: price.p50=<=35000 (sent as price.p50=%3C%3D35000) keeps groups whose median price is at most 35,000
    • Example: price_over_mc_msrp_percentage=<-5 (sent as price_over_mc_msrp_percentage=%3C-5) keeps groups whose mean price is more than 5% below the mean MarketCheck MSRP
  • min_sold_count=<n> is shorthand for sold_count=>=<n>. Sending both returns 422
    • Example: min_sold_count=30 keeps groups with at least 30 sales
  • rank_after_filters sets the order of ranking and filtering. With the default false, groups are ranked first and then filtered, and ranks can have gaps. With true, groups are filtered first, so removed groups leave no gaps in the ranks
  • If every ranked group is removed, data is empty and the API returns a measure_filter_removed_all_ranked_rows warning
URL-encode the operators in your HTTP requests (e.g., > as %3E, < as %3C, and >= as %3E%3D).

Example

Here in this example, we are finding used models in Texas with a median mileage under 30,000 in July 2026, ranked by units sold among the groups that pass the filter:

request.js
import axios from 'axios';

const options = {
method: 'GET',
url: 'https://api.marketcheck.com/v2/sold-vehicles/summary',
params: {
api_key: 'YOUR_API_KEY',
summary_by: 'state',
state: 'TX',
inventory_type: 'used',
'miles.p50': '<30000',
rank_after_filters: 'true',
ranking_dimensions: 'make,model',
ranking_measure: 'sold_count',
top_n: '10',
date_from: '2026-07-01',
date_to: '2026-07-31'
},
headers: {Accept: 'application/json'}
};

try {
const { data } = await axios.request(options);
console.log(data);
} catch (error) {
console.error(error);
}

Response

The Sold Vehicles Summary API returns a JSON object containing the request as the API interpreted it (applied), any warnings, and one row of statistics per group.

Schema

interface SoldSummaryResponse {
  success: boolean; // true when the query ran, even if it matched no groups
  result_count: number; // Number of rows in data
  limit: number; // Row limit the query ran with
  truncated: boolean; // true when limit removed rows
  warnings: Warning[]; // Always present; [] when there is nothing to report
  applied: object; // The request as the API interpreted it, including defaults
  data: SummaryRow[]; // One object per group
}

interface Warning {
  code: string; // Warning code (see Warnings below)
  message: string; // Human-readable explanation
  detail: object; // Warning-specific context
}

interface SummaryRow {
  month: string; // "YYYY-MM"
  inventory_type?: string; // "new" or "used" (certified vehicles show as "used"); absent when inventory_type=all and inventory_type is not in ranking_dimensions
  city?: string; // Present only when summary_by=city_state
  state?: string; // Present when summary_by=state or city_state
  // ...one key per requested ranking dimension, for example make, model
  rank: number; // Rank within the month and geography
  sold_count: number; // Number of vehicles sold
  price: PriceStats; // Advertised asking price at the time of sale
  miles: MilesStats; // Odometer reading
  dom_active: DaysStats; // Days for sale on any website
  dos_active: DaysStats; // Days for sale on the website it sold on
  msrp: MsrpStats; // MSRP shown on the listing
  mc_msrp: MsrpStats; // MarketCheck MSRP
  price_over_msrp_percentage: number | null; // (mean price - mean msrp) / mean msrp x 100
  price_over_mc_msrp_percentage: number | null; // Same, against mc_msrp
}

interface PriceStats {
  count: number; // Vehicles with a price
  mean: number | null;
  sum: number | null;
  min: number | null;
  max: number | null;
  stddev: number | null; // Sample standard deviation; null when count is 1
  percentiles: { "25.0": number | null; "50.0": number | null; "75.0": number | null; "95.0": number | null };
}

interface MilesStats {
  count: number; // Vehicles with a valid odometer reading
  mean: number | null;
  percentiles: { "25.0": number | null; "50.0": number | null; "75.0": number | null; "95.0": number | null };
}

interface DaysStats {
  count: number; // Vehicles with a value
  mean: number | null;
  percentiles: { "50.0": number | null };
}

interface MsrpStats {
  count: number; // Vehicles with a value
  mean: number | null;
}

Warnings

Each warning in the warnings array has a code, message, and detail. Use code, not message, when you handle warnings. A warning does not change the status code or the data returned.

CodeReturned When
city_filter_without_statecity is sent without state
measure_filter_removed_all_ranked_rowsdata is empty and measure filters were applied
pooled_populationsinventory_type=all is sent and inventory_type is not in ranking_dimensions. detail.affected_measures names the affected measure objects, such as price and miles
ranking_parameters_ignoredranking_dimensions=none is sent, and you explicitly sent top_n, ranking_measure, or ranking_order
result_truncatedlimit removed rows
sparse_dimension_rows_excludedA requested ranking dimension has no value on many rows
window_outside_available_historyThe date window falls wholly or partly outside the available history

Success Response

  • 200 OK - Returns JSON object with grouped sold-vehicle statistics, or an empty data array (with success: true) when no groups match
  • Percentile keys are strings such as "50.0". Counts and rank are integers, and other statistics are floats rounded to 2 decimal places
  • Mileage values are in miles, dom_active and dos_active values are in days, and price_over_*_percentage values are percentages (-5 means 5% below MSRP)
  • Keys that do not apply to a row are omitted (e.g., city at state level, or inventory_type when inventory_type=all is sent without inventory_type in ranking_dimensions), and a statistic is null when its count is 0

applied echoes the request as the API interpreted it, including defaults, inventory_type as sent (e.g., "certified"), the canonical spellings of any dealership_group_name values, and available_history (the first and latest complete months).

The request under Base Path returns a response like the following, captured when July 2026 was the latest complete month (applied is abridged):

{
  "success": true,
  "result_count": 1,
  "limit": 20000,
  "truncated": false,
  "warnings": [],
  "applied": {
    "summary_by": "state",
    "ranking_dimensions": ["make", "model"],
    "ranking_measure": "sold_count",
    "ranking_order": "desc",
    "top_n": 1,
    "top_n_source": "request",
    "limit": 20000,
    "date_from": "2026-07-01",
    "date_to": "2026-07-31",
    "date_window_source": "default",
    "available_history": {
      "first_month": "2021-01",
      "latest_complete_month": "2026-07"
    },
    "inventory_type": "used",
    "state": ["RI"],
    "make": ["Toyota"],
    "model": ["RAV4"],
    "semantics": {
      "drop_null_dimensions": true,
      "rank_after_filters": false
    }
  },
  "data": [
    {
      "month": "2026-07",
      "inventory_type": "used",
      "state": "RI",
      "make": "Toyota",
      "model": "RAV4",
      "rank": 1,
      "sold_count": 125,
      "price": {
        "count": 111,
        "mean": 26470.85,
        "sum": 2938264.0,
        "min": 4499.0,
        "max": 43708.0,
        "stddev": 9521.45,
        "percentiles": {
          "25.0": 18998.0,
          "50.0": 27419.0,
          "75.0": 34608.0,
          "95.0": 39876.5
        }
      },
      "miles": {
        "count": 124,
        "mean": 75611.2,
        "percentiles": {
          "25.0": 25119.25,
          "50.0": 62588.0,
          "75.0": 116009.0,
          "95.0": 184984.3
        }
      },
      "dom_active": {
        "count": 125,
        "mean": 31.1,
        "percentiles": { "50.0": 21.0 }
      },
      "dos_active": {
        "count": 125,
        "mean": 29.77,
        "percentiles": { "50.0": 20.0 }
      },
      "msrp": { "count": 111, "mean": 26697.7 },
      "mc_msrp": { "count": 125, "mean": 33264.46 },
      "price_over_msrp_percentage": -0.85,
      "price_over_mc_msrp_percentage": -20.42
    }
  ]
}

Here, 125 vehicles sold and 111 had a price, and price.mean is the mean over those 111 vehicles. The mean price is 0.85% below the mean msrp and 20.42% below the mean mc_msrp. This gap is why mc_msrp is the better reference on used vehicles.

Error Response

Status CodeDescriptionCommon Causes
401UnauthorizedMissing/invalid API key
403ForbiddenAccess denied to resource
405Method Not AllowedA method other than GET or OPTIONS
422Unprocessable EntityMissing inventory_type, an invalid value or combination, or an unknown, repeated, or empty parameter
429Too Many RequestsRate limit exceeded
500Internal Server ErrorTemporary server issues, or a request that did not complete in time
502Bad GatewayIssues with upstream services
503Service UnavailableData temporarily unavailable, or the request was too large to process

Error Response Format

Most error responses follow this structure. message is usually a string, but it can be an object, as in a 422 response, which contains a detail array (shown below), and in some 5xx responses. A 429 response contains only message (see Quota and Rate Limits), and some 502 and 503 responses may not follow this structure:

{
  "code": <HTTP status code>,
  "message": "<Error message describing the issue>"
}

Example Error Response:

Unrecognized parameter (422):

{
  "code": 422,
  "message": {
    "detail": [
      {
        "type": "extra_forbidden",
        "loc": ["query", "bogus"],
        "msg": "Extra inputs are not permitted",
        "input": "1"
      }
    ]
  }
}

In a 422 response, message.detail has one entry for each invalid parameter. Use type and loc, not msg, in your error handling, since msg text can change:

TypeReturned For
enumAn invalid value for inventory_type, dealer_type, summary_by, or ranking_order, including a differently cased value
extra_forbiddenAn unrecognized parameter
greater_than_equal, less_than_equaltop_n below 1, or limit below 1 or above 20000
missinginventory_type not sent
value_errorA repeated or empty parameter, or an invalid fuel_type_category, ranking_measure, year, year_range, miles_range, dealership_group_name, or measure filter

Best Practices

  • Always check HTTP status codes
  • Log the full 422 body. msg explains how to fix the request, but match on type and loc in code
  • Read applied when data is empty
  • Retry 502 and 503 with exponential backoff. If a 500 or 503 repeats for the same request, narrow the date window or filters instead. On 429, wait for the time in the Retry-After header (see Quota and Rate Limits)

Use Cases & Examples

Each example sets date_from and date_to. Change them to the months you need.

Get Totals for a Model in a State

Get the full set of statistics for one model in one market, such as the price range and typical days on market. This is useful for shoppers and dealers who need a market reference for a specific vehicle.

Use ranking_dimensions=none to get one totals row per month. With one row per month and geography, ranking has no effect, and applied.ranking_ignored is true in the response.

Example:

Here in this example, we are retrieving totals for used Subaru Crosstreks sold in Colorado in July 2026:

request.js
import axios from 'axios';

const options = {
method: 'GET',
url: 'https://api.marketcheck.com/v2/sold-vehicles/summary',
params: {
api_key: 'YOUR_API_KEY',
summary_by: 'state',
state: 'CO',
make: 'Subaru',
model: 'Crosstrek',
inventory_type: 'used',
ranking_dimensions: 'none',
date_from: '2026-07-01',
date_to: '2026-07-31'
},
headers: {Accept: 'application/json'}
};

try {
const { data } = await axios.request(options);
console.log(data);
} catch (error) {
console.error(error);
}

Find the Top-Selling Models in a State

Find which models sold the most in a state to guide stocking decisions. Use ranking_dimensions=make,model, and compare price.mean with price.percentiles["50.0"] to see how much high-priced outliers raise the mean.

Example:

Here in this example, we are ranking the top 15 used makes and models in Texas by units sold in July 2026:

request.js
import axios from 'axios';

const options = {
method: 'GET',
url: 'https://api.marketcheck.com/v2/sold-vehicles/summary',
params: {
api_key: 'YOUR_API_KEY',
summary_by: 'state',
state: 'TX',
inventory_type: 'used',
ranking_dimensions: 'make,model',
ranking_measure: 'sold_count',
ranking_order: 'desc',
top_n: '15',
date_from: '2026-07-01',
date_to: '2026-07-31'
},
headers: {Accept: 'application/json'}
};

try {
const { data } = await axios.request(options);
console.log(data);
} catch (error) {
console.error(error);
}

Find the Top-Selling Certified Pre-Owned Models

Find which certified pre-owned models sell the most with inventory_type=certified. The statistics cover certified vehicles only, and each row shows inventory_type as "used". Compare the results with an inventory_type=used request to see the certified share of used sales.

Example:

Here in this example, we are ranking the top 3 certified pre-owned Toyota models nationally by units sold in July 2026:

request.js
import axios from 'axios';

const options = {
method: 'GET',
url: 'https://api.marketcheck.com/v2/sold-vehicles/summary',
params: {
api_key: 'YOUR_API_KEY',
summary_by: 'national',
inventory_type: 'certified',
make: 'Toyota',
ranking_dimensions: 'model',
top_n: '3',
date_from: '2026-07-01',
date_to: '2026-07-31'
},
headers: {Accept: 'application/json'}
};

try {
const { data } = await axios.request(options);
console.log(data);
} catch (error) {
console.error(error);
}

Find the Fastest-Selling Models

Find the models that sold fastest with ranking_measure=dom_active.mean&ranking_order=asc. Use min_sold_count to require a minimum number of sales, and rank_after_filters=true to apply that minimum before ranking, so the top 10 come from models that meet it.

Example:

Here in this example, we are ranking used models in Ohio by mean days on market for each month from May through July 2026, keeping only models with at least 30 sales:

request.js
import axios from 'axios';

const options = {
method: 'GET',
url: 'https://api.marketcheck.com/v2/sold-vehicles/summary',
params: {
api_key: 'YOUR_API_KEY',
summary_by: 'state',
state: 'OH',
inventory_type: 'used',
ranking_dimensions: 'make,model',
ranking_measure: 'dom_active.mean',
ranking_order: 'asc',
min_sold_count: '30',
rank_after_filters: 'true',
top_n: '10',
date_from: '2026-05-01',
date_to: '2026-07-31'
},
headers: {Accept: 'application/json'}
};

try {
const { data } = await axios.request(options);
console.log(data);
} catch (error) {
console.error(error);
}

Estimate a Price Band for a Specific Vehicle

Estimate the advertised price band for a specific vehicle by filtering to one year, make, model, and trim. The response has one row per month. Read the band from price.percentiles, and check price.count to see how many sales each band is based on.

Example:

Here in this example, we are retrieving monthly price distributions for used 2023 Honda Civic EX vehicles sold in Pennsylvania from May through July 2026:

request.js
import axios from 'axios';

const options = {
method: 'GET',
url: 'https://api.marketcheck.com/v2/sold-vehicles/summary',
params: {
api_key: 'YOUR_API_KEY',
summary_by: 'state',
state: 'PA',
make: 'Honda',
model: 'Civic',
trim: 'EX',
year: '2023',
inventory_type: 'used',
ranking_dimensions: 'none',
date_from: '2026-05-01',
date_to: '2026-07-31'
},
headers: {Accept: 'application/json'}
};

try {
const { data } = await axios.request(options);
console.log(data);
} catch (error) {
console.error(error);
}

Find the Top-Selling Websites in a City

Find which dealer websites sell the most vehicles in a city. Use summary_by=city_state with state and city, and set ranking_dimensions=source. source is the website domain, the closest available match to an individual dealer.

Example:

Here in this example, we are ranking the websites with the most used-vehicle sales in Austin, Texas, in July 2026:

request.js
import axios from 'axios';

const options = {
method: 'GET',
url: 'https://api.marketcheck.com/v2/sold-vehicles/summary',
params: {
api_key: 'YOUR_API_KEY',
summary_by: 'city_state',
state: 'TX',
city: 'Austin',
inventory_type: 'used',
ranking_dimensions: 'source',
ranking_measure: 'sold_count',
top_n: '10',
date_from: '2026-07-01',
date_to: '2026-07-31'
},
headers: {Accept: 'application/json'}
};

try {
const { data } = await axios.request(options);
console.log(data);
} catch (error) {
console.error(error);
}

Analyze a Mileage Band

Analyze prices for vehicles within a mileage band, for example to support lending decisions. Use miles_range to filter vehicles before statistics are computed, so every statistic describes only the vehicles inside the band.

Example:

Here in this example, we are retrieving statistics for used 2020 to 2023 model-year vehicles with 30,000 to 60,000 miles sold in Texas in July 2026:

request.js
import axios from 'axios';

const options = {
method: 'GET',
url: 'https://api.marketcheck.com/v2/sold-vehicles/summary',
params: {
api_key: 'YOUR_API_KEY',
summary_by: 'state',
state: 'TX',
year_range: '2020-2023',
miles_range: '30000-60000',
inventory_type: 'used',
ranking_dimensions: 'none',
date_from: '2026-07-01',
date_to: '2026-07-31'
},
headers: {Accept: 'application/json'}
};

try {
const { data } = await axios.request(options);
console.log(data);
} catch (error) {
console.error(error);
}

Track a Monthly Trend

Track how volume, price, and mileage change month by month with a single twelve-month request. To combine months yourself, use price.sum and price.count rather than averaging the monthly means.

Example:

Here in this example, we are retrieving national used-vehicle totals for each month from August 2025 through July 2026:

request.js
import axios from 'axios';

const options = {
method: 'GET',
url: 'https://api.marketcheck.com/v2/sold-vehicles/summary',
params: {
api_key: 'YOUR_API_KEY',
summary_by: 'national',
inventory_type: 'used',
ranking_dimensions: 'none',
date_from: '2025-08-01',
date_to: '2026-07-31'
},
headers: {Accept: 'application/json'}
};

try {
const { data } = await axios.request(options);
console.log(data);
} catch (error) {
console.error(error);
}

Find Where a Make Sells Below MSRP

Find the states where a make sells below MSRP. Use price_over_msrp_percentage=%3C0 to keep only groups that sold below MSRP on average, and min_sold_count to remove groups with too few sales to compare.

Example:

Here in this example, we are finding the states where new Nissans sold below MSRP on average in July 2026, with at least 50 sales:

request.js
import axios from 'axios';

const options = {
method: 'GET',
url: 'https://api.marketcheck.com/v2/sold-vehicles/summary',
params: {
api_key: 'YOUR_API_KEY',
summary_by: 'state',
make: 'Nissan',
inventory_type: 'new',
ranking_dimensions: 'none',
price_over_msrp_percentage: '<0',
min_sold_count: '50',
date_from: '2026-07-01',
date_to: '2026-07-31'
},
headers: {Accept: 'application/json'}
};

try {
const { data } = await axios.request(options);
console.log(data);
} catch (error) {
console.error(error);
}

Rank Models by Median Price

Rank models by a percentile instead of a count, for example with ranking_measure=price.p50 to find the highest-priced models. Pair it with min_sold_count and rank_after_filters=true to keep small groups out of the ranking.

Example:

Here in this example, we are ranking the top 8 used models nationally by median price in July 2026, keeping only models with at least 250 sales:

request.js
import axios from 'axios';

const options = {
method: 'GET',
url: 'https://api.marketcheck.com/v2/sold-vehicles/summary',
params: {
api_key: 'YOUR_API_KEY',
summary_by: 'national',
inventory_type: 'used',
ranking_dimensions: 'make,model',
ranking_measure: 'price.p50',
ranking_order: 'desc',
min_sold_count: '250',
rank_after_filters: 'true',
top_n: '8',
date_from: '2026-07-01',
date_to: '2026-07-31'
},
headers: {Accept: 'application/json'}
};

try {
const { data } = await axios.request(options);
console.log(data);
} catch (error) {
console.error(error);
}

Rank Dealership Groups by Sales

Rank dealership groups to compare their sales volume in a region. Use ranking_dimensions=dealership_group_name. Rows without a dealership group are excluded, and the response includes a sparse_dimension_rows_excluded warning.

Example:

Here in this example, we are ranking the top 10 dealership groups by used-vehicle sales in each of Illinois, Indiana, and Wisconsin in July 2026:

request.js
import axios from 'axios';

const options = {
method: 'GET',
url: 'https://api.marketcheck.com/v2/sold-vehicles/summary',
params: {
api_key: 'YOUR_API_KEY',
summary_by: 'state',
state: 'IL,IN,WI',
inventory_type: 'used',
ranking_dimensions: 'dealership_group_name',
ranking_measure: 'sold_count',
top_n: '10',
date_from: '2026-07-01',
date_to: '2026-07-31'
},
headers: {Accept: 'application/json'}
};

try {
const { data } = await axios.request(options);
console.log(data);
} catch (error) {
console.error(error);
}

Compare Specific Dealership Groups

Compare named dealership groups by passing their names as dealership_group_name and ranking by dealership_group_name. Each row describes one dealership group, so you can compare their volume, prices, and days on market side by side.

Example:

Here in this example, we are comparing used-vehicle sales for six dealership groups nationally in July 2026:

request.js
import axios from 'axios';

const options = {
method: 'GET',
url: 'https://api.marketcheck.com/v2/sold-vehicles/summary',
params: {
api_key: 'YOUR_API_KEY',
summary_by: 'national',
dealership_group_name: 'AutoNation Inc.,Lithia Motors Inc.,Penske Automotive Group Inc.,Group 1 Automotive Inc.,Asbury Automotive Group,Sonic Automotive Inc.',
ranking_dimensions: 'dealership_group_name',
inventory_type: 'used',
top_n: '10',
date_from: '2026-07-01',
date_to: '2026-07-31'
},
headers: {Accept: 'application/json'}
};

try {
const { data } = await axios.request(options);
console.log(data);
} catch (error) {
console.error(error);
}

Compare New and Used Sales

Compare new and used sales in one request with inventory_type=all and inventory_type in ranking_dimensions. Each row then describes one inventory type, so means and percentiles stay accurate and no pooled_populations warning is returned. New and used groups are ranked together, so the top ranks can mix both. To rank each inventory type separately, send one request per type.

Example:

Here in this example, we are comparing new and used sales for four dealership groups nationally in July 2026:

request.js
import axios from 'axios';

const options = {
method: 'GET',
url: 'https://api.marketcheck.com/v2/sold-vehicles/summary',
params: {
api_key: 'YOUR_API_KEY',
summary_by: 'national',
dealership_group_name: 'AutoNation Inc.,Lithia Motors Inc.,Penske Automotive Group Inc.,Group 1 Automotive Inc.',
ranking_dimensions: 'inventory_type,dealership_group_name',
inventory_type: 'all',
top_n: '20',
date_from: '2026-07-01',
date_to: '2026-07-31'
},
headers: {Accept: 'application/json'}
};

try {
const { data } = await axios.request(options);
console.log(data);
} catch (error) {
console.error(error);
}

Performance Considerations

Request time grows with the width of the date window, not with the size of the result. Twelve-month requests can take tens of seconds, while single-month requests return faster.

Optimal Request Patterns

  1. Narrow the date window first - limit and top_n reduce the response size, not the request time
  2. Set a generous client timeout - twelve-month requests can take tens of seconds. See Request Timeout for the gateway limit
  3. Cache long series - the data changes monthly, so you can reuse a series instead of requesting it again

See Also