Skip to content
API reference / Market & demandView Markdown ↗
Beta

AutoUncle Data Services is in beta. The API, MCP tools and agent skill may change often, including breaking changes, until version 1.0. Read the changelog before you upgrade an integration.

Market & demand

Understand the market for a car type in one country: how many are on sale, what they cost, how fast listings leave the market, how long that takes, whether the type moves faster or slower than the market as a whole, and how that has changed over the last 12 months. Field tables on this page are generated from the OpenAPI contract.

Endpoint MCP tool Answers
POST /v1/market get_market How big and how fast the market for a car type is
POST /v1/selling-times forecast_selling_time How long one specific car takes to sell at each price level. See selling-time forecasts

Use both together: POST /v1/market for the type (a 2019 Volvo XC60 diesel automatic), then POST /v1/selling-times for the one car you are pricing.

What the figures are

Every figure is an aggregate over the listings AutoUncle tracks in the requested market, never a single listing.

  • Listings, not registrations. The counts describe the listings AutoUncle tracks, not every car registered or sold.
  • Left the market is not always a sale. A listing that left the market was removed from sale, which is usually, but not always, a sale. Its price is the last asking price, not a transaction price.
  • The same segment as the similar-cars link. The segment is the search behind a valuation's similar_cars_url, and segment.similar_cars_url opens it on the market's own AutoUncle site. It is make and model plus whatever you send that narrows it. A model year gives that year and one either side, kept within the model generation; in Germany and Italy it gives the exact year. Mileage narrows the segment only in Germany and Italy. Fuel, gearbox and body narrow it too.
  • Small numbers are withheld. A figure built from fewer than 10 listings is left out, and suppressed says which block or month. Prices are rounded to three significant figures and mileage to 1,000 km or mi (100 Scandinavian mil), so no listing can be picked out.
  • Freshness. On-sale and left-the-market figures can be up to three hours old, because they come from a shared cache. as_of says when the request read them.
Block What it says Window
supply Listings on sale now: the count, asking price and mileage (5th percentile, median, 95th percentile), model years, the share in each price rating, the share whose price has been lowered and the most listed equipment variants Now
flow Listings that left the market per day, and listings that went on sale in the window and are still on sale, per day Last 30 days
turnover Median and mean days from going on sale to leaving the market Last 60 days
demand Days of supply, turnovers per year, and the level against the whole market Now and the last 30 days
trend Per month: listings that left the market, median days to leave and median last asking price Last 12 complete months

Demand measures

  • days_of_supply = listings on sale ÷ listings leaving the market per day. It is how long today's stock would last at the current pace.
  • turnovers_per_year = 12 × listings that left in 30 days ÷ listings on sale.
  • relative_to_market = the segment's days_of_supply ÷ the same measure for the market's whole used-car stock. Below 1 the type moves faster than the market.
  • level is high when relative_to_market is below 0.8, low above 1.25, and average in between. Comparing with the market itself keeps the level meaningful across countries, and it cancels most of the effect of listings removed for reasons other than a sale.

flow.new_listings_still_on_sale_per_day counts only listings that are still on sale. A listing that went on sale and left within the window is not in it. So it is not total inflow, and subtracting left_market_per_day from it does not give a net change.

Status and cost

status Means Live cost
measured Figures were published One credit
partial A data store could not answer, so some blocks are null; warnings says which (market_supply_unavailable, market_flow_unavailable, market_trend_unavailable, market_baseline_unavailable) Free; request it again
insufficient_data Too few listings match, so every figure was withheld Free

Test keys return deterministic example figures (synthetic: true) for free. Nothing is stored: a replay with the same Idempotency-Key reads the market again without spending a credit, and there is no read-back endpoint. See credits.

POST /v1/market

Market and demand figures for a car type.

Describes the market for a car type in one country: how many are on sale and at what prices and mileages, the price-rating mix, how fast listings arrive and leave the market, how long they take to leave, days of supply and a demand level relative to the whole market, and a 12-month trend of listings leaving the market. Send the same vehicle input as a valuation; at least a make and model must be recognised, and model year, mileage, fuel, gearbox and body narrow the segment exactly as the valuation's similar_cars_url does. Every figure is an aggregate over the listings AutoUncle tracks in that market (not registrations or confirmed sales); left the market means removed from sale. A figure built from fewer than 10 listings is withheld and listed in suppressed. One credit for a measured live result; partial and insufficient_data results, refusals, failures, idempotent replays and test keys are free. Needs the valuations:write scope and shares the valuation rate and concurrency limits. Nothing is stored: a replay with the same Idempotency-Key reads the market again without spending a credit.

Nothing is stored: a replay with the same Idempotency-Key reads the market again without spending a credit, and there is no read-back endpoint. Counts against the valuation rate limit and needs a valuation concurrency slot, like POST /v1/valuations.

  • Scope: valuations:write
  • Cost: One credit for a measured live result. partial and insufficient_data results, test keys, refusals, failures and idempotent replays are free.
  • Rate limit: valuations bucket, default 60 requests per minute. See limits.

Parameters

Name In Type Required Description
Idempotency-Key header string No Workspace- and mode-scoped retry key. A replay of a finished request spends no credit. 1 to 200 characters.

Request body

application/json, a MarketRequest: A car type in one market: the same vehicle input as a valuation (a VehicleInput, a description or photos), of which at least a make and model must be recognised. Mileage and model year are optional and only narrow the segment as the similar-cars link does. Pricing does not apply. Unknown fields are rejected.

Field Type Description
country required string Market as an ISO 3166-1 alpha-2 code, such as DK, DE or GB. Every figure comes from that market's own listings only. 2 to 10 characters.
vehicle VehicleInput The vehicle, as a VehicleInput: an AVS vehicle document (any vehicle an endpoint returned, posted back unchanged) or the vehicle's attributes as a listing gives them.
description string Unstructured listing text describing the vehicle. Existing parsers and deployment-configured optional AI can propose attributes; the response identifies assumptions and unresolved inputs. 1 to 20000 characters.
images array Up to eight vehicle photos, each supplied by HTTPS URL or inline base64 data, to identify the car type. AI image resolution is deployment-configured and never runs for test keys. Photos cost nothing extra on a market request. At most 8 items.
images[].url string (uri) Public HTTPS image URL on port 443, without credentials or fragments. Private network destinations and redirects are rejected. Remote images must be supported image types and at most 8 MB each. At most 2048 characters.
images[].data string Strict base64-encoded image bytes, without a data-URL prefix. Inline data must also fit the total 1 MB API request limit. At most 1000000 characters.
images[].media_type string MIME type for inline image bytes: image/jpeg, image/png, image/webp or image/gif. The actual image signature is checked. At most 100 characters.
options object How the vehicle is resolved.
options.resolution string auto uses deterministic resolution and optional configured AI; no_ai and strict use deterministic resolution only. One of auto, no_ai, strict.

Structured example:

{
  "country": "SE",
  "vehicle": {
    "make": "Volvo",
    "model": "XC60",
    "model_year": 2019,
    "fuel": "diesel",
    "transmission": "automatic"
  }
}

Text example:

{
  "country": "DE",
  "description": "VW Golf 1.5 TSI 2020"
}

Response

application/json, a MarketResponse: Market & demand figures for a car type in one market: aggregates over the listings AutoUncle tracks there, never a listing. Errors return a Problem as application/problem+json.

Field Type Description
request_id string The request's ID, shown in the console request log. Pattern ^mkt_[A-Za-z0-9]+$.
object string Always market. One of market.
status string measured: figures were published; one credit on a live key. partial: a data store could not answer, so some figures are missing (see warnings); not charged. insufficient_data: every figure was withheld because too few listings match; not charged. One of measured, partial, insufficient_data.
country string Market as an ISO 3166-1 alpha-2 code, normalized from your request (for example SE). Pattern ^[A-Z]{2}$.
mode string test for a test key (synthetic figures) or live for a live key. One of live, test.
synthetic boolean True for test keys: deterministic example figures, no market data.
vehicle Vehicle The identified vehicle. An AVS vehicle document; left out when the vehicle could not be identified to a brand and a model, with the reason in identification.
identification VehicleIdentification How the vehicle was identified: status, depth, candidates and the provenance of every value in vehicle.
segment object The listings the figures describe.
segment.criteria required object What a listing must match to be in the segment, in the public vocabulary. Null means not restricted.
segment.criteria.make required string Make every listing in the segment has.
segment.criteria.model required string Model every listing in the segment has.
segment.criteria.model_year required object or null Model years the segment covers. Null when not restricted.
segment.criteria.model_year.from required integer or null Earliest model year.
segment.criteria.model_year.to required integer or null Latest model year.
segment.criteria.mileage required object or null Mileage band the segment covers (Germany and Italy only, when you send a mileage). Null when not restricted.
segment.criteria.mileage.from required integer or null Lowest mileage.
segment.criteria.mileage.to required integer or null Highest mileage.
segment.criteria.mileage.unit required string km, mi or mil (Scandinavian mil). One of km, mi, mil.
segment.criteria.fuel required string or null Fuel every listing has. Null when not restricted.
segment.criteria.transmission required string or null automatic or manual when the gearbox is restricted, otherwise null. One of automatic, manual.
segment.criteria.body required string or null Body type every listing has. Null when not restricted.
segment.criteria.engine_size_l required number or null Engine size in litres every listing has. Null when not restricted.
segment.similar_cars_url required string or null (uri) The same segment as a search on the market's own AutoUncle site.
as_of string (date-time) When the figures were read. On-sale and left-the-market figures can be up to three hours old (shared cache).
supply object or null Listings on sale now. Null when those figures could not be read (market_supply_unavailable warning).
supply.on_sale required integer or null Listings on sale now in the segment. Null when fewer than 10, with on_sale_band set. Minimum 0.
supply.on_sale_band required string or null fewer_than_10 when the count is withheld; every other supply figure is then left out. One of fewer_than_10.
supply.price object Asking prices of the listings on sale.
supply.price.p5 required integer or null 5th percentile asking price, rounded to three significant figures. Minimum 0.
supply.price.median required integer or null Median asking price, rounded to three significant figures. Minimum 0.
supply.price.p95 required integer or null 95th percentile asking price, rounded to three significant figures. Minimum 0.
supply.price.currency required string ISO 4217 currency of the market. Pattern ^[A-Z]{3}$.
supply.mileage object Mileage of the listings on sale, in the market's unit.
supply.mileage.p5 required integer or null 5th percentile mileage, rounded to 1,000 km or mi (100 Scandinavian mil). Minimum 0.
supply.mileage.median required integer or null Median mileage, rounded the same way. Minimum 0.
supply.mileage.p95 required integer or null 95th percentile mileage, rounded the same way. Minimum 0.
supply.mileage.unit required string km, mi or mil (Scandinavian mil): the market's unit. One of km, mi, mil.
supply.model_years object or null Model years of the listings on sale. Null when the store returned none.
supply.model_years.most_common required integer or null The most listed model year. Minimum 1900.
supply.model_years.from required integer or null Earliest model year of all but the outer 2% of listings. Minimum 1900.
supply.model_years.to required integer or null Latest model year of all but the outer 2% of listings. Minimum 1900.
supply.price_ratings object Share of listings on sale in each AutoUncle price rating (5 is super price, 1 is expensive), to two decimals.
supply.price_ratings.5 required number or null Share of listings on sale with price rating 5. 0 to 1.
supply.price_ratings.4 required number or null Share of listings on sale with price rating 4. 0 to 1.
supply.price_ratings.3 required number or null Share of listings on sale with price rating 3. 0 to 1.
supply.price_ratings.2 required number or null Share of listings on sale with price rating 2. 0 to 1.
supply.price_ratings.1 required number or null Share of listings on sale with price rating 1. 0 to 1.
supply.price_ratings.unrated required number or null Share of listings on sale without a price rating. 0 to 1.
supply.share_with_price_drop number or null Share of listings on sale whose asking price has been lowered. 0 to 1.
supply.top_equipment_variants array The three most listed equipment-variant names, most listed first. At most 3 items.
flow object or null Pace over the last 30 days. Null when withheld (fewer than 10 listings left the market in the window) or unavailable.
flow.window_days required integer Days the per-day rates are averaged over. Always 30.
flow.left_market_per_day required number or null Listings that left the market per day over the window (on sale at least one day). Left the market means removed from sale, usually but not always a sale. Minimum 0.
flow.new_listings_still_on_sale_per_day required number or null Listings that went on sale within the window and are still on sale, per day. Listings that came and went within the window are not counted, so this is not total inflow. Minimum 0.
turnover object or null How long listings of this type take to leave the market. Null when withheld or unavailable.
turnover.window_days required integer Days back the listings that left the market are taken from. Always 60.
turnover.median_days_to_leave required integer or null Median days from going on sale to leaving the market, for listings that left in the window. Minimum 0.
turnover.mean_days_to_leave required integer or null Mean of the same. Minimum 0.
demand object or null Derived demand measures. Null when on_sale or flow is withheld or unavailable.
demand.days_of_supply required integer or null Listings on sale ÷ listings leaving the market per day: how long today's stock lasts at the current pace. Minimum 0.
demand.turnovers_per_year required number or null 12 × listings that left in 30 days ÷ listings on sale. Minimum 0.
demand.relative_to_market required number or null days_of_supply ÷ the same measure for the market's whole used-car stock. Below 1 the type moves faster than the market. Minimum 0.
demand.level required string or null high below 0.8 relative_to_market, low above 1.25, otherwise average. Null when the whole market's figures could not be read. One of high, average, low.
trend object or null The last 12 complete months of listings that left the market. Null when it could not be read (market_trend_unavailable warning).
trend.months required integer Complete calendar months in series: 12, or fewer where the store holds less history. 0 to 12.
trend.currency required string ISO 4217 currency of median_last_asking_price. Pattern ^[A-Z]{3}$.
trend.series required array Oldest month first. At most 12 items.
trend.series[].month required string Calendar month as YYYY-MM. Pattern ^[0-9]{4}-[0-9]{2}$.
trend.series[].left_market required integer or null Listings that left the market that month (on sale at least one day). Minimum 0.
trend.series[].median_days_to_leave required integer or null Median days from going on sale to leaving the market. Minimum 0.
trend.series[].median_last_asking_price required integer or null Median last asking price before leaving the market, rounded to three significant figures. Not a transaction price. Minimum 0.
trend.series[].suppressed required boolean True when fewer than 10 listings left the market that month; its figures are then null.
trend.current_month required object The month in progress, which is never in series.
trend.current_month.month required string The month in progress, as YYYY-MM. Pattern ^[0-9]{4}-[0-9]{2}$.
trend.current_month.partial required boolean Always true: the month in progress is never in series.
suppressed array Every block or trend month withheld because it would be built from fewer than 10 listings.
suppressed[].section required string supply, flow, turnover, demand or trend. One of supply, flow, turnover, demand, trend.
suppressed[].month string For trend, the month withheld, as YYYY-MM. Pattern ^[0-9]{4}-[0-9]{2}$.
suppressed[].reason required string Why it was withheld. Always fewer_than_10_listings. One of fewer_than_10_listings.
warnings array Problems with this request, for example market_flow_unavailable (status partial) or model_not_recognized. Match on code.
warnings[].code required string Stable machine-readable warning code. Pattern ^[a-z][a-z0-9_]*$.
warnings[].message required string Plain-language explanation.
usage object Billing for this call.
usage.billable required boolean true when this result captured a credit (status measured on a live key).
usage.credits_used required integer Credits this call consumed. Always 0 on an idempotent replay. 0 to 1.
usage.original_credits_used required integer Credits the original request consumed (0 or 1), also on a replay. 0 to 1.
usage.charges required object What original_credits_used paid for. Empty when nothing was charged.
usage.charges.base integer The market figures, 1 credit. Minimum 1.
usage.credits_remaining required integer Workspace credits left after this call. Minimum 0.
usage.cache_hit required boolean Reserved. Always false in this version.
usage.idempotent_replay required boolean true when the same Idempotency-Key and body were sent before; the market is read again for free.
usage.mode required string test or live. One of live, test.
notes Note array Standing limitations and notices, including market_figures_describe_listings. Always present.
attributions Attribution array Data sources that contributed to this result. Always present.

Response headers

Header Description
X-Request-Id The HTTP request ID, on every response. Use it to correlate one HTTP exchange in proxy and application logs; it echoes a valid X-Request-Id you send. It is not the valuation ID.
Retry-After Seconds to wait before retrying.

Errors

Code HTTP Retryable Meaning
invalid_request 400 No Send a request matching the documented schema.
country_required 400 No Include country, the valuation market, in the request.
unsupported_country 400 No Choose a supported ISO country code.
unauthenticated 401 No Supply an API key as a Bearer token.
invalid_api_key 401 No Supply a valid AutoUncle Data Services API key.
key_revoked 401 No This key has expired or been revoked. Create a new key.
insufficient_credits 402 No The organization has no credits available. Contact sales for a package.
key_spend_limit_reached 402 No This API key has reached its monthly credit limit.
insufficient_scope 403 No Use a key with the required scope.
country_not_enabled 403 No This country is not enabled for this organization or key.
organization_pending 403 No This workspace is waiting for AutoUncle to approve it.
organization_suspended 403 No This organization is inactive. Contact support.
unknown_catalogue_id 404 No The catalogue ID is unknown. Fetch current IDs from the catalogue API.
idempotency_conflict 409 No This idempotency key was used with different input. Choose a new key.
request_in_progress 409 Yes A request with this idempotency key is still running. Retry later with the same key.
payload_too_large 413 No The request exceeds the maximum supported size of 1 MB.
vehicle_not_identified 422 No Provide more vehicle attributes or select catalogue IDs.
catalogue_id_conflict 422 No The catalogue IDs do not describe the same vehicle hierarchy.
vehicle_out_of_range 422 No The vehicle is outside the supported valuation range.
images_unreadable 422 No Provide readable supported images.
rate_limited 429 Yes The request rate limit was reached. Retry after the current minute.
test_limit_reached 429 Yes This workspace has used its fair-use allowance of test-key requests for now.
concurrency_limited 429 Yes Too many valuations are running at the same time for this organization.
rate_limit_unavailable 503 Yes Request limiting is temporarily unavailable. Retry later.
engine_busy 503 Yes The valuation engine is at capacity. Retry after a short delay.
request_timeout 504 Yes The valuation request exhausted its processing time budget.
resolution_timeout 504 Yes Vehicle interpretation did not finish within its time budget.
resolution_unavailable 503 Yes Vehicle interpretation is temporarily unavailable.
resolution_invalid_response 502 Yes Vehicle interpretation returned an invalid response.
image_timeout 504 Yes Image retrieval did not finish within its time budget.
image_unavailable 503 Yes The image service is temporarily unavailable.
image_invalid_response 502 Yes The image service returned an invalid response.
market_data_unavailable 503 Yes Market figures are temporarily unavailable.
internal_error 500 No The valuation could not be completed. Contact support with the request ID.

Examples

curl https://data-services.autouncle.com/v1/market \
  -H "Authorization: Bearer $AUTOUNCLE_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: market-001' \
  -d @- <<'JSON'
{
  "country": "SE",
  "vehicle": {
    "make": "Volvo",
    "model": "XC60",
    "model_year": 2019,
    "fuel": "diesel",
    "transmission": "automatic"
  }
}
JSON