{"openapi":"3.0.3","info":{"title":"Cars API","version":"1.1.0","description":"Public vehicle API. Authenticate with api_key in the query and send Accept: application/json. On this documentation page the single API-key field also authorizes Swagger. Source IDs are account-specific: load /domains first. Schemas describe the backend response contract; examples alone are synthetic, use placeholder credentials and do not promise live inventory. Internal car IDs, source listing IDs, brand IDs and domain IDs are different identifiers. Missing/null values are not zero or false. Use the schemas and endpoint-specific error examples below."},"servers":[{"url":"https://api.auctionsapi.com","description":"Current API"}],"security":[{"ApiKeyAuth":[]}],"tags":[{"name":"Vehicles","description":"Search and exact vehicle lookups"},{"name":"Export","description":"Full inventory synchronization"},{"name":"Dictionaries","description":"Source IDs, brands, models, locations and equipment"}],"paths":{"/search":{"get":{"operationId":"search","tags":["Vehicles"],"summary":"Search vehicles","description":"Search active vehicles in enabled sources. Filters select matching cars; inspect listings[].external.domain.id when choosing a source. Full inspection/history report arrays are omitted here. Use /cars for exports beyond the 10,000-result search window. An empty result is HTTP 200. Current pagination implementation fetches perPage + 1 records without trimming the extra hit, so data can contain one more car than perPage while metadata uses perPage. To avoid the search engine window boundary, keep page × perPage + 1 ≤ 10000. meta.total can stop at 10000 because the search engine does not track all matches. A value of 10000 is a lower bound, not a reliable inventory size; meta.last_page is based on that value. This is separate from the pagination window limit. Use /search/count with the same filters and domain scope for an exact count.\n\nVehicle filters apply identically to /search, /search/count and /cars. Omitted vehicle_type means automobile/1 (including old cars without a stored type); motorcycle/2 selects motorcycles. This is a root car filter, independent of source/listing access. Use matching types in all dictionaries. Exact ID/VIN/listing lookups keep their existing behavior and do not accept these filters.\n\nThe hierarchy is brands[] → models[] → generations[] → variants[] and trims[]. Legacy integer models[] remain supported; structured model objects require id and optional generations. Brand and generation objects also require id. Siblings at each level are OR alternatives; selected parent IDs and variant/trim constraints inside one branch are AND. Variant and trim lists each use OR. Omitted or empty children mean no descendant restriction. A root car must match one complete branch, so choices under different models/generations never mix. To request exact variant/trim pairs, repeat the same generation in separate branches, each with its own single variant and trim; branches are never merged into a cross product. Every array is limited to 100 entries. Positive unknown IDs or incompatible parent/child combinations return zero matches; malformed values return 422. A child without its own parent id is invalid. Filters use stored numeric root IDs only: cars without normalized generation/variant/trim IDs cannot match those selections. No name inference or catalogue join is performed.\n\nPHP query syntax: brands[0][id]=101&brands[0][models][0][id]=201&brands[0][models][0][generations][0][id]=301&brands[0][models][0][generations][0][variants][]=501&brands[0][models][0][generations][0][trims][]=401. IDs are synthetic; take real IDs from dictionaries. Never send the legacy models[] append syntax and structured models[0] together for the same brand: both target PHP index 0. Prefer structured objects for every model when using the extended hierarchy.\n\nFor /cars, type and the complete brand hierarchy are fixed when the scroll starts and are preserved in next_url. Continuing with scroll_id alone retains them; repeating equivalent values/order is allowed. Changing either filter returns 422. Explicit vehicle filters also return 422 if cached filter state is lost or the scroll predates these filters: start a new scroll. Old scrolls continued without new parameters keep their original Elasticsearch query. New response fields vehicle_type, generation_id, variant_id and trim_id expose the stored selection; missing optional IDs are null. These additive response fields participate in hash.\n\nAdditional listing fields are discovered with authenticated GET /listing-fields, optionally narrowed by domains[]. The catalogue is private to the key and enabled domains. Never hardcode field keys or types from examples. Only filterable=true definitions can be filtered; operators and constraints come from the catalogue. Keys are flat, with one global type and optional homogeneous array cardinality. JSON objects are stored-only.\n\nUse custom_fields[key][eq]=value, custom_fields[key][in][]=value or custom_fields[key][exists]=true/false. Numbers and dates additionally support gt/gte/lt/lte. Boolean eq=false means the exact false value, not absence. For arrays a matching element satisfies a comparison. Use eq, in or a non-conflicting lower/upper range; exists is standalone. Maximum 20 fields, 100 values per in. Monetary comparisons require custom_fields[key][currency]=cad (the listing native currency); there is no conversion. These conditions, domain access/selection, activity and other listing constraints must match the same nested listing, preventing matches across different ads of one car. A response may still contain other visible listings.\n\nUnknown or unavailable fields, unsupported operators and invalid values return 422; unavailable catalogue returns 503. Stored-only values remain in listings[].source_data; indexed values appear in listings[].custom_fields for that listing/domain. Preserve 0, false and arrays; missing/null means no indexed value. Existing source_data is unchanged, including vhr_url. Newly published fields populate on subsequent normal imports, without historical backfill. Sorting and aggregations are not supported in this stage. /cars pins the normalized conditions and field contract for the cursor: follow next_url unchanged or scroll_id alone; changing conditions or an incompatible/missing contract requires a new scroll (422).\n\nEvery listing includes location_details with the same country/region/district/place shape. country is {id, name, iso}; other components are {id, name}. Missing components are null. Names use lang with dictionary fallbacks; unresolved IDs retain their ID with name:null. Existing textual source labels have id:null. The legacy location field retains its endpoint-specific format for compatibility. All visible listing IDs are collected from the complete response batch before bulk dictionary lookup (up to 1000 unique documents per request across both country and location indexes), never one request per car. Read location_details directly for display; /countries and /locations remain available for selectors and independent lookup. No city or parent is inferred from coordinates. /cars next_url preserves the effective lang across scroll pages. location_details participates in the car hash.","parameters":[{"name":"vin","in":"query","required":false,"description":"Case-insensitive partial VIN. For an exact 16–19 character VIN, use /cars/vin/{vin}.","schema":{"type":"string","minLength":1,"maxLength":19,"pattern":"^[A-Za-z0-9]+$"}},{"name":"page","in":"query","required":false,"description":"Page number. For /search, explicitly pass perPage and keep page × perPage ≤ 10000. /search/count ignores pagination and skips this offset check.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"perPage","in":"query","required":false,"description":"Search page size: minimum 2, maximum 50. perPage=1 returns 422; use perPage=2 to fetch a small sample. Omitted or null pagination values use page=1 and perPage=50, including the search result-window check. Invalid values return 422.","schema":{"type":"integer","minimum":2,"maximum":50,"default":50}},{"name":"sort","in":"query","required":false,"description":"Sort order. Price sorting requires a resolved currency. auction_nearest selects only cars with an active listing in an enabled/selected domain with auction_at >= now; past dates do not participate in sorting. Pass the same sort to /search/count for a matching count.","schema":{"type":"string","enum":["newest","oldest","cheaper","expensive","odometer_asc","odometer_desc","year_asc","year_desc","auction_nearest"]}},{"name":"currency","in":"query","required":false,"description":"Case-insensitive currency code for price filtering/sorting. Must exist in the currency dictionary. Does not convert serialized listing prices.","schema":{"type":"string","minLength":3,"maxLength":3,"pattern":"^[A-Za-z]{3}$","default":"usd"}},{"name":"currency_id","in":"query","required":false,"description":"Optional internal currency ID; overrides currency.","schema":{"type":"integer","minimum":1}},{"name":"domains[]","in":"query","required":false,"description":"Optional source scope. Use IDs returned by GET /domains. Omit to use all enabled domains. Repeat the bracketed parameter: domains[]=33&domains[]=34. Every ID must be enabled for this key.","schema":{"type":"array","minItems":1,"uniqueItems":true,"items":{"type":"integer","minimum":1}},"style":"form","explode":true,"x-autofill":"domains"},{"name":"is_leasing","in":"query","required":false,"description":"Optional leasing filter. Send true (or 1) for listings explicitly marked is_leasing=true. Send false (or 0) to exclude true, including stored false, null and missing fields. Omit for no leasing filter; empty or invalid values return 422. A car must have at least one matching active listing in the enabled/selected domain scope. Other listings can remain in the response, so cars with mixed listing types can match both values. For /cars, set this on the first request and follow next_url unchanged; false is preserved. Continuing with only scroll_id retains the filter. Changing or adding the filter mid-scroll returns 422. If cached filter state is lost or the scroll predates this parameter, an explicit value returns 422; start a new scroll.","schema":{"type":"boolean"},"examples":{"leasing":{"summary":"Only leasing listings","value":true},"nonLeasing":{"summary":"Exclude leasing, including missing flags","value":false}}},{"name":"is_auction","in":"query","required":false,"description":"Optional auction filter. Send true (or 1) for listings explicitly marked is_auction=true. Send false (or 0) to exclude true, including stored false, null and missing fields. Omit for no auction filter; empty or invalid values return 422. Combined is_auction and is_leasing must match the same listing. A car must have at least one matching active listing in the enabled/selected domain scope. Other listings can remain in the response, so cars with mixed listing types can match both values. For /cars, set this on the first request and follow next_url unchanged; false is preserved. Continuing with only scroll_id retains the filter. Changing or adding the filter mid-scroll returns 422. If cached filter state is lost or the scroll predates this parameter, an explicit value returns 422; start a new scroll.","schema":{"type":"boolean"},"examples":{"auction":{"summary":"Only auction listings","value":true},"nonAuction":{"summary":"Exclude auction, including missing flags","value":false}}},{"name":"seats","in":"query","required":false,"description":"Exact seating capacity.","schema":{"type":"integer","minimum":1,"maximum":200}},{"name":"price_from","in":"query","required":false,"description":"Minimum listing price in the selected currency. Maximum 9223372036854775807 (signed 64-bit integer); values beyond JavaScript safe integers must be preserved as decimal text by clients.","schema":{"type":"integer","minimum":0,"format":"int64"}},{"name":"price_to","in":"query","required":false,"description":"Maximum listing price in the selected currency. Maximum 9223372036854775807 (signed 64-bit integer); values beyond JavaScript safe integers must be preserved as decimal text by clients.","schema":{"type":"integer","minimum":1,"format":"int64"}},{"name":"year_from","in":"query","required":false,"description":"Minimum production year.","schema":{"type":"integer","minimum":1800,"maximum":3000}},{"name":"year_to","in":"query","required":false,"description":"Maximum production year.","schema":{"type":"integer","minimum":1800,"maximum":3000}},{"name":"odometer_from","in":"query","required":false,"description":"Minimum mileage in kilometres.","schema":{"type":"integer","minimum":0,"maximum":999999999}},{"name":"odometer_to","in":"query","required":false,"description":"Maximum mileage in kilometres.","schema":{"type":"integer","minimum":0,"maximum":999999999}},{"name":"engine_volume_from","in":"query","required":false,"description":"Minimum engine displacement.","schema":{"type":"integer","minimum":0,"maximum":999999999}},{"name":"engine_volume_to","in":"query","required":false,"description":"Maximum engine displacement.","schema":{"type":"integer","minimum":0,"maximum":999999999}},{"name":"power_hp_from","in":"query","required":false,"description":"Minimum power in horsepower.","schema":{"type":"integer","minimum":0,"maximum":100000}},{"name":"power_hp_to","in":"query","required":false,"description":"Maximum power in horsepower.","schema":{"type":"integer","minimum":1,"maximum":100000}},{"name":"keys_available","in":"query","required":false,"description":"Listing has keys. Send 1 (true) or 0 (false). Omit for either value; strings \"true\"/\"false\" are rejected.","schema":{"type":"integer","enum":[0,1]}},{"name":"is_manufacturer_certified","in":"query","required":false,"description":"Listing is certified by the manufacturer or official dealer program. Send 1 (true) or 0 (false). Omit for either value; strings \"true\"/\"false\" are rejected.","schema":{"type":"integer","enum":[0,1]}},{"name":"has_inspections","in":"query","required":false,"description":"Root car has a public inspection. Send 1 (true) or 0 (false). Omit for either value; strings \"true\"/\"false\" are rejected.","schema":{"type":"integer","enum":[0,1]}},{"name":"has_history_reports","in":"query","required":false,"description":"A listing in the selected domain scope has a public history report. Send 1 (true) or 0 (false). Omit for either value; strings \"true\"/\"false\" are rejected.","schema":{"type":"integer","enum":[0,1]}},{"name":"body_types[]","in":"query","required":false,"description":"1 = sedan; 2 = wagon; 3 = coupe; 4 = pickup; 5 = suv; 6 = cabrio; 7 = van; 11 = hatchback; 12 = roadster; 13 = limousine; 20 = liftback; 22 = hearse; 27 = sport_car","schema":{"type":"array","items":{"type":"integer","enum":[1,2,3,4,5,6,7,11,12,13,20,22,27]}},"style":"form","explode":true},{"name":"colors[]","in":"query","required":false,"description":"1 = silver; 2 = purple; 3 = orange; 4 = green; 5 = red; 6 = gold; 8 = brown; 9 = grey; 10 = turquoise; 11 = blue; 12 = bronze; 13 = white; 14 = cream; 15 = black; 16 = yellow; 17 = beige; 18 = pink; 100 = two_colors","schema":{"type":"array","items":{"type":"integer","enum":[1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,17,18,100]}},"style":"form","explode":true},{"name":"fuels[]","in":"query","required":false,"description":"1 = diesel; 2 = electric; 3 = hybrid; 4 = gasoline; 5 = gas; 6 = flexible; 7 = hydrogen; 8 = ethanol","schema":{"type":"array","items":{"type":"integer","enum":[1,2,3,4,5,6,7,8]}},"style":"form","explode":true},{"name":"transmission","in":"query","required":false,"description":"1 = automatic; 2 = manual","schema":{"type":"integer","enum":[1,2]}},{"name":"seller_type","in":"query","required":false,"description":"1 = individual; 2 = dealer","schema":{"type":"integer","enum":[1,2]}},{"name":"steering_wheel_position","in":"query","required":false,"description":"1 = left; 2 = right","schema":{"type":"integer","enum":[1,2]}},{"name":"airbags","in":"query","required":false,"description":"1 = intact; 2 = deployed; 3 = missing","schema":{"type":"integer","enum":[1,2,3]}},{"name":"damages[]","in":"query","required":false,"description":"1 = side; 2 = theft; 3 = burn; 4 = electric; 5 = vandalized; 6 = water; 7 = top_roof; 8 = transmission; 9 = suspension; 10 = biohazard; 11 = cash_for_clunkers; 12 = repossession; 13 = rollover; 14 = all_over; 15 = engine; 16 = frame; 17 = front; 18 = rear; 19 = front_and_rear; 20 = hail; 21 = mechanical; 22 = minor_dents_scratches; 23 = vin; 24 = normal_wear; 25 = rejected_or_partial_repair; 26 = storm; 27 = stripped; 28 = undercarriage","schema":{"type":"array","items":{"type":"integer","enum":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28]}},"style":"form","explode":true},{"name":"conditions[]","in":"query","required":false,"description":"1 = used; 2 = new; 3 = damaged","schema":{"type":"array","items":{"type":"integer","enum":[1,2,3]}},"style":"form","explode":true},{"name":"availabilities[]","in":"query","required":false,"description":"1 = in_stock; 2 = in_transit; 3 = on_order","schema":{"type":"array","items":{"type":"integer","enum":[1,2,3]}},"style":"form","explode":true},{"name":"emissions[]","in":"query","required":false,"description":"1 = euro_1; 2 = euro_2; 3 = euro_3; 4 = euro_4; 5 = euro_5; 6 = euro_6; 7 = zev","schema":{"type":"array","items":{"type":"integer","enum":[1,2,3,4,5,6,7]}},"style":"form","explode":true},{"name":"drive_wheels[]","in":"query","required":false,"description":"1 = rear; 2 = front; 3 = all","schema":{"type":"array","items":{"type":"integer","enum":[1,2,3]}},"style":"form","explode":true},{"name":"vehicle_type","in":"query","required":false,"description":"Vehicle scope: automobile/1 (default), motorcycle/2. Missing stored type counts as automobile. Explicit empty or invalid values return 422. Keep this type in dictionary lookups and inventory requests. On /cars, set it on the first request and follow next_url unchanged; changing it mid-scroll or supplying it when cached state is unavailable returns 422.","schema":{"type":"string","enum":["automobile","motorcycle","1","2"],"default":"automobile"}},{"name":"interior_colors[]","in":"query","required":false,"description":"Interior color IDs from the colors dictionary. OR within the list; missing values do not match. Applies to /search, /search/count and /cars. Keep unchanged during scroll.","schema":{"type":"array","items":{"type":"integer","enum":[1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,17,18,100]},"maxItems":100,"uniqueItems":true},"style":"form","explode":true},{"name":"cylinders[]","in":"query","required":false,"description":"Exact cylinder counts (1–99), OR within the list; unknown counts do not match. Applies to /search, /search/count and /cars. Keep unchanged during scroll.","schema":{"type":"array","items":{"type":"integer","minimum":1,"maximum":99},"maxItems":99,"uniqueItems":true},"style":"form","explode":true},{"name":"brands[0][id]","in":"query","required":false,"description":"First brand ID from /brands for the selected vehicle_type. Additional brands use brands[1][id], etc. All sibling brands are OR alternatives.","schema":{"type":"integer","minimum":1},"x-autofill":"brands"},{"name":"brands[0][models][]","in":"query","required":false,"description":"Legacy model ID list for the first brand. Omit for all models. For generation/variant/trim filtering use structured models instead; clear this field before sending models[0][id] to avoid overwriting PHP index 0.","schema":{"type":"array","items":{"type":"integer","minimum":1},"maxItems":100},"style":"form","explode":true,"x-autofill":"models"},{"name":"brands[0][models][0][id]","in":"query","required":false,"description":"Structured model ID from /models/{brand_id}. Required on each model object. Do not combine this index with the legacy append syntax models[]. Additional models use models[1][id], etc.","schema":{"type":"integer","minimum":1}},{"name":"brands[0][models][0][generations][0][id]","in":"query","required":false,"description":"Generation ID from /generations/{model_id}. Required on each generation object. Omit generations or send an empty list to include every generation of this model. Additional generations use generations[1][id], etc.","schema":{"type":"integer","minimum":1}},{"name":"brands[0][models][0][generations][0][variants][]","in":"query","required":false,"description":"Optional variant IDs from /variants/{generation_id}, OR within the list. Omitted/empty means any variant. Intersected with this generation and its trims; missing stored variant_id does not match a selected ID.","schema":{"type":"array","items":{"type":"integer","minimum":1},"maxItems":100},"style":"form","explode":true},{"name":"brands[0][models][0][generations][0][trims][]","in":"query","required":false,"description":"Optional trim IDs from /trims/{generation_id}, OR within the list. Omitted/empty means any trim. Intersected with this generation and its variants; missing stored trim_id does not match a selected ID.","schema":{"type":"array","items":{"type":"integer","minimum":1},"maxItems":100},"style":"form","explode":true},{"name":"countries[0][id]","in":"query","required":false,"description":"First internal country ID from /countries. Additional countries use countries[1][id], etc.","schema":{"type":"integer"}},{"name":"countries[0][regions][]","in":"query","required":false,"description":"Optional internal region IDs belonging to the first country.","schema":{"type":"array","items":{"type":"integer"}},"style":"form","explode":true},{"name":"custom_fields","in":"query","required":false,"description":"Additional listing fields are discovered with authenticated GET /listing-fields, optionally narrowed by domains[]. The catalogue is private to the key and enabled domains. Never hardcode field keys or types from examples. Only filterable=true definitions can be filtered; operators and constraints come from the catalogue. Keys are flat, with one global type and optional homogeneous array cardinality. JSON objects are stored-only.\n\nUse custom_fields[key][eq]=value, custom_fields[key][in][]=value or custom_fields[key][exists]=true/false. Numbers and dates additionally support gt/gte/lt/lte. Boolean eq=false means the exact false value, not absence. For arrays a matching element satisfies a comparison. Use eq, in or a non-conflicting lower/upper range; exists is standalone. Maximum 20 fields, 100 values per in. Monetary comparisons require custom_fields[key][currency]=cad (the listing native currency); there is no conversion. These conditions, domain access/selection, activity and other listing constraints must match the same nested listing, preventing matches across different ads of one car. A response may still contain other visible listings.\n\nUnknown or unavailable fields, unsupported operators and invalid values return 422; unavailable catalogue returns 503. Stored-only values remain in listings[].source_data; indexed values appear in listings[].custom_fields for that listing/domain. Preserve 0, false and arrays; missing/null means no indexed value. Existing source_data is unchanged, including vhr_url. Newly published fields populate on subsequent normal imports, without historical backfill. Sorting and aggregations are not supported in this stage. /cars pins the normalized conditions and field contract for the cursor: follow next_url unchanged or scroll_id alone; changing conditions or an incompatible/missing contract requires a new scroll (422).","schema":{"type":"object","maxProperties":20,"additionalProperties":{"$ref":"#/components/schemas/ListingFieldCondition"}},"style":"deepObject","explode":true},{"name":"lang","in":"query","required":false,"description":"Response locale. Option translations are also limited by the account languages. The page selects its current language automatically.","schema":{"type":"string","enum":["en","ru","sq","pl","uk","bg"]}}],"responses":{"200":{"description":"Paginated cars with links and meta. Synthetic examples; real pagination links also preserve query parameters, including api_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CarPage"},"examples":{"vehicles":{"summary":"One matching vehicle","value":{"data":[{"id":"example-car-001","has_inspections":true,"has_history_reports":true,"year":2022,"vin":"EXAMPLEVIN00000001","brand":{"id":101,"name":"Example brand"},"model":{"id":201,"name":"Example model"},"vehicle_type":1,"generation_id":null,"variant_id":null,"trim_id":null,"seats":5,"doors":4,"cylinders":4,"steering_wheel_position":{"id":1,"name":"left"},"option_ids":[101],"listings":[{"external":{"id":"example-listing-001","domain":{"id":33,"name":"cars.example.com"},"url":"https://cars.example.com/listing/example-listing-001"},"archived":false,"title":{"en":"Example vehicle"},"odometer":32000,"location":{"iso":"DE","country":1,"position":{"lat":52.52,"lon":13.405}},"location_details":{"country":{"id":1,"name":"Germany","iso":"DE"},"region":null,"district":null,"place":null},"images":[{"original":"https://cars.example.com/images/example.jpg"}],"video":["https://cars.example.com/videos/example.mp4"],"created_at":"2026-09-01T10:00:00Z","last_seen_at":"2026-09-13T10:00:00Z","updated_at":"2026-09-13T10:00:00Z","price":{"price":25000,"currency":{"id":1,"name":"usd"},"negotiable":false,"history":[{"price":26000,"currency_id":1,"created_at":"2026-09-01T10:00:00Z"}]},"seller_type":null,"option_ids":[101],"is_auction":false,"current_bid":null,"auction_at":null,"availability":null,"is_manufacturer_certified":true,"has_history_reports":true,"condition":null,"keys_available":true,"damage":null,"second_damage":null,"airbag_state":null,"document_id":null}],"hash":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}],"links":{"first":"https://api.auctionsapi.com/search?page=1","last":"https://api.auctionsapi.com/search?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"&laquo; Previous","active":false},{"url":"https://api.auctionsapi.com/search?page=1","label":"1","active":true},{"url":null,"label":"Next &raquo;","active":false}],"path":"https://api.auctionsapi.com/search","per_page":50,"to":1,"total":1}}},"empty":{"summary":"No matches","value":{"data":[],"links":{"first":"https://api.auctionsapi.com/search?page=1","last":"https://api.auctionsapi.com/search?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":null,"last_page":1,"links":[{"url":null,"label":"&laquo; Previous","active":false},{"url":"https://api.auctionsapi.com/search?page=1","label":"1","active":true},{"url":null,"label":"Next &raquo;","active":false}],"path":"https://api.auctionsapi.com/search","per_page":50,"to":null,"total":0}}}}}}},"400":{"description":"Search engine rejected the query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rejected":{"summary":"Search query rejected; message depends on the engine","value":{"error":"search_phase_execution_exception"}}}}}},"403":{"description":"API key, subscription, source access or IP restriction. Correct the account/access condition before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missingKey":{"summary":"API key is missing","value":{"error":"please add your api_key in get param"}},"invalidKey":{"summary":"API key is invalid","value":{"error":"wrong api key"}},"expiredSubscription":{"summary":"Subscription has expired","value":{"error":"your api subscription has expired"}},"inactiveSubscription":{"summary":"Subscription is inactive","value":{"error":"your api subscription is not active"}},"ipNotAllowed":{"summary":"Request IP is not allowlisted","value":{"error":"ip address is not in whitelist","ip":"203.0.113.10"}},"noSources":{"summary":"Subscription has no enabled sources","value":{"error":"you don't have any data in your subscription"}}}}}},"404":{"description":"Service lookup failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"examples":{"missing":{"summary":"Referenced record not found","value":{"errors":{"id":["Not found"]}}}}}}},"422":{"description":"Invalid filter, currency, domain access or pagination. Correct the named fields. Validation messages can be localized.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"examples":{"vehicleType":{"summary":"Invalid vehicle type","value":{"errors":{"vehicle_type":["The selected vehicle type is invalid."]}}},"modelParent":{"summary":"Structured model is missing its ID","value":{"errors":{"brands.0.models.0.id":["The brands.0.models.0.id field is required."]}}},"perPageMinimum":{"summary":"Page size below 2","value":{"errors":{"perPage":["The per page field must be at least 2."]}}},"perPage":{"summary":"Page size exceeds 50","value":{"errors":{"perPage":["The per page field must not be greater than 50."]}}},"offset":{"summary":"Search result window exceeded","value":{"errors":{"offset":["Max num of offset is 10k"]}}},"currency":{"summary":"Unknown currency code","value":{"errors":{"currency":["currency is invalid"]}}},"domain":{"summary":"A selected domain is not enabled","value":{"errors":{"domains":["These domain IDs are not enabled for this API key: 999999"]}}},"leasing":{"summary":"Invalid leasing value","value":{"errors":{"is_leasing":["The is leasing field must be true or false."]}}}}}}},"503":{"description":"Search service is temporarily unavailable. Retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Search unavailable","value":{"error":"search service temporarily unavailable"}}}}},"headers":{"Retry-After":{"schema":{"type":"string","example":"5"},"description":"Delay in seconds."}}},"default":{"description":"Unexpected upstream/infrastructure failure (including an upstream 429 or 5xx). JSON and HTML/text bodies are possible. No universal requests-per-minute limit is configured on these public routes; account/upstream limits can still apply. Respect Retry-After when returned and use bounded backoff for temporary failures. The examples illustrate possible envelopes, not a guarantee of exact infrastructure text.","headers":{"Retry-After":{"description":"Optional retry delay in seconds or an HTTP date.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Framework failure","value":{"message":"Server Error"}},"rateLimit":{"summary":"Upstream rate limit","value":{"message":"Too Many Attempts."}}}},"text/html":{"schema":{"type":"string"},"examples":{"gateway":{"summary":"Gateway failure","value":"<html><body>502 Bad Gateway</body></html>"}}}}}},"x-vehicle-filter-schema":{"$ref":"#/components/schemas/VehicleSelectionFilter"}}},"/search/count":{"get":{"operationId":"searchCount","tags":["Vehicles"],"summary":"Count matching vehicles","description":"Uses the same filters as /search, returns only count. page, perPage and sort do not paginate the count. sort=auction_nearest applies the same upcoming-auction filter as /search. Empty matches return count: 0.\n\nVehicle filters apply identically to /search, /search/count and /cars. Omitted vehicle_type means automobile/1 (including old cars without a stored type); motorcycle/2 selects motorcycles. This is a root car filter, independent of source/listing access. Use matching types in all dictionaries. Exact ID/VIN/listing lookups keep their existing behavior and do not accept these filters.\n\nThe hierarchy is brands[] → models[] → generations[] → variants[] and trims[]. Legacy integer models[] remain supported; structured model objects require id and optional generations. Brand and generation objects also require id. Siblings at each level are OR alternatives; selected parent IDs and variant/trim constraints inside one branch are AND. Variant and trim lists each use OR. Omitted or empty children mean no descendant restriction. A root car must match one complete branch, so choices under different models/generations never mix. To request exact variant/trim pairs, repeat the same generation in separate branches, each with its own single variant and trim; branches are never merged into a cross product. Every array is limited to 100 entries. Positive unknown IDs or incompatible parent/child combinations return zero matches; malformed values return 422. A child without its own parent id is invalid. Filters use stored numeric root IDs only: cars without normalized generation/variant/trim IDs cannot match those selections. No name inference or catalogue join is performed.\n\nPHP query syntax: brands[0][id]=101&brands[0][models][0][id]=201&brands[0][models][0][generations][0][id]=301&brands[0][models][0][generations][0][variants][]=501&brands[0][models][0][generations][0][trims][]=401. IDs are synthetic; take real IDs from dictionaries. Never send the legacy models[] append syntax and structured models[0] together for the same brand: both target PHP index 0. Prefer structured objects for every model when using the extended hierarchy.\n\nFor /cars, type and the complete brand hierarchy are fixed when the scroll starts and are preserved in next_url. Continuing with scroll_id alone retains them; repeating equivalent values/order is allowed. Changing either filter returns 422. Explicit vehicle filters also return 422 if cached filter state is lost or the scroll predates these filters: start a new scroll. Old scrolls continued without new parameters keep their original Elasticsearch query. New response fields vehicle_type, generation_id, variant_id and trim_id expose the stored selection; missing optional IDs are null. These additive response fields participate in hash.\n\nAdditional listing fields are discovered with authenticated GET /listing-fields, optionally narrowed by domains[]. The catalogue is private to the key and enabled domains. Never hardcode field keys or types from examples. Only filterable=true definitions can be filtered; operators and constraints come from the catalogue. Keys are flat, with one global type and optional homogeneous array cardinality. JSON objects are stored-only.\n\nUse custom_fields[key][eq]=value, custom_fields[key][in][]=value or custom_fields[key][exists]=true/false. Numbers and dates additionally support gt/gte/lt/lte. Boolean eq=false means the exact false value, not absence. For arrays a matching element satisfies a comparison. Use eq, in or a non-conflicting lower/upper range; exists is standalone. Maximum 20 fields, 100 values per in. Monetary comparisons require custom_fields[key][currency]=cad (the listing native currency); there is no conversion. These conditions, domain access/selection, activity and other listing constraints must match the same nested listing, preventing matches across different ads of one car. A response may still contain other visible listings.\n\nUnknown or unavailable fields, unsupported operators and invalid values return 422; unavailable catalogue returns 503. Stored-only values remain in listings[].source_data; indexed values appear in listings[].custom_fields for that listing/domain. Preserve 0, false and arrays; missing/null means no indexed value. Existing source_data is unchanged, including vhr_url. Newly published fields populate on subsequent normal imports, without historical backfill. Sorting and aggregations are not supported in this stage. /cars pins the normalized conditions and field contract for the cursor: follow next_url unchanged or scroll_id alone; changing conditions or an incompatible/missing contract requires a new scroll (422).","parameters":[{"name":"vin","in":"query","required":false,"description":"Case-insensitive partial VIN. For an exact 16–19 character VIN, use /cars/vin/{vin}.","schema":{"type":"string","minLength":1,"maxLength":19,"pattern":"^[A-Za-z0-9]+$"}},{"name":"page","in":"query","required":false,"description":"Page number. For /search, explicitly pass perPage and keep page × perPage ≤ 10000. /search/count ignores pagination and skips this offset check.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"perPage","in":"query","required":false,"description":"Search page size: minimum 2, maximum 50. perPage=1 returns 422; use perPage=2 to fetch a small sample. Omitted or null pagination values use page=1 and perPage=50, including the search result-window check. Invalid values return 422.","schema":{"type":"integer","minimum":2,"maximum":50,"default":50}},{"name":"sort","in":"query","required":false,"description":"Sort order. Price sorting requires a resolved currency. auction_nearest selects only cars with an active listing in an enabled/selected domain with auction_at >= now; past dates do not participate in sorting. Pass the same sort to /search/count for a matching count.","schema":{"type":"string","enum":["newest","oldest","cheaper","expensive","odometer_asc","odometer_desc","year_asc","year_desc","auction_nearest"]}},{"name":"currency","in":"query","required":false,"description":"Case-insensitive currency code for price filtering/sorting. Must exist in the currency dictionary. Does not convert serialized listing prices.","schema":{"type":"string","minLength":3,"maxLength":3,"pattern":"^[A-Za-z]{3}$","default":"usd"}},{"name":"currency_id","in":"query","required":false,"description":"Optional internal currency ID; overrides currency.","schema":{"type":"integer","minimum":1}},{"name":"domains[]","in":"query","required":false,"description":"Optional source scope. Use IDs returned by GET /domains. Omit to use all enabled domains. Repeat the bracketed parameter: domains[]=33&domains[]=34. Every ID must be enabled for this key.","schema":{"type":"array","minItems":1,"uniqueItems":true,"items":{"type":"integer","minimum":1}},"style":"form","explode":true,"x-autofill":"domains"},{"name":"is_leasing","in":"query","required":false,"description":"Optional leasing filter. Send true (or 1) for listings explicitly marked is_leasing=true. Send false (or 0) to exclude true, including stored false, null and missing fields. Omit for no leasing filter; empty or invalid values return 422. A car must have at least one matching active listing in the enabled/selected domain scope. Other listings can remain in the response, so cars with mixed listing types can match both values. For /cars, set this on the first request and follow next_url unchanged; false is preserved. Continuing with only scroll_id retains the filter. Changing or adding the filter mid-scroll returns 422. If cached filter state is lost or the scroll predates this parameter, an explicit value returns 422; start a new scroll.","schema":{"type":"boolean"},"examples":{"leasing":{"summary":"Only leasing listings","value":true},"nonLeasing":{"summary":"Exclude leasing, including missing flags","value":false}}},{"name":"is_auction","in":"query","required":false,"description":"Optional auction filter. Send true (or 1) for listings explicitly marked is_auction=true. Send false (or 0) to exclude true, including stored false, null and missing fields. Omit for no auction filter; empty or invalid values return 422. Combined is_auction and is_leasing must match the same listing. A car must have at least one matching active listing in the enabled/selected domain scope. Other listings can remain in the response, so cars with mixed listing types can match both values. For /cars, set this on the first request and follow next_url unchanged; false is preserved. Continuing with only scroll_id retains the filter. Changing or adding the filter mid-scroll returns 422. If cached filter state is lost or the scroll predates this parameter, an explicit value returns 422; start a new scroll.","schema":{"type":"boolean"},"examples":{"auction":{"summary":"Only auction listings","value":true},"nonAuction":{"summary":"Exclude auction, including missing flags","value":false}}},{"name":"seats","in":"query","required":false,"description":"Exact seating capacity.","schema":{"type":"integer","minimum":1,"maximum":200}},{"name":"price_from","in":"query","required":false,"description":"Minimum listing price in the selected currency. Maximum 9223372036854775807 (signed 64-bit integer); values beyond JavaScript safe integers must be preserved as decimal text by clients.","schema":{"type":"integer","minimum":0,"format":"int64"}},{"name":"price_to","in":"query","required":false,"description":"Maximum listing price in the selected currency. Maximum 9223372036854775807 (signed 64-bit integer); values beyond JavaScript safe integers must be preserved as decimal text by clients.","schema":{"type":"integer","minimum":1,"format":"int64"}},{"name":"year_from","in":"query","required":false,"description":"Minimum production year.","schema":{"type":"integer","minimum":1800,"maximum":3000}},{"name":"year_to","in":"query","required":false,"description":"Maximum production year.","schema":{"type":"integer","minimum":1800,"maximum":3000}},{"name":"odometer_from","in":"query","required":false,"description":"Minimum mileage in kilometres.","schema":{"type":"integer","minimum":0,"maximum":999999999}},{"name":"odometer_to","in":"query","required":false,"description":"Maximum mileage in kilometres.","schema":{"type":"integer","minimum":0,"maximum":999999999}},{"name":"engine_volume_from","in":"query","required":false,"description":"Minimum engine displacement.","schema":{"type":"integer","minimum":0,"maximum":999999999}},{"name":"engine_volume_to","in":"query","required":false,"description":"Maximum engine displacement.","schema":{"type":"integer","minimum":0,"maximum":999999999}},{"name":"power_hp_from","in":"query","required":false,"description":"Minimum power in horsepower.","schema":{"type":"integer","minimum":0,"maximum":100000}},{"name":"power_hp_to","in":"query","required":false,"description":"Maximum power in horsepower.","schema":{"type":"integer","minimum":1,"maximum":100000}},{"name":"keys_available","in":"query","required":false,"description":"Listing has keys. Send 1 (true) or 0 (false). Omit for either value; strings \"true\"/\"false\" are rejected.","schema":{"type":"integer","enum":[0,1]}},{"name":"is_manufacturer_certified","in":"query","required":false,"description":"Listing is certified by the manufacturer or official dealer program. Send 1 (true) or 0 (false). Omit for either value; strings \"true\"/\"false\" are rejected.","schema":{"type":"integer","enum":[0,1]}},{"name":"has_inspections","in":"query","required":false,"description":"Root car has a public inspection. Send 1 (true) or 0 (false). Omit for either value; strings \"true\"/\"false\" are rejected.","schema":{"type":"integer","enum":[0,1]}},{"name":"has_history_reports","in":"query","required":false,"description":"A listing in the selected domain scope has a public history report. Send 1 (true) or 0 (false). Omit for either value; strings \"true\"/\"false\" are rejected.","schema":{"type":"integer","enum":[0,1]}},{"name":"body_types[]","in":"query","required":false,"description":"1 = sedan; 2 = wagon; 3 = coupe; 4 = pickup; 5 = suv; 6 = cabrio; 7 = van; 11 = hatchback; 12 = roadster; 13 = limousine; 20 = liftback; 22 = hearse; 27 = sport_car","schema":{"type":"array","items":{"type":"integer","enum":[1,2,3,4,5,6,7,11,12,13,20,22,27]}},"style":"form","explode":true},{"name":"colors[]","in":"query","required":false,"description":"1 = silver; 2 = purple; 3 = orange; 4 = green; 5 = red; 6 = gold; 8 = brown; 9 = grey; 10 = turquoise; 11 = blue; 12 = bronze; 13 = white; 14 = cream; 15 = black; 16 = yellow; 17 = beige; 18 = pink; 100 = two_colors","schema":{"type":"array","items":{"type":"integer","enum":[1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,17,18,100]}},"style":"form","explode":true},{"name":"fuels[]","in":"query","required":false,"description":"1 = diesel; 2 = electric; 3 = hybrid; 4 = gasoline; 5 = gas; 6 = flexible; 7 = hydrogen; 8 = ethanol","schema":{"type":"array","items":{"type":"integer","enum":[1,2,3,4,5,6,7,8]}},"style":"form","explode":true},{"name":"transmission","in":"query","required":false,"description":"1 = automatic; 2 = manual","schema":{"type":"integer","enum":[1,2]}},{"name":"seller_type","in":"query","required":false,"description":"1 = individual; 2 = dealer","schema":{"type":"integer","enum":[1,2]}},{"name":"steering_wheel_position","in":"query","required":false,"description":"1 = left; 2 = right","schema":{"type":"integer","enum":[1,2]}},{"name":"airbags","in":"query","required":false,"description":"1 = intact; 2 = deployed; 3 = missing","schema":{"type":"integer","enum":[1,2,3]}},{"name":"damages[]","in":"query","required":false,"description":"1 = side; 2 = theft; 3 = burn; 4 = electric; 5 = vandalized; 6 = water; 7 = top_roof; 8 = transmission; 9 = suspension; 10 = biohazard; 11 = cash_for_clunkers; 12 = repossession; 13 = rollover; 14 = all_over; 15 = engine; 16 = frame; 17 = front; 18 = rear; 19 = front_and_rear; 20 = hail; 21 = mechanical; 22 = minor_dents_scratches; 23 = vin; 24 = normal_wear; 25 = rejected_or_partial_repair; 26 = storm; 27 = stripped; 28 = undercarriage","schema":{"type":"array","items":{"type":"integer","enum":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28]}},"style":"form","explode":true},{"name":"conditions[]","in":"query","required":false,"description":"1 = used; 2 = new; 3 = damaged","schema":{"type":"array","items":{"type":"integer","enum":[1,2,3]}},"style":"form","explode":true},{"name":"availabilities[]","in":"query","required":false,"description":"1 = in_stock; 2 = in_transit; 3 = on_order","schema":{"type":"array","items":{"type":"integer","enum":[1,2,3]}},"style":"form","explode":true},{"name":"emissions[]","in":"query","required":false,"description":"1 = euro_1; 2 = euro_2; 3 = euro_3; 4 = euro_4; 5 = euro_5; 6 = euro_6; 7 = zev","schema":{"type":"array","items":{"type":"integer","enum":[1,2,3,4,5,6,7]}},"style":"form","explode":true},{"name":"drive_wheels[]","in":"query","required":false,"description":"1 = rear; 2 = front; 3 = all","schema":{"type":"array","items":{"type":"integer","enum":[1,2,3]}},"style":"form","explode":true},{"name":"vehicle_type","in":"query","required":false,"description":"Vehicle scope: automobile/1 (default), motorcycle/2. Missing stored type counts as automobile. Explicit empty or invalid values return 422. Keep this type in dictionary lookups and inventory requests. On /cars, set it on the first request and follow next_url unchanged; changing it mid-scroll or supplying it when cached state is unavailable returns 422.","schema":{"type":"string","enum":["automobile","motorcycle","1","2"],"default":"automobile"}},{"name":"interior_colors[]","in":"query","required":false,"description":"Interior color IDs from the colors dictionary. OR within the list; missing values do not match. Applies to /search, /search/count and /cars. Keep unchanged during scroll.","schema":{"type":"array","items":{"type":"integer","enum":[1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,17,18,100]},"maxItems":100,"uniqueItems":true},"style":"form","explode":true},{"name":"cylinders[]","in":"query","required":false,"description":"Exact cylinder counts (1–99), OR within the list; unknown counts do not match. Applies to /search, /search/count and /cars. Keep unchanged during scroll.","schema":{"type":"array","items":{"type":"integer","minimum":1,"maximum":99},"maxItems":99,"uniqueItems":true},"style":"form","explode":true},{"name":"brands[0][id]","in":"query","required":false,"description":"First brand ID from /brands for the selected vehicle_type. Additional brands use brands[1][id], etc. All sibling brands are OR alternatives.","schema":{"type":"integer","minimum":1},"x-autofill":"brands"},{"name":"brands[0][models][]","in":"query","required":false,"description":"Legacy model ID list for the first brand. Omit for all models. For generation/variant/trim filtering use structured models instead; clear this field before sending models[0][id] to avoid overwriting PHP index 0.","schema":{"type":"array","items":{"type":"integer","minimum":1},"maxItems":100},"style":"form","explode":true,"x-autofill":"models"},{"name":"brands[0][models][0][id]","in":"query","required":false,"description":"Structured model ID from /models/{brand_id}. Required on each model object. Do not combine this index with the legacy append syntax models[]. Additional models use models[1][id], etc.","schema":{"type":"integer","minimum":1}},{"name":"brands[0][models][0][generations][0][id]","in":"query","required":false,"description":"Generation ID from /generations/{model_id}. Required on each generation object. Omit generations or send an empty list to include every generation of this model. Additional generations use generations[1][id], etc.","schema":{"type":"integer","minimum":1}},{"name":"brands[0][models][0][generations][0][variants][]","in":"query","required":false,"description":"Optional variant IDs from /variants/{generation_id}, OR within the list. Omitted/empty means any variant. Intersected with this generation and its trims; missing stored variant_id does not match a selected ID.","schema":{"type":"array","items":{"type":"integer","minimum":1},"maxItems":100},"style":"form","explode":true},{"name":"brands[0][models][0][generations][0][trims][]","in":"query","required":false,"description":"Optional trim IDs from /trims/{generation_id}, OR within the list. Omitted/empty means any trim. Intersected with this generation and its variants; missing stored trim_id does not match a selected ID.","schema":{"type":"array","items":{"type":"integer","minimum":1},"maxItems":100},"style":"form","explode":true},{"name":"countries[0][id]","in":"query","required":false,"description":"First internal country ID from /countries. Additional countries use countries[1][id], etc.","schema":{"type":"integer"}},{"name":"countries[0][regions][]","in":"query","required":false,"description":"Optional internal region IDs belonging to the first country.","schema":{"type":"array","items":{"type":"integer"}},"style":"form","explode":true},{"name":"custom_fields","in":"query","required":false,"description":"Additional listing fields are discovered with authenticated GET /listing-fields, optionally narrowed by domains[]. The catalogue is private to the key and enabled domains. Never hardcode field keys or types from examples. Only filterable=true definitions can be filtered; operators and constraints come from the catalogue. Keys are flat, with one global type and optional homogeneous array cardinality. JSON objects are stored-only.\n\nUse custom_fields[key][eq]=value, custom_fields[key][in][]=value or custom_fields[key][exists]=true/false. Numbers and dates additionally support gt/gte/lt/lte. Boolean eq=false means the exact false value, not absence. For arrays a matching element satisfies a comparison. Use eq, in or a non-conflicting lower/upper range; exists is standalone. Maximum 20 fields, 100 values per in. Monetary comparisons require custom_fields[key][currency]=cad (the listing native currency); there is no conversion. These conditions, domain access/selection, activity and other listing constraints must match the same nested listing, preventing matches across different ads of one car. A response may still contain other visible listings.\n\nUnknown or unavailable fields, unsupported operators and invalid values return 422; unavailable catalogue returns 503. Stored-only values remain in listings[].source_data; indexed values appear in listings[].custom_fields for that listing/domain. Preserve 0, false and arrays; missing/null means no indexed value. Existing source_data is unchanged, including vhr_url. Newly published fields populate on subsequent normal imports, without historical backfill. Sorting and aggregations are not supported in this stage. /cars pins the normalized conditions and field contract for the cursor: follow next_url unchanged or scroll_id alone; changing conditions or an incompatible/missing contract requires a new scroll (422).","schema":{"type":"object","maxProperties":20,"additionalProperties":{"$ref":"#/components/schemas/ListingFieldCondition"}},"style":"deepObject","explode":true},{"name":"lang","in":"query","required":false,"description":"Response locale. Option translations are also limited by the account languages. The page selects its current language automatically.","schema":{"type":"string","enum":["en","ru","sq","pl","uk","bg"]}}],"responses":{"200":{"description":"Number of matching cars.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Count"},"examples":{"matches":{"summary":"Matching vehicles","value":{"count":1234}},"empty":{"summary":"No matches","value":{"count":0}}}}}},"400":{"description":"Search engine rejected the query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rejected":{"summary":"Search query rejected","value":{"error":"search_phase_execution_exception"}}}}}},"403":{"description":"API key, subscription, source access or IP restriction. Correct the account/access condition before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missingKey":{"summary":"API key is missing","value":{"error":"please add your api_key in get param"}},"invalidKey":{"summary":"API key is invalid","value":{"error":"wrong api key"}},"expiredSubscription":{"summary":"Subscription has expired","value":{"error":"your api subscription has expired"}},"inactiveSubscription":{"summary":"Subscription is inactive","value":{"error":"your api subscription is not active"}},"ipNotAllowed":{"summary":"Request IP is not allowlisted","value":{"error":"ip address is not in whitelist","ip":"203.0.113.10"}},"noSources":{"summary":"Subscription has no enabled sources","value":{"error":"you don't have any data in your subscription"}}}}}},"404":{"description":"Service lookup failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"examples":{"missing":{"summary":"Referenced record not found","value":{"errors":{"id":["Not found"]}}}}}}},"422":{"description":"Invalid filter, currency, domain access or pagination. Correct the named fields. Validation messages can be localized.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"examples":{"vehicleType":{"summary":"Invalid vehicle type","value":{"errors":{"vehicle_type":["The selected vehicle type is invalid."]}}},"modelParent":{"summary":"Structured model is missing its ID","value":{"errors":{"brands.0.models.0.id":["The brands.0.models.0.id field is required."]}}},"perPageMinimum":{"summary":"Page size below 2","value":{"errors":{"perPage":["The per page field must be at least 2."]}}},"perPage":{"summary":"Page size exceeds 50","value":{"errors":{"perPage":["The per page field must not be greater than 50."]}}},"currency":{"summary":"Unknown currency code","value":{"errors":{"currency":["currency is invalid"]}}},"domain":{"summary":"A selected domain is not enabled","value":{"errors":{"domains":["These domain IDs are not enabled for this API key: 999999"]}}},"leasing":{"summary":"Invalid leasing value","value":{"errors":{"is_leasing":["The is leasing field must be true or false."]}}}}}}},"default":{"description":"Unexpected upstream/infrastructure failure (including an upstream 429 or 5xx). JSON and HTML/text bodies are possible. No universal requests-per-minute limit is configured on these public routes; account/upstream limits can still apply. Respect Retry-After when returned and use bounded backoff for temporary failures. The examples illustrate possible envelopes, not a guarantee of exact infrastructure text.","headers":{"Retry-After":{"description":"Optional retry delay in seconds or an HTTP date.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Framework failure","value":{"message":"Server Error"}},"rateLimit":{"summary":"Upstream rate limit","value":{"message":"Too Many Attempts."}}}},"text/html":{"schema":{"type":"string"},"examples":{"gateway":{"summary":"Gateway failure","value":"<html><body>502 Bad Gateway</body></html>"}}}}}},"x-vehicle-filter-schema":{"$ref":"#/components/schemas/VehicleSelectionFilter"}}},"/cars":{"get":{"operationId":"cars","tags":["Export"],"summary":"Export vehicles with a cursor","description":"Scroll through active vehicles and full reports. Start without scroll_id, then follow each next_url unchanged. next_url uses HTTPS on the public API host used for the request (api.carstat.dev, api.auctionsapi.com or api.vehicleapi.dev); legacy or unrecognized hosts fall back to api.carstat.dev. Keep the same API key and domain scope for the entire scroll. Fetch the next batch before scroll_time expires. Stop when scroll_id is null and data is empty. Batch limit and scroll_time are cast to integers by the backend; use positive values. Values above the documented maxima return 400.\n\nVehicle filters apply identically to /search, /search/count and /cars. Omitted vehicle_type means automobile/1 (including old cars without a stored type); motorcycle/2 selects motorcycles. This is a root car filter, independent of source/listing access. Use matching types in all dictionaries. Exact ID/VIN/listing lookups keep their existing behavior and do not accept these filters.\n\nThe hierarchy is brands[] → models[] → generations[] → variants[] and trims[]. Legacy integer models[] remain supported; structured model objects require id and optional generations. Brand and generation objects also require id. Siblings at each level are OR alternatives; selected parent IDs and variant/trim constraints inside one branch are AND. Variant and trim lists each use OR. Omitted or empty children mean no descendant restriction. A root car must match one complete branch, so choices under different models/generations never mix. To request exact variant/trim pairs, repeat the same generation in separate branches, each with its own single variant and trim; branches are never merged into a cross product. Every array is limited to 100 entries. Positive unknown IDs or incompatible parent/child combinations return zero matches; malformed values return 422. A child without its own parent id is invalid. Filters use stored numeric root IDs only: cars without normalized generation/variant/trim IDs cannot match those selections. No name inference or catalogue join is performed.\n\nPHP query syntax: brands[0][id]=101&brands[0][models][0][id]=201&brands[0][models][0][generations][0][id]=301&brands[0][models][0][generations][0][variants][]=501&brands[0][models][0][generations][0][trims][]=401. IDs are synthetic; take real IDs from dictionaries. Never send the legacy models[] append syntax and structured models[0] together for the same brand: both target PHP index 0. Prefer structured objects for every model when using the extended hierarchy.\n\nFor /cars, type and the complete brand hierarchy are fixed when the scroll starts and are preserved in next_url. Continuing with scroll_id alone retains them; repeating equivalent values/order is allowed. Changing either filter returns 422. Explicit vehicle filters also return 422 if cached filter state is lost or the scroll predates these filters: start a new scroll. Old scrolls continued without new parameters keep their original Elasticsearch query. New response fields vehicle_type, generation_id, variant_id and trim_id expose the stored selection; missing optional IDs are null. These additive response fields participate in hash.\n\nAdditional listing fields are discovered with authenticated GET /listing-fields, optionally narrowed by domains[]. The catalogue is private to the key and enabled domains. Never hardcode field keys or types from examples. Only filterable=true definitions can be filtered; operators and constraints come from the catalogue. Keys are flat, with one global type and optional homogeneous array cardinality. JSON objects are stored-only.\n\nUse custom_fields[key][eq]=value, custom_fields[key][in][]=value or custom_fields[key][exists]=true/false. Numbers and dates additionally support gt/gte/lt/lte. Boolean eq=false means the exact false value, not absence. For arrays a matching element satisfies a comparison. Use eq, in or a non-conflicting lower/upper range; exists is standalone. Maximum 20 fields, 100 values per in. Monetary comparisons require custom_fields[key][currency]=cad (the listing native currency); there is no conversion. These conditions, domain access/selection, activity and other listing constraints must match the same nested listing, preventing matches across different ads of one car. A response may still contain other visible listings.\n\nUnknown or unavailable fields, unsupported operators and invalid values return 422; unavailable catalogue returns 503. Stored-only values remain in listings[].source_data; indexed values appear in listings[].custom_fields for that listing/domain. Preserve 0, false and arrays; missing/null means no indexed value. Existing source_data is unchanged, including vhr_url. Newly published fields populate on subsequent normal imports, without historical backfill. Sorting and aggregations are not supported in this stage. /cars pins the normalized conditions and field contract for the cursor: follow next_url unchanged or scroll_id alone; changing conditions or an incompatible/missing contract requires a new scroll (422).\n\nEvery listing includes location_details with the same country/region/district/place shape. country is {id, name, iso}; other components are {id, name}. Missing components are null. Names use lang with dictionary fallbacks; unresolved IDs retain their ID with name:null. Existing textual source labels have id:null. The legacy location field retains its endpoint-specific format for compatibility. All visible listing IDs are collected from the complete response batch before bulk dictionary lookup (up to 1000 unique documents per request across both country and location indexes), never one request per car. Read location_details directly for display; /countries and /locations remain available for selectors and independent lookup. No city or parent is inferred from coordinates. /cars next_url preserves the effective lang across scroll pages. location_details participates in the car hash.","parameters":[{"name":"limit","in":"query","required":false,"description":"Items per batch. Default 500; maximum 500. Positive values are required for a usable export.","schema":{"type":"integer","minimum":1,"maximum":500,"default":500}},{"name":"scroll_time","in":"query","required":false,"description":"Cursor lifetime in minutes. Default 10, maximum 15.","schema":{"type":"integer","minimum":1,"maximum":15,"default":10}},{"name":"scroll_id","in":"query","required":false,"description":"Opaque cursor from the preceding response. Prefer following next_url.","schema":{"type":"string"}},{"name":"domains[]","in":"query","required":false,"description":"Optional source scope. Use IDs returned by GET /domains. Omit to use all enabled domains. Repeat the bracketed parameter: domains[]=33&domains[]=34. Every ID must be enabled for this key.","schema":{"type":"array","minItems":1,"uniqueItems":true,"items":{"type":"integer","minimum":1}},"style":"form","explode":true,"x-autofill":"domains"},{"name":"is_leasing","in":"query","required":false,"description":"Optional leasing filter. Send true (or 1) for listings explicitly marked is_leasing=true. Send false (or 0) to exclude true, including stored false, null and missing fields. Omit for no leasing filter; empty or invalid values return 422. A car must have at least one matching active listing in the enabled/selected domain scope. Other listings can remain in the response, so cars with mixed listing types can match both values. For /cars, set this on the first request and follow next_url unchanged; false is preserved. Continuing with only scroll_id retains the filter. Changing or adding the filter mid-scroll returns 422. If cached filter state is lost or the scroll predates this parameter, an explicit value returns 422; start a new scroll.","schema":{"type":"boolean"},"examples":{"leasing":{"summary":"Only leasing listings","value":true},"nonLeasing":{"summary":"Exclude leasing, including missing flags","value":false}}},{"name":"is_auction","in":"query","required":false,"description":"Optional auction filter. Send true (or 1) for listings explicitly marked is_auction=true. Send false (or 0) to exclude true, including stored false, null and missing fields. Omit for no auction filter; empty or invalid values return 422. Combined is_auction and is_leasing must match the same listing. A car must have at least one matching active listing in the enabled/selected domain scope. Other listings can remain in the response, so cars with mixed listing types can match both values. For /cars, set this on the first request and follow next_url unchanged; false is preserved. Continuing with only scroll_id retains the filter. Changing or adding the filter mid-scroll returns 422. If cached filter state is lost or the scroll predates this parameter, an explicit value returns 422; start a new scroll.","schema":{"type":"boolean"},"examples":{"auction":{"summary":"Only auction listings","value":true},"nonAuction":{"summary":"Exclude auction, including missing flags","value":false}}},{"name":"vehicle_type","in":"query","required":false,"description":"Vehicle scope: automobile/1 (default), motorcycle/2. Missing stored type counts as automobile. Explicit empty or invalid values return 422. Keep this type in dictionary lookups and inventory requests. On /cars, set it on the first request and follow next_url unchanged; changing it mid-scroll or supplying it when cached state is unavailable returns 422.","schema":{"type":"string","enum":["automobile","motorcycle","1","2"],"default":"automobile"}},{"name":"interior_colors[]","in":"query","required":false,"description":"Interior color IDs from the colors dictionary. OR within the list; missing values do not match. Applies to /search, /search/count and /cars. Keep unchanged during scroll.","schema":{"type":"array","items":{"type":"integer","enum":[1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,17,18,100]},"maxItems":100,"uniqueItems":true},"style":"form","explode":true},{"name":"cylinders[]","in":"query","required":false,"description":"Exact cylinder counts (1–99), OR within the list; unknown counts do not match. Applies to /search, /search/count and /cars. Keep unchanged during scroll.","schema":{"type":"array","items":{"type":"integer","minimum":1,"maximum":99},"maxItems":99,"uniqueItems":true},"style":"form","explode":true},{"name":"brands[0][id]","in":"query","required":false,"description":"First brand ID from /brands for the selected vehicle_type. Additional brands use brands[1][id], etc. All sibling brands are OR alternatives.","schema":{"type":"integer","minimum":1},"x-autofill":"brands"},{"name":"brands[0][models][]","in":"query","required":false,"description":"Legacy model ID list for the first brand. Omit for all models. For generation/variant/trim filtering use structured models instead; clear this field before sending models[0][id] to avoid overwriting PHP index 0.","schema":{"type":"array","items":{"type":"integer","minimum":1},"maxItems":100},"style":"form","explode":true,"x-autofill":"models"},{"name":"brands[0][models][0][id]","in":"query","required":false,"description":"Structured model ID from /models/{brand_id}. Required on each model object. Do not combine this index with the legacy append syntax models[]. Additional models use models[1][id], etc.","schema":{"type":"integer","minimum":1}},{"name":"brands[0][models][0][generations][0][id]","in":"query","required":false,"description":"Generation ID from /generations/{model_id}. Required on each generation object. Omit generations or send an empty list to include every generation of this model. Additional generations use generations[1][id], etc.","schema":{"type":"integer","minimum":1}},{"name":"brands[0][models][0][generations][0][variants][]","in":"query","required":false,"description":"Optional variant IDs from /variants/{generation_id}, OR within the list. Omitted/empty means any variant. Intersected with this generation and its trims; missing stored variant_id does not match a selected ID.","schema":{"type":"array","items":{"type":"integer","minimum":1},"maxItems":100},"style":"form","explode":true},{"name":"brands[0][models][0][generations][0][trims][]","in":"query","required":false,"description":"Optional trim IDs from /trims/{generation_id}, OR within the list. Omitted/empty means any trim. Intersected with this generation and its variants; missing stored trim_id does not match a selected ID.","schema":{"type":"array","items":{"type":"integer","minimum":1},"maxItems":100},"style":"form","explode":true},{"name":"custom_fields","in":"query","required":false,"description":"Additional listing fields are discovered with authenticated GET /listing-fields, optionally narrowed by domains[]. The catalogue is private to the key and enabled domains. Never hardcode field keys or types from examples. Only filterable=true definitions can be filtered; operators and constraints come from the catalogue. Keys are flat, with one global type and optional homogeneous array cardinality. JSON objects are stored-only.\n\nUse custom_fields[key][eq]=value, custom_fields[key][in][]=value or custom_fields[key][exists]=true/false. Numbers and dates additionally support gt/gte/lt/lte. Boolean eq=false means the exact false value, not absence. For arrays a matching element satisfies a comparison. Use eq, in or a non-conflicting lower/upper range; exists is standalone. Maximum 20 fields, 100 values per in. Monetary comparisons require custom_fields[key][currency]=cad (the listing native currency); there is no conversion. These conditions, domain access/selection, activity and other listing constraints must match the same nested listing, preventing matches across different ads of one car. A response may still contain other visible listings.\n\nUnknown or unavailable fields, unsupported operators and invalid values return 422; unavailable catalogue returns 503. Stored-only values remain in listings[].source_data; indexed values appear in listings[].custom_fields for that listing/domain. Preserve 0, false and arrays; missing/null means no indexed value. Existing source_data is unchanged, including vhr_url. Newly published fields populate on subsequent normal imports, without historical backfill. Sorting and aggregations are not supported in this stage. /cars pins the normalized conditions and field contract for the cursor: follow next_url unchanged or scroll_id alone; changing conditions or an incompatible/missing contract requires a new scroll (422).","schema":{"type":"object","maxProperties":20,"additionalProperties":{"$ref":"#/components/schemas/ListingFieldCondition"}},"style":"deepObject","explode":true},{"name":"lang","in":"query","required":false,"description":"Response locale. Option translations are also limited by the account languages. The page selects its current language automatically.","schema":{"type":"string","enum":["en","ru","sq","pl","uk","bg"]}}],"responses":{"200":{"description":"Batch, cursor and total; next_url is omitted when complete. total may be null if its cache entry was lost.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CarScroll"},"examples":{"batch":{"summary":"First or subsequent batch","value":{"data":[{"id":"example-car-001","has_inspections":true,"has_history_reports":true,"year":2022,"vin":"EXAMPLEVIN00000001","brand":{"id":101,"name":"Example brand"},"model":{"id":201,"name":"Example model"},"vehicle_type":1,"generation_id":null,"variant_id":null,"trim_id":null,"seats":5,"doors":4,"cylinders":4,"steering_wheel_position":{"id":1,"name":"left"},"option_ids":[101],"listings":[{"external":{"id":"example-listing-001","domain":{"id":33,"name":"cars.example.com"},"url":"https://cars.example.com/listing/example-listing-001"},"archived":false,"title":{"en":"Example vehicle"},"odometer":32000,"location":{"iso":"DE","country":1,"position":{"lat":52.52,"lon":13.405}},"location_details":{"country":{"id":1,"name":"Germany","iso":"DE"},"region":null,"district":null,"place":null},"images":[{"original":"https://cars.example.com/images/example.jpg"}],"video":["https://cars.example.com/videos/example.mp4"],"created_at":"2026-09-01T10:00:00Z","last_seen_at":"2026-09-13T10:00:00Z","updated_at":"2026-09-13T10:00:00Z","price":{"price":25000,"currency":{"id":1,"name":"usd"},"negotiable":false,"history":[{"price":26000,"currency_id":1,"created_at":"2026-09-01T10:00:00Z"}]},"seller_type":null,"option_ids":[101],"is_auction":false,"current_bid":null,"auction_at":null,"availability":null,"is_manufacturer_certified":true,"has_history_reports":true,"condition":null,"keys_available":true,"damage":null,"second_damage":null,"airbag_state":null,"document_id":null}],"hash":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","inspections":[{"schema_version":1,"mapper_contract_version":1,"report_id":"example-inspection-001","status":"published","visibility":"public","language":"en","vehicle_ref":{"domain_id":33,"listing_id":"example-listing-001","site_car_id":123,"vin":"EXAMPLEVIN00000001"},"participants":[{"role_key":"inspector","name":"Example inspector","company_id":10,"user_id":20}],"conclusions":{"overall_result_key":"issue"},"inspection_blocks":[{"id":"block-1","key":"exterior","result_key":"issue"}],"checked_items":[{"id":"item-1","block_id":"block-1","block_key":"exterior","part_key":"front_door","part_label":"Front door","result_key":"issue","issue_type_keys":["scratch"],"severity_key":"minor","description":"Small surface scratch","evidence_media_ids":[],"measurements":[]}],"diagnostic_errors":[],"media":[{"id":"media-1","type_key":"photo","external_url":"https://cars.example.com/images/inspection.jpg","server_id":1,"sort_order":0}],"files":[],"limitations":[],"translations":{"language":"en","fallback_language":"en","terms":{"result":{"issue":"Issue"}},"missing":[],"taxonomy_available":true,"source_text_translated":false}}],"vehicle_history_reports":[{"schema_version":1,"mapper_contract_version":1,"report_id":"example-history-001","status":"published","visibility":"public","language":"en","vehicle_ref":{"domain_id":33,"listing_id":"example-listing-001","vin":"EXAMPLEVIN00000001"},"coverage":{"completeness_key":"partial","section_keys":["registration"]},"summary":{"first_registered_at":"2022-05-01","owner_change_count":1},"checks":[{"id":"check-1","type_key":"flood_total_loss_history","result_key":"unknown","count":null}],"events":[{"id":"event-1","type_key":"initial_registration","occurred_at":"2022-05-01","date_precision_key":"day","details":[]}],"media":[],"files":[],"limitations":[{"id":"limit-1","type_key":"other","description":"Synthetic example with partial source coverage"}],"translations":{"language":"en","fallback_language":"en","terms":{},"missing":[{"type":"event_type","key":"initial_registration","fallback_language":null}],"taxonomy_available":false,"source_text_translated":false}}]}],"next_url":"https://api.auctionsapi.com/cars?scroll_id=EXAMPLE_CURSOR&api_key=YOUR_API_KEY&domains%5B0%5D=33","scroll_id":"EXAMPLE_CURSOR","total":1}},"complete":{"summary":"Export complete","value":{"scroll_id":null,"data":[],"total":1,"message":"No more data"}}}}}},"400":{"description":"Batch limit or cursor lifetime is too large.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"limit":{"summary":"Too many items","value":{"message":"limit must be less than 500 items per page","your_value":501,"default_value":500}},"lifetime":{"summary":"Lifetime too long","value":{"message":"scroll_time must be less than 15 minutes","your_value":16,"default_value":10}}}}}},"403":{"description":"Authentication/access failure, or an invalid cursor rejected with 403 by the search service.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missingKey":{"summary":"API key is missing","value":{"error":"please add your api_key in get param"}},"invalidKey":{"summary":"API key is invalid","value":{"error":"wrong api key"}},"expiredSubscription":{"summary":"Subscription has expired","value":{"error":"your api subscription has expired"}},"inactiveSubscription":{"summary":"Subscription is inactive","value":{"error":"your api subscription is not active"}},"ipNotAllowed":{"summary":"Request IP is not allowlisted","value":{"error":"ip address is not in whitelist","ip":"203.0.113.10"}},"noSources":{"summary":"Subscription has no enabled sources","value":{"error":"you don't have any data in your subscription"}},"cursor":{"summary":"Cursor rejected","value":{"error":"your scroll id was expired or it's invalid","scrollId":"EXAMPLE_CURSOR","code":403}},"noData":{"summary":"No data in domain scope","value":{"message":"you dont have any data in your subscription"}}}}}},"404":{"description":"Cursor expired or invalid. Start a new scroll without scroll_id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"expired":{"summary":"Expired cursor","value":{"error":"your scroll id was expired or it's invalid","scrollId":"EXAMPLE_CURSOR","code":404}}}}}},"422":{"description":"Invalid filter/hierarchy, unauthorized domain, or a domain/leasing/auction/vehicle filter changed mid-scroll. Start a new scroll when filter state is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"examples":{"domain":{"summary":"A selected domain is not enabled","value":{"message":"The given data was invalid.","errors":{"domains":["These domain IDs are not enabled for this API key: 999999"]}}},"changed":{"summary":"Changed cursor scope","value":{"errors":{"domains":["domains cannot be changed while continuing an existing scroll"]}}},"leasing":{"summary":"Invalid leasing value","value":{"message":"The given data was invalid.","errors":{"is_leasing":["The is leasing field must be true or false."]}}},"leasingChanged":{"summary":"Changed or unavailable leasing filter","value":{"errors":{"is_leasing":["is_leasing cannot be changed while continuing an existing scroll; start a new scroll to change the filter"]}}},"vehicleChanged":{"summary":"Vehicle type changed","value":{"errors":{"vehicle_type":["vehicle_type cannot be changed while continuing an existing scroll; start a new scroll to change the filter"]}}},"hierarchyChanged":{"summary":"Vehicle hierarchy changed","value":{"errors":{"brands":["brands cannot be changed while continuing an existing scroll; start a new scroll to change the filter"]}}}}}}},"503":{"description":"Search service is temporarily unavailable. Retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Search unavailable","value":{"error":"search service temporarily unavailable"}}}}},"headers":{"Retry-After":{"schema":{"type":"string","example":"5"},"description":"Delay in seconds."}}},"default":{"description":"Unexpected upstream/infrastructure failure (including an upstream 429 or 5xx). JSON and HTML/text bodies are possible. No universal requests-per-minute limit is configured on these public routes; account/upstream limits can still apply. Respect Retry-After when returned and use bounded backoff for temporary failures. The examples illustrate possible envelopes, not a guarantee of exact infrastructure text.","headers":{"Retry-After":{"description":"Optional retry delay in seconds or an HTTP date.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Framework failure","value":{"message":"Server Error"}},"rateLimit":{"summary":"Upstream rate limit","value":{"message":"Too Many Attempts."}}}},"text/html":{"schema":{"type":"string"},"examples":{"gateway":{"summary":"Gateway failure","value":"<html><body>502 Bad Gateway</body></html>"}}}}}},"x-vehicle-filter-schema":{"$ref":"#/components/schemas/VehicleSelectionFilter"}}},"/cars/vin/{vin}":{"get":{"operationId":"carByVin","tags":["Vehicles"],"summary":"Find a vehicle by VIN","description":"Returns one car in data, including full public reports. Exact lookups can return recently archived cars while retained. Car-level reports are assembled from active listings; for a retained archived listing use /listing/{domain_id}/{listing_id}.\n\nEvery listing includes location_details with the same country/region/district/place shape. country is {id, name, iso}; other components are {id, name}. Missing components are null. Names use lang with dictionary fallbacks; unresolved IDs retain their ID with name:null. Existing textual source labels have id:null. The legacy location field retains its endpoint-specific format for compatibility. All visible listing IDs are collected from the complete response batch before bulk dictionary lookup (up to 1000 unique documents per request across both country and location indexes), never one request per car. Read location_details directly for display; /countries and /locations remain available for selectors and independent lookup. No city or parent is inferred from coordinates. /cars next_url preserves the effective lang across scroll pages. location_details participates in the car hash.","parameters":[{"name":"vin","in":"path","required":true,"description":"Exact VIN, case-insensitive. The page fills an available VIN from a search result after connecting your key.","schema":{"type":"string","minLength":16,"maxLength":19,"pattern":"^[A-Za-z0-9]+$"},"example":"EXAMPLEVIN00000001"},{"name":"lang","in":"query","required":false,"description":"Response locale. Option translations are also limited by the account languages. The page selects its current language automatically.","schema":{"type":"string","enum":["en","ru","sq","pl","uk","bg"]}}],"responses":{"200":{"description":"Single vehicle with reports.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CarDetail"},"examples":{"vehicle":{"summary":"Detailed vehicle","value":{"data":{"id":"example-car-001","has_inspections":true,"has_history_reports":true,"year":2022,"vin":"EXAMPLEVIN00000001","brand":{"id":101,"name":"Example brand"},"model":{"id":201,"name":"Example model"},"vehicle_type":1,"generation_id":null,"variant_id":null,"trim_id":null,"seats":5,"doors":4,"cylinders":4,"steering_wheel_position":{"id":1,"name":"left"},"option_ids":[101],"listings":[{"external":{"id":"example-listing-001","domain":{"id":33,"name":"cars.example.com"},"url":"https://cars.example.com/listing/example-listing-001"},"archived":false,"title":{"en":"Example vehicle"},"odometer":32000,"location":{"iso":"DE","country":1,"position":{"lat":52.52,"lon":13.405}},"location_details":{"country":{"id":1,"name":"Germany","iso":"DE"},"region":null,"district":null,"place":null},"images":[{"original":"https://cars.example.com/images/example.jpg"}],"video":["https://cars.example.com/videos/example.mp4"],"created_at":"2026-09-01T10:00:00Z","last_seen_at":"2026-09-13T10:00:00Z","updated_at":"2026-09-13T10:00:00Z","price":{"price":25000,"currency":{"id":1,"name":"usd"},"negotiable":false,"history":[{"price":26000,"currency_id":1,"created_at":"2026-09-01T10:00:00Z"}]},"seller_type":null,"option_ids":[101],"is_auction":false,"current_bid":null,"auction_at":null,"availability":null,"is_manufacturer_certified":true,"has_history_reports":true,"condition":null,"keys_available":true,"damage":null,"second_damage":null,"airbag_state":null,"document_id":null}],"hash":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","inspections":[{"schema_version":1,"mapper_contract_version":1,"report_id":"example-inspection-001","status":"published","visibility":"public","language":"en","vehicle_ref":{"domain_id":33,"listing_id":"example-listing-001","site_car_id":123,"vin":"EXAMPLEVIN00000001"},"participants":[{"role_key":"inspector","name":"Example inspector","company_id":10,"user_id":20}],"conclusions":{"overall_result_key":"issue"},"inspection_blocks":[{"id":"block-1","key":"exterior","result_key":"issue"}],"checked_items":[{"id":"item-1","block_id":"block-1","block_key":"exterior","part_key":"front_door","part_label":"Front door","result_key":"issue","issue_type_keys":["scratch"],"severity_key":"minor","description":"Small surface scratch","evidence_media_ids":[],"measurements":[]}],"diagnostic_errors":[],"media":[{"id":"media-1","type_key":"photo","external_url":"https://cars.example.com/images/inspection.jpg","server_id":1,"sort_order":0}],"files":[],"limitations":[],"translations":{"language":"en","fallback_language":"en","terms":{"result":{"issue":"Issue"}},"missing":[],"taxonomy_available":true,"source_text_translated":false}}],"vehicle_history_reports":[{"schema_version":1,"mapper_contract_version":1,"report_id":"example-history-001","status":"published","visibility":"public","language":"en","vehicle_ref":{"domain_id":33,"listing_id":"example-listing-001","vin":"EXAMPLEVIN00000001"},"coverage":{"completeness_key":"partial","section_keys":["registration"]},"summary":{"first_registered_at":"2022-05-01","owner_change_count":1},"checks":[{"id":"check-1","type_key":"flood_total_loss_history","result_key":"unknown","count":null}],"events":[{"id":"event-1","type_key":"initial_registration","occurred_at":"2022-05-01","date_precision_key":"day","details":[]}],"media":[],"files":[],"limitations":[{"id":"limit-1","type_key":"other","description":"Synthetic example with partial source coverage"}],"translations":{"language":"en","fallback_language":"en","terms":{},"missing":[{"type":"event_type","key":"initial_registration","fallback_language":null}],"taxonomy_available":false,"source_text_translated":false}}]}}},"noReports":{"summary":"Vehicle without reports","value":{"data":{"id":"example-car-001","has_inspections":false,"has_history_reports":false,"year":2022,"vin":"EXAMPLEVIN00000001","brand":{"id":101,"name":"Example brand"},"model":{"id":201,"name":"Example model"},"vehicle_type":1,"generation_id":null,"variant_id":null,"trim_id":null,"seats":5,"doors":4,"cylinders":4,"steering_wheel_position":{"id":1,"name":"left"},"option_ids":[101],"listings":[{"external":{"id":"example-listing-001","domain":{"id":33,"name":"cars.example.com"},"url":"https://cars.example.com/listing/example-listing-001"},"archived":false,"title":null,"odometer":32000,"location":{"iso":"DE","country":1,"position":{"lat":52.52,"lon":13.405}},"location_details":{"country":{"id":1,"name":"Germany","iso":"DE"},"region":null,"district":null,"place":null},"images":[{"original":"https://cars.example.com/images/example.jpg"}],"video":[],"created_at":"2026-09-01T10:00:00Z","last_seen_at":"2026-09-13T10:00:00Z","updated_at":"2026-09-13T10:00:00Z","price":{"price":25000,"currency":{"id":1,"name":"usd"},"negotiable":false,"history":[{"price":26000,"currency_id":1,"created_at":"2026-09-01T10:00:00Z"}]},"seller_type":null,"option_ids":[101],"is_auction":false,"current_bid":null,"auction_at":null,"availability":null,"is_manufacturer_certified":true,"has_history_reports":false,"condition":null,"keys_available":true,"damage":null,"second_damage":null,"airbag_state":null,"document_id":null}],"hash":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","inspections":[],"vehicle_history_reports":[]}}}}}}},"400":{"description":"Search engine rejected the lookup.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid":{"summary":"Invalid lookup","value":{"error":"invalid request to search car by vin","vin":"invalid-value"}}}}}},"403":{"description":"API key, subscription, source access or IP restriction. Correct the account/access condition before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missingKey":{"summary":"API key is missing","value":{"error":"please add your api_key in get param"}},"invalidKey":{"summary":"API key is invalid","value":{"error":"wrong api key"}},"expiredSubscription":{"summary":"Subscription has expired","value":{"error":"your api subscription has expired"}},"inactiveSubscription":{"summary":"Subscription is inactive","value":{"error":"your api subscription is not active"}},"ipNotAllowed":{"summary":"Request IP is not allowlisted","value":{"error":"ip address is not in whitelist","ip":"203.0.113.10"}},"noSources":{"summary":"Subscription has no enabled sources","value":{"error":"you don't have any data in your subscription"}}}}}},"404":{"description":"Vehicle not found within the account source scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"Vehicle not found","value":{"error":"car not found","vin":"examplevin00000001"}}}}}},"422":{"description":"VIN must contain 16–19 ASCII letters/digits.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"examples":{"invalidVin":{"summary":"VIN too short","value":{"errors":{"vin":["The vin field must be between 16 and 19 characters."]}}}}}}},"503":{"description":"Search service is temporarily unavailable. Retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Search unavailable","value":{"error":"search service temporarily unavailable"}}}}},"headers":{"Retry-After":{"schema":{"type":"string","example":"5"},"description":"Delay in seconds."}}},"default":{"description":"Unexpected upstream/infrastructure failure (including an upstream 429 or 5xx). JSON and HTML/text bodies are possible. No universal requests-per-minute limit is configured on these public routes; account/upstream limits can still apply. Respect Retry-After when returned and use bounded backoff for temporary failures. The examples illustrate possible envelopes, not a guarantee of exact infrastructure text.","headers":{"Retry-After":{"description":"Optional retry delay in seconds or an HTTP date.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Framework failure","value":{"message":"Server Error"}},"rateLimit":{"summary":"Upstream rate limit","value":{"message":"Too Many Attempts."}}}},"text/html":{"schema":{"type":"string"},"examples":{"gateway":{"summary":"Gateway failure","value":"<html><body>502 Bad Gateway</body></html>"}}}}}}}},"/cars/{car_id}":{"get":{"operationId":"carById","tags":["Vehicles"],"summary":"Find a vehicle by ID","description":"Returns one car in data, including full public reports. Exact lookups can return recently archived cars while retained. Car-level reports are assembled from active listings; for a retained archived listing use /listing/{domain_id}/{listing_id}.\n\nEvery listing includes location_details with the same country/region/district/place shape. country is {id, name, iso}; other components are {id, name}. Missing components are null. Names use lang with dictionary fallbacks; unresolved IDs retain their ID with name:null. Existing textual source labels have id:null. The legacy location field retains its endpoint-specific format for compatibility. All visible listing IDs are collected from the complete response batch before bulk dictionary lookup (up to 1000 unique documents per request across both country and location indexes), never one request per car. Read location_details directly for display; /countries and /locations remain available for selectors and independent lookup. No city or parent is inferred from coordinates. /cars next_url preserves the effective lang across scroll pages. location_details participates in the car hash.","parameters":[{"name":"car_id","in":"path","required":true,"description":"Opaque internal id returned by /search or /cars. The page fills an available car ID after connecting your key. This is not a source listing ID.","schema":{"type":"string"},"example":"example-car-001"},{"name":"lang","in":"query","required":false,"description":"Response locale. Option translations are also limited by the account languages. The page selects its current language automatically.","schema":{"type":"string","enum":["en","ru","sq","pl","uk","bg"]}}],"responses":{"200":{"description":"Single vehicle with reports.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CarDetail"},"examples":{"vehicle":{"summary":"Detailed vehicle","value":{"data":{"id":"example-car-001","has_inspections":true,"has_history_reports":true,"year":2022,"vin":"EXAMPLEVIN00000001","brand":{"id":101,"name":"Example brand"},"model":{"id":201,"name":"Example model"},"vehicle_type":1,"generation_id":null,"variant_id":null,"trim_id":null,"seats":5,"doors":4,"cylinders":4,"steering_wheel_position":{"id":1,"name":"left"},"option_ids":[101],"listings":[{"external":{"id":"example-listing-001","domain":{"id":33,"name":"cars.example.com"},"url":"https://cars.example.com/listing/example-listing-001"},"archived":false,"title":{"en":"Example vehicle"},"odometer":32000,"location":{"iso":"DE","country":1,"position":{"lat":52.52,"lon":13.405}},"location_details":{"country":{"id":1,"name":"Germany","iso":"DE"},"region":null,"district":null,"place":null},"images":[{"original":"https://cars.example.com/images/example.jpg"}],"video":["https://cars.example.com/videos/example.mp4"],"created_at":"2026-09-01T10:00:00Z","last_seen_at":"2026-09-13T10:00:00Z","updated_at":"2026-09-13T10:00:00Z","price":{"price":25000,"currency":{"id":1,"name":"usd"},"negotiable":false,"history":[{"price":26000,"currency_id":1,"created_at":"2026-09-01T10:00:00Z"}]},"seller_type":null,"option_ids":[101],"is_auction":false,"current_bid":null,"auction_at":null,"availability":null,"is_manufacturer_certified":true,"has_history_reports":true,"condition":null,"keys_available":true,"damage":null,"second_damage":null,"airbag_state":null,"document_id":null}],"hash":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","inspections":[{"schema_version":1,"mapper_contract_version":1,"report_id":"example-inspection-001","status":"published","visibility":"public","language":"en","vehicle_ref":{"domain_id":33,"listing_id":"example-listing-001","site_car_id":123,"vin":"EXAMPLEVIN00000001"},"participants":[{"role_key":"inspector","name":"Example inspector","company_id":10,"user_id":20}],"conclusions":{"overall_result_key":"issue"},"inspection_blocks":[{"id":"block-1","key":"exterior","result_key":"issue"}],"checked_items":[{"id":"item-1","block_id":"block-1","block_key":"exterior","part_key":"front_door","part_label":"Front door","result_key":"issue","issue_type_keys":["scratch"],"severity_key":"minor","description":"Small surface scratch","evidence_media_ids":[],"measurements":[]}],"diagnostic_errors":[],"media":[{"id":"media-1","type_key":"photo","external_url":"https://cars.example.com/images/inspection.jpg","server_id":1,"sort_order":0}],"files":[],"limitations":[],"translations":{"language":"en","fallback_language":"en","terms":{"result":{"issue":"Issue"}},"missing":[],"taxonomy_available":true,"source_text_translated":false}}],"vehicle_history_reports":[{"schema_version":1,"mapper_contract_version":1,"report_id":"example-history-001","status":"published","visibility":"public","language":"en","vehicle_ref":{"domain_id":33,"listing_id":"example-listing-001","vin":"EXAMPLEVIN00000001"},"coverage":{"completeness_key":"partial","section_keys":["registration"]},"summary":{"first_registered_at":"2022-05-01","owner_change_count":1},"checks":[{"id":"check-1","type_key":"flood_total_loss_history","result_key":"unknown","count":null}],"events":[{"id":"event-1","type_key":"initial_registration","occurred_at":"2022-05-01","date_precision_key":"day","details":[]}],"media":[],"files":[],"limitations":[{"id":"limit-1","type_key":"other","description":"Synthetic example with partial source coverage"}],"translations":{"language":"en","fallback_language":"en","terms":{},"missing":[{"type":"event_type","key":"initial_registration","fallback_language":null}],"taxonomy_available":false,"source_text_translated":false}}]}}},"noReports":{"summary":"Vehicle without reports","value":{"data":{"id":"example-car-001","has_inspections":false,"has_history_reports":false,"year":2022,"vin":"EXAMPLEVIN00000001","brand":{"id":101,"name":"Example brand"},"model":{"id":201,"name":"Example model"},"vehicle_type":1,"generation_id":null,"variant_id":null,"trim_id":null,"seats":5,"doors":4,"cylinders":4,"steering_wheel_position":{"id":1,"name":"left"},"option_ids":[101],"listings":[{"external":{"id":"example-listing-001","domain":{"id":33,"name":"cars.example.com"},"url":"https://cars.example.com/listing/example-listing-001"},"archived":false,"title":null,"odometer":32000,"location":{"iso":"DE","country":1,"position":{"lat":52.52,"lon":13.405}},"location_details":{"country":{"id":1,"name":"Germany","iso":"DE"},"region":null,"district":null,"place":null},"images":[{"original":"https://cars.example.com/images/example.jpg"}],"video":[],"created_at":"2026-09-01T10:00:00Z","last_seen_at":"2026-09-13T10:00:00Z","updated_at":"2026-09-13T10:00:00Z","price":{"price":25000,"currency":{"id":1,"name":"usd"},"negotiable":false,"history":[{"price":26000,"currency_id":1,"created_at":"2026-09-01T10:00:00Z"}]},"seller_type":null,"option_ids":[101],"is_auction":false,"current_bid":null,"auction_at":null,"availability":null,"is_manufacturer_certified":true,"has_history_reports":false,"condition":null,"keys_available":true,"damage":null,"second_damage":null,"airbag_state":null,"document_id":null}],"hash":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","inspections":[],"vehicle_history_reports":[]}}}}}}},"400":{"description":"Search engine rejected the lookup.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid":{"summary":"Invalid lookup","value":{"error":"invalid request to search car by id","car_id":"invalid-value"}}}}}},"403":{"description":"API key, subscription, source access or IP restriction. Correct the account/access condition before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missingKey":{"summary":"API key is missing","value":{"error":"please add your api_key in get param"}},"invalidKey":{"summary":"API key is invalid","value":{"error":"wrong api key"}},"expiredSubscription":{"summary":"Subscription has expired","value":{"error":"your api subscription has expired"}},"inactiveSubscription":{"summary":"Subscription is inactive","value":{"error":"your api subscription is not active"}},"ipNotAllowed":{"summary":"Request IP is not allowlisted","value":{"error":"ip address is not in whitelist","ip":"203.0.113.10"}},"noSources":{"summary":"Subscription has no enabled sources","value":{"error":"you don't have any data in your subscription"}}}}}},"404":{"description":"Vehicle not found within the account source scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"Vehicle not found","value":{"error":"car not found","car_id":"example-car-001"}}}}}},"503":{"description":"Search service is temporarily unavailable. Retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Search unavailable","value":{"error":"search service temporarily unavailable"}}}}},"headers":{"Retry-After":{"schema":{"type":"string","example":"5"},"description":"Delay in seconds."}}},"default":{"description":"Unexpected upstream/infrastructure failure (including an upstream 429 or 5xx). JSON and HTML/text bodies are possible. No universal requests-per-minute limit is configured on these public routes; account/upstream limits can still apply. Respect Retry-After when returned and use bounded backoff for temporary failures. The examples illustrate possible envelopes, not a guarantee of exact infrastructure text.","headers":{"Retry-After":{"description":"Optional retry delay in seconds or an HTTP date.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Framework failure","value":{"message":"Server Error"}},"rateLimit":{"summary":"Upstream rate limit","value":{"message":"Too Many Attempts."}}}},"text/html":{"schema":{"type":"string"},"examples":{"gateway":{"summary":"Gateway failure","value":"<html><body>502 Bad Gateway</body></html>"}}}}}}}},"/listing/{domain_id}/{listing_id}":{"get":{"operationId":"listing","tags":["Vehicles"],"summary":"Find a vehicle by source listing","description":"Look up the exact source domain and listing ID pair. Returns the containing car, with reports for that specific listing. Select the matching listing from data.listings; other visible listings can also be present. Recently archived listings can be found while retained.\n\nEvery listing includes location_details with the same country/region/district/place shape. country is {id, name, iso}; other components are {id, name}. Missing components are null. Names use lang with dictionary fallbacks; unresolved IDs retain their ID with name:null. Existing textual source labels have id:null. The legacy location field retains its endpoint-specific format for compatibility. All visible listing IDs are collected from the complete response batch before bulk dictionary lookup (up to 1000 unique documents per request across both country and location indexes), never one request per car. Read location_details directly for display; /countries and /locations remain available for selectors and independent lookup. No city or parent is inferred from coordinates. /cars next_url preserves the effective lang across scroll pages. location_details participates in the car hash.","parameters":[{"name":"domain_id","in":"path","required":true,"description":"Enabled ID from /domains. The page fills an available domain/listing pair after connecting your key; both IDs must refer to the same listing.","schema":{"type":"integer","minimum":1},"example":33,"x-autofill":"domains"},{"name":"listing_id","in":"path","required":true,"description":"Source identifier from listings[].external.id. Must belong to the selected domain.","schema":{"type":"string"},"example":"example-listing-001"},{"name":"lang","in":"query","required":false,"description":"Response locale. Option translations are also limited by the account languages. The page selects its current language automatically.","schema":{"type":"string","enum":["en","ru","sq","pl","uk","bg"]}}],"responses":{"200":{"description":"Containing vehicle with reports attached for this listing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CarDetail"},"examples":{"listing":{"summary":"Listing lookup","value":{"data":{"id":"example-car-001","has_inspections":true,"has_history_reports":true,"year":2022,"vin":"EXAMPLEVIN00000001","brand":{"id":101,"name":"Example brand"},"model":{"id":201,"name":"Example model"},"vehicle_type":1,"generation_id":null,"variant_id":null,"trim_id":null,"seats":5,"doors":4,"cylinders":4,"steering_wheel_position":{"id":1,"name":"left"},"option_ids":[101],"listings":[{"external":{"id":"example-listing-001","domain":{"id":33,"name":"cars.example.com"},"url":"https://cars.example.com/listing/example-listing-001"},"archived":false,"title":{"en":"Example vehicle"},"odometer":32000,"location":{"iso":"DE","country":1,"position":{"lat":52.52,"lon":13.405}},"location_details":{"country":{"id":1,"name":"Germany","iso":"DE"},"region":null,"district":null,"place":null},"images":[{"original":"https://cars.example.com/images/example.jpg"}],"video":["https://cars.example.com/videos/example.mp4"],"created_at":"2026-09-01T10:00:00Z","last_seen_at":"2026-09-13T10:00:00Z","updated_at":"2026-09-13T10:00:00Z","price":{"price":25000,"currency":{"id":1,"name":"usd"},"negotiable":false,"history":[{"price":26000,"currency_id":1,"created_at":"2026-09-01T10:00:00Z"}]},"seller_type":null,"option_ids":[101],"is_auction":false,"current_bid":null,"auction_at":null,"availability":null,"is_manufacturer_certified":true,"has_history_reports":true,"condition":null,"keys_available":true,"damage":null,"second_damage":null,"airbag_state":null,"document_id":null}],"hash":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","inspections":[{"schema_version":1,"mapper_contract_version":1,"report_id":"example-inspection-001","status":"published","visibility":"public","language":"en","vehicle_ref":{"domain_id":33,"listing_id":"example-listing-001","site_car_id":123,"vin":"EXAMPLEVIN00000001"},"participants":[{"role_key":"inspector","name":"Example inspector","company_id":10,"user_id":20}],"conclusions":{"overall_result_key":"issue"},"inspection_blocks":[{"id":"block-1","key":"exterior","result_key":"issue"}],"checked_items":[{"id":"item-1","block_id":"block-1","block_key":"exterior","part_key":"front_door","part_label":"Front door","result_key":"issue","issue_type_keys":["scratch"],"severity_key":"minor","description":"Small surface scratch","evidence_media_ids":[],"measurements":[]}],"diagnostic_errors":[],"media":[{"id":"media-1","type_key":"photo","external_url":"https://cars.example.com/images/inspection.jpg","server_id":1,"sort_order":0}],"files":[],"limitations":[],"translations":{"language":"en","fallback_language":"en","terms":{"result":{"issue":"Issue"}},"missing":[],"taxonomy_available":true,"source_text_translated":false}}],"vehicle_history_reports":[{"schema_version":1,"mapper_contract_version":1,"report_id":"example-history-001","status":"published","visibility":"public","language":"en","vehicle_ref":{"domain_id":33,"listing_id":"example-listing-001","vin":"EXAMPLEVIN00000001"},"coverage":{"completeness_key":"partial","section_keys":["registration"]},"summary":{"first_registered_at":"2022-05-01","owner_change_count":1},"checks":[{"id":"check-1","type_key":"flood_total_loss_history","result_key":"unknown","count":null}],"events":[{"id":"event-1","type_key":"initial_registration","occurred_at":"2022-05-01","date_precision_key":"day","details":[]}],"media":[],"files":[],"limitations":[{"id":"limit-1","type_key":"other","description":"Synthetic example with partial source coverage"}],"translations":{"language":"en","fallback_language":"en","terms":{},"missing":[{"type":"event_type","key":"initial_registration","fallback_language":null}],"taxonomy_available":false,"source_text_translated":false}}]}}}}}}},"400":{"description":"Search engine rejected the lookup.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid":{"summary":"Invalid lookup","value":{"error":"invalid request to search listing","domain_id":33,"listing_id":"invalid-value"}}}}}},"403":{"description":"Authentication failure or domain not enabled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missingKey":{"summary":"API key is missing","value":{"error":"please add your api_key in get param"}},"invalidKey":{"summary":"API key is invalid","value":{"error":"wrong api key"}},"expiredSubscription":{"summary":"Subscription has expired","value":{"error":"your api subscription has expired"}},"inactiveSubscription":{"summary":"Subscription is inactive","value":{"error":"your api subscription is not active"}},"ipNotAllowed":{"summary":"Request IP is not allowlisted","value":{"error":"ip address is not in whitelist","ip":"203.0.113.10"}},"noSources":{"summary":"Subscription has no enabled sources","value":{"error":"you don't have any data in your subscription"}},"domain":{"summary":"Domain denied by middleware","value":{"error":"invalid domain_id, you don't have access to this domain"}},"disabled":{"summary":"Domain disabled by access service","value":{"error":"domain_id is not enabled for this api key","domain_id":999999}},"noSite":{"summary":"No source access","value":{"error":"you don't have access to any site"}},"invalidDomain":{"summary":"Zero domain ID","value":{"error":"invalid domain_id"}}}}}},"404":{"description":"Listing pair not found. A nonnumeric domain path fails route matching and can return a framework message instead.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"Listing not found","value":{"error":"listing not found by (domain_id, listing_id)","domain_id":33,"listing_id":"example-listing-001"}},"route":{"summary":"Route not found","value":{"message":"Not Found"}}}}}},"503":{"description":"Search service is temporarily unavailable. Retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Search unavailable","value":{"error":"search service temporarily unavailable"}}}}},"headers":{"Retry-After":{"schema":{"type":"string","example":"5"},"description":"Delay in seconds."}}},"default":{"description":"Unexpected upstream/infrastructure failure (including an upstream 429 or 5xx). JSON and HTML/text bodies are possible. No universal requests-per-minute limit is configured on these public routes; account/upstream limits can still apply. Respect Retry-After when returned and use bounded backoff for temporary failures. The examples illustrate possible envelopes, not a guarantee of exact infrastructure text.","headers":{"Retry-After":{"description":"Optional retry delay in seconds or an HTTP date.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Framework failure","value":{"message":"Server Error"}},"rateLimit":{"summary":"Upstream rate limit","value":{"message":"Too Many Attempts."}}}},"text/html":{"schema":{"type":"string"},"examples":{"gateway":{"summary":"Gateway failure","value":"<html><body>502 Bad Gateway</body></html>"}}}}}}}},"/listing-fields":{"get":{"operationId":"listingFields","tags":["Dictionaries"],"summary":"Available listing fields","description":"Additional listing fields are discovered with authenticated GET /listing-fields, optionally narrowed by domains[]. The catalogue is private to the key and enabled domains. Never hardcode field keys or types from examples. Only filterable=true definitions can be filtered; operators and constraints come from the catalogue. Keys are flat, with one global type and optional homogeneous array cardinality. JSON objects are stored-only.\n\nUse custom_fields[key][eq]=value, custom_fields[key][in][]=value or custom_fields[key][exists]=true/false. Numbers and dates additionally support gt/gte/lt/lte. Boolean eq=false means the exact false value, not absence. For arrays a matching element satisfies a comparison. Use eq, in or a non-conflicting lower/upper range; exists is standalone. Maximum 20 fields, 100 values per in. Monetary comparisons require custom_fields[key][currency]=cad (the listing native currency); there is no conversion. These conditions, domain access/selection, activity and other listing constraints must match the same nested listing, preventing matches across different ads of one car. A response may still contain other visible listings.\n\nUnknown or unavailable fields, unsupported operators and invalid values return 422; unavailable catalogue returns 503. Stored-only values remain in listings[].source_data; indexed values appear in listings[].custom_fields for that listing/domain. Preserve 0, false and arrays; missing/null means no indexed value. Existing source_data is unchanged, including vhr_url. Newly published fields populate on subsequent normal imports, without historical backfill. Sorting and aggregations are not supported in this stage. /cars pins the normalized conditions and field contract for the cursor: follow next_url unchanged or scroll_id alone; changing conditions or an incompatible/missing contract requires a new scroll (422).","parameters":[{"name":"domains[]","in":"query","required":false,"description":"Optional source scope. Use IDs returned by GET /domains. Omit to use all enabled domains. Repeat the bracketed parameter: domains[]=33&domains[]=34. Every ID must be enabled for this key.","schema":{"type":"array","minItems":1,"uniqueItems":true,"items":{"type":"integer","minimum":1}},"style":"form","explode":true,"x-autofill":"domains"},{"name":"lang","in":"query","required":false,"description":"Response locale. Option translations are also limited by the account languages. The page selects its current language automatically.","schema":{"type":"string","enum":["en","ru","sq","pl","uk","bg"]}}],"responses":{"200":{"description":"Authorized definitions and domain-specific notes. No source extraction paths or private domain settings.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListingFieldCatalogue"},"examples":{"empty":{"summary":"Synthetic empty catalogue","value":{"schema_version":1,"revision":"1","fields":[],"bindings":[]}}}}}},"403":{"description":"API key, subscription, source access or IP restriction. Correct the account/access condition before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missingKey":{"summary":"API key is missing","value":{"error":"please add your api_key in get param"}},"invalidKey":{"summary":"API key is invalid","value":{"error":"wrong api key"}},"expiredSubscription":{"summary":"Subscription has expired","value":{"error":"your api subscription has expired"}},"inactiveSubscription":{"summary":"Subscription is inactive","value":{"error":"your api subscription is not active"}},"ipNotAllowed":{"summary":"Request IP is not allowlisted","value":{"error":"ip address is not in whitelist","ip":"203.0.113.10"}},"noSources":{"summary":"Subscription has no enabled sources","value":{"error":"you don't have any data in your subscription"}}}}}},"422":{"description":"Invalid or unauthorized domain scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"examples":{"domain":{"summary":"A selected domain is not enabled","value":{"errors":{"domains":["These domain IDs are not enabled for this API key: 999999"]}}}}}}},"503":{"description":"Search service is temporarily unavailable. Retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Search unavailable","value":{"error":"search service temporarily unavailable"}}}}},"headers":{"Retry-After":{"schema":{"type":"string","example":"5"},"description":"Delay in seconds."}}},"default":{"description":"Unexpected upstream/infrastructure failure (including an upstream 429 or 5xx). JSON and HTML/text bodies are possible. No universal requests-per-minute limit is configured on these public routes; account/upstream limits can still apply. Respect Retry-After when returned and use bounded backoff for temporary failures. The examples illustrate possible envelopes, not a guarantee of exact infrastructure text.","headers":{"Retry-After":{"description":"Optional retry delay in seconds or an HTTP date.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Framework failure","value":{"message":"Server Error"}},"rateLimit":{"summary":"Upstream rate limit","value":{"message":"Too Many Attempts."}}}},"text/html":{"schema":{"type":"string"},"examples":{"gateway":{"summary":"Gateway failure","value":"<html><body>502 Bad Gateway</body></html>"}}}}}}}},"/domains":{"get":{"operationId":"domains","tags":["Dictionaries"],"summary":"Available source domains","description":"Only returns sources enabled for this API key. Use these IDs in domains[] and listing lookups. No favicon or private domain configuration is exposed.","parameters":[{"name":"search","in":"query","required":false,"description":"Case-insensitive partial match on name or base_url.","schema":{"type":"string","maxLength":200}},{"name":"lang","in":"query","required":false,"description":"Response locale. Option translations are also limited by the account languages. The page selects its current language automatically.","schema":{"type":"string","enum":["en","ru","sq","pl","uk","bg"]}}],"responses":{"200":{"description":"Bare array of enabled domains.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}},"examples":{"sources":{"summary":"Enabled source","value":[{"id":33,"name":"Example marketplace","base_url":"cars.example.com"}]},"empty":{"summary":"No search matches","value":[]}}}}},"403":{"description":"API key, subscription, source access or IP restriction. Correct the account/access condition before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missingKey":{"summary":"API key is missing","value":{"error":"please add your api_key in get param"}},"invalidKey":{"summary":"API key is invalid","value":{"error":"wrong api key"}},"expiredSubscription":{"summary":"Subscription has expired","value":{"error":"your api subscription has expired"}},"inactiveSubscription":{"summary":"Subscription is inactive","value":{"error":"your api subscription is not active"}},"ipNotAllowed":{"summary":"Request IP is not allowlisted","value":{"error":"ip address is not in whitelist","ip":"203.0.113.10"}},"noSources":{"summary":"Subscription has no enabled sources","value":{"error":"you don't have any data in your subscription"}}}}}},"422":{"description":"search must be a string of at most 200 characters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"examples":{"invalid":{"summary":"Array instead of text","value":{"message":"The given data was invalid.","errors":{"search":["The search field must be a string."]}}}}}}},"default":{"description":"Unexpected upstream/infrastructure failure (including an upstream 429 or 5xx). JSON and HTML/text bodies are possible. No universal requests-per-minute limit is configured on these public routes; account/upstream limits can still apply. Respect Retry-After when returned and use bounded backoff for temporary failures. The examples illustrate possible envelopes, not a guarantee of exact infrastructure text.","headers":{"Retry-After":{"description":"Optional retry delay in seconds or an HTTP date.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Framework failure","value":{"message":"Server Error"}},"rateLimit":{"summary":"Upstream rate limit","value":{"message":"Too Many Attempts."}}}},"text/html":{"schema":{"type":"string"},"examples":{"gateway":{"summary":"Gateway failure","value":"<html><body>502 Bad Gateway</body></html>"}}}}}}}},"/brands":{"get":{"operationId":"brands","tags":["Dictionaries"],"summary":"Vehicle brands","description":"All reads use the published Elasticsearch catalogue. Omitted vehicle_type means automobiles; motorcycle/2 selects motorcycles only. Brand flags cars/motorcycles define membership; shared brands can occur in both scopes. Legacy rows without a vehicle type/brand car flag count as automobiles only. Unknown, inactive or wrong-type parents return empty data. These are shared dictionaries, not subscription inventory; a dictionary entry does not guarantee available listings. Requires api_key and an active subscription.\n\nPaged responses are {data, meta}. Default/maximum per_page=100; minimum 1. Numeric ID ascending order gives stable traversal for an unchanged catalogue, including query results. meta.total is exact; with after_id it counts remaining matches after that ID. meta.page and last_page are relative to the remaining set in cursor mode. Follow next_page with the same filters for offset pagination, or follow next_after_id as after_id with page omitted for full traversal. At the 10k offset boundary next_page is null but has_more and next_after_id still allow continuation. Stop when has_more=false. There is no frozen snapshot across requests: updates can change totals; restart periodically when synchronizing. Invalid values, conflicting pagination or an excessive offset return 422. Elasticsearch unavailability or an incomplete/stale configuration publication returns 503 with Retry-After: 5. Examples use synthetic IDs.\n\nCompatibility: without page, per_page or after_id this returns the existing bare array (up to 10000 without query, up to 50 with query, existing name/relevance sort). vehicle_type alone does not change the envelope. Internal marker documents without a brand ID are excluded. Brand IDs are independent of source IDs. icon_url is omitted on api.auctionsapi.com.","parameters":[{"name":"vehicle_type","in":"query","required":false,"description":"Dictionary scope: automobile/1 (default), motorcycle/2. Explicit empty or invalid values return 422. Keep the same type throughout brand → model → generation → variant/trim lookups and in inventory filters.","schema":{"type":"string","enum":["automobile","motorcycle","1","2"],"default":"automobile"}},{"name":"query","in":"query","required":false,"description":"Optional name or synonym phrase. Blank disables search. Prefix/substring matching is case-insensitive; * and ? are literal characters. Paged results stay ordered by numeric ID, not relevance.","schema":{"type":"string","maxLength":200}},{"name":"page","in":"query","required":false,"description":"Offset page. page × per_page must be ≤ 10000. Cannot be combined with after_id. Sending page enables the paged envelope on /brands and /models.","schema":{"type":"integer","minimum":1,"maximum":10000,"default":1}},{"name":"per_page","in":"query","required":false,"description":"Page size, default/maximum 100. Sending per_page enables the paged envelope on /brands and /models. Use per_page, not inventory-search perPage.","schema":{"type":"integer","minimum":1,"maximum":100,"default":100}},{"name":"after_id","in":"query","required":false,"description":"Cursor: return IDs greater than the last returned ID. Start with page=1 or per_page=100, then send meta.next_after_id as after_id, omitting page and keeping other filters unchanged. No 10k traversal limit. Sending after_id enables the paged envelope on legacy endpoints.","schema":{"type":"integer","minimum":1}},{"name":"lang","in":"query","required":false,"description":"Response locale. Option translations are also limited by the account languages. The page selects its current language automatically.","schema":{"type":"string","enum":["en","ru","sq","pl","uk","bg"]}}],"responses":{"200":{"description":"Legacy array, or paged envelope when any pagination parameter is supplied.","content":{"application/json":{"schema":{"oneOf":[{"type":"array","items":{"$ref":"#/components/schemas/Brand"}},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Brand"}},"meta":{"$ref":"#/components/schemas/VehicleDictionaryMeta"}},"required":["data","meta"]}]},"examples":{"brands":{"summary":"Legacy car brands","value":[{"id":101,"name":"Example brand","icon_url":null}]},"paged":{"summary":"With page=1","value":{"data":[{"id":101,"name":"Example brand","icon_url":null}],"meta":{"vehicle_type":1,"page":1,"per_page":100,"total":1,"last_page":1,"has_more":false,"next_page":null,"next_after_id":null}}},"empty":{"summary":"Empty page","value":{"data":[],"meta":{"vehicle_type":1,"page":1,"per_page":100,"total":0,"last_page":1,"has_more":false,"next_page":null,"next_after_id":null}}}}}}},"403":{"description":"API key, subscription, source access or IP restriction. Correct the account/access condition before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missingKey":{"summary":"API key is missing","value":{"error":"please add your api_key in get param"}},"invalidKey":{"summary":"API key is invalid","value":{"error":"wrong api key"}},"expiredSubscription":{"summary":"Subscription has expired","value":{"error":"your api subscription has expired"}},"inactiveSubscription":{"summary":"Subscription is inactive","value":{"error":"your api subscription is not active"}},"ipNotAllowed":{"summary":"Request IP is not allowlisted","value":{"error":"ip address is not in whitelist","ip":"203.0.113.10"}},"noSources":{"summary":"Subscription has no enabled sources","value":{"error":"you don't have any data in your subscription"}}}}}},"422":{"description":"Invalid vehicle type, parent ID, query, page size, conflicting page/after_id or excessive offset.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"examples":{"vehicleType":{"summary":"Unsupported type","value":{"errors":{"vehicle_type":["The selected vehicle type is invalid."]}}},"pageSize":{"summary":"Page size exceeds 100","value":{"errors":{"per_page":["The per page field must not be greater than 100."]}}},"window":{"summary":"Offset exceeds 10000","value":{"errors":{"page":["The page × per_page result window must not exceed 10000."]}}}}}}},"503":{"description":"Search service is temporarily unavailable. Retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Search unavailable","value":{"error":"search service temporarily unavailable"}}}}},"headers":{"Retry-After":{"schema":{"type":"string","example":"5"},"description":"Delay in seconds."}}},"default":{"description":"Unexpected upstream/infrastructure failure (including an upstream 429 or 5xx). JSON and HTML/text bodies are possible. No universal requests-per-minute limit is configured on these public routes; account/upstream limits can still apply. Respect Retry-After when returned and use bounded backoff for temporary failures. The examples illustrate possible envelopes, not a guarantee of exact infrastructure text.","headers":{"Retry-After":{"description":"Optional retry delay in seconds or an HTTP date.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Framework failure","value":{"message":"Server Error"}},"rateLimit":{"summary":"Upstream rate limit","value":{"message":"Too Many Attempts."}}}},"text/html":{"schema":{"type":"string"},"examples":{"gateway":{"summary":"Gateway failure","value":"<html><body>502 Bad Gateway</body></html>"}}}}}}}},"/models/{brand_id}":{"get":{"operationId":"models","tags":["Dictionaries"],"summary":"Vehicle models","description":"All reads use the published Elasticsearch catalogue. Omitted vehicle_type means automobiles; motorcycle/2 selects motorcycles only. Brand flags cars/motorcycles define membership; shared brands can occur in both scopes. Legacy rows without a vehicle type/brand car flag count as automobiles only. Unknown, inactive or wrong-type parents return empty data. These are shared dictionaries, not subscription inventory; a dictionary entry does not guarantee available listings. Requires api_key and an active subscription.\n\nPaged responses are {data, meta}. Default/maximum per_page=100; minimum 1. Numeric ID ascending order gives stable traversal for an unchanged catalogue, including query results. meta.total is exact; with after_id it counts remaining matches after that ID. meta.page and last_page are relative to the remaining set in cursor mode. Follow next_page with the same filters for offset pagination, or follow next_after_id as after_id with page omitted for full traversal. At the 10k offset boundary next_page is null but has_more and next_after_id still allow continuation. Stop when has_more=false. There is no frozen snapshot across requests: updates can change totals; restart periodically when synchronizing. Invalid values, conflicting pagination or an excessive offset return 422. Elasticsearch unavailability or an incomplete/stale configuration publication returns 503 with Retry-After: 5. Examples use synthetic IDs.\n\nCompatibility: without page, per_page or after_id this returns the existing bare array of up to 1000 models, retaining the existing search order. Embedded generations retain their legacy {name,from,to} shape and are not independently paginated/searched. Fetch /generations/{model_id} for generation IDs and full pagination.","parameters":[{"name":"brand_id","in":"path","required":true,"description":"Positive brand ID from /brands for the same vehicle_type.","schema":{"type":"integer","minimum":1},"example":101,"x-autofill":"brands"},{"name":"vehicle_type","in":"query","required":false,"description":"Dictionary scope: automobile/1 (default), motorcycle/2. Explicit empty or invalid values return 422. Keep the same type throughout brand → model → generation → variant/trim lookups and in inventory filters.","schema":{"type":"string","enum":["automobile","motorcycle","1","2"],"default":"automobile"}},{"name":"query","in":"query","required":false,"description":"Optional name or synonym phrase. Blank disables search. Prefix/substring matching is case-insensitive; * and ? are literal characters. Paged results stay ordered by numeric ID, not relevance.","schema":{"type":"string","maxLength":200}},{"name":"page","in":"query","required":false,"description":"Offset page. page × per_page must be ≤ 10000. Cannot be combined with after_id. Sending page enables the paged envelope on /brands and /models.","schema":{"type":"integer","minimum":1,"maximum":10000,"default":1}},{"name":"per_page","in":"query","required":false,"description":"Page size, default/maximum 100. Sending per_page enables the paged envelope on /brands and /models. Use per_page, not inventory-search perPage.","schema":{"type":"integer","minimum":1,"maximum":100,"default":100}},{"name":"after_id","in":"query","required":false,"description":"Cursor: return IDs greater than the last returned ID. Start with page=1 or per_page=100, then send meta.next_after_id as after_id, omitting page and keeping other filters unchanged. No 10k traversal limit. Sending after_id enables the paged envelope on legacy endpoints.","schema":{"type":"integer","minimum":1}},{"name":"lang","in":"query","required":false,"description":"Response locale. Option translations are also limited by the account languages. The page selects its current language automatically.","schema":{"type":"string","enum":["en","ru","sq","pl","uk","bg"]}}],"responses":{"200":{"description":"Legacy array, or paged envelope when any pagination parameter is supplied.","content":{"application/json":{"schema":{"oneOf":[{"type":"array","items":{"$ref":"#/components/schemas/Model"}},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Model"}},"meta":{"$ref":"#/components/schemas/VehicleDictionaryMeta"}},"required":["data","meta"]}]},"examples":{"models":{"summary":"Legacy car models","value":[{"id":201,"name":"Example model","generations":[{"name":"Example generation","from":2020,"to":null}]}]},"paged":{"summary":"Motorcycle models with page=1&vehicle_type=motorcycle","value":{"data":[{"id":202,"name":"Example motorcycle model","generations":[]}],"meta":{"vehicle_type":2,"page":1,"per_page":100,"total":1,"last_page":1,"has_more":false,"next_page":null,"next_after_id":null}}},"empty":{"summary":"No matches or wrong-type brand","value":[]}}}}},"403":{"description":"API key, subscription, source access or IP restriction. Correct the account/access condition before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missingKey":{"summary":"API key is missing","value":{"error":"please add your api_key in get param"}},"invalidKey":{"summary":"API key is invalid","value":{"error":"wrong api key"}},"expiredSubscription":{"summary":"Subscription has expired","value":{"error":"your api subscription has expired"}},"inactiveSubscription":{"summary":"Subscription is inactive","value":{"error":"your api subscription is not active"}},"ipNotAllowed":{"summary":"Request IP is not allowlisted","value":{"error":"ip address is not in whitelist","ip":"203.0.113.10"}},"noSources":{"summary":"Subscription has no enabled sources","value":{"error":"you don't have any data in your subscription"}}}}}},"422":{"description":"Invalid vehicle type, parent ID, query, page size, conflicting page/after_id or excessive offset.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"examples":{"vehicleType":{"summary":"Unsupported type","value":{"errors":{"vehicle_type":["The selected vehicle type is invalid."]}}},"pageSize":{"summary":"Page size exceeds 100","value":{"errors":{"per_page":["The per page field must not be greater than 100."]}}},"window":{"summary":"Offset exceeds 10000","value":{"errors":{"page":["The page × per_page result window must not exceed 10000."]}}}}}}},"503":{"description":"Search service is temporarily unavailable. Retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Search unavailable","value":{"error":"search service temporarily unavailable"}}}}},"headers":{"Retry-After":{"schema":{"type":"string","example":"5"},"description":"Delay in seconds."}}},"default":{"description":"Unexpected upstream/infrastructure failure (including an upstream 429 or 5xx). JSON and HTML/text bodies are possible. No universal requests-per-minute limit is configured on these public routes; account/upstream limits can still apply. Respect Retry-After when returned and use bounded backoff for temporary failures. The examples illustrate possible envelopes, not a guarantee of exact infrastructure text.","headers":{"Retry-After":{"description":"Optional retry delay in seconds or an HTTP date.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Framework failure","value":{"message":"Server Error"}},"rateLimit":{"summary":"Upstream rate limit","value":{"message":"Too Many Attempts."}}}},"text/html":{"schema":{"type":"string"},"examples":{"gateway":{"summary":"Gateway failure","value":"<html><body>502 Bad Gateway</body></html>"}}}}}}}},"/generations/{model_id}":{"get":{"operationId":"generations","tags":["Dictionaries"],"summary":"Vehicle generations","description":"All reads use the published Elasticsearch catalogue. Omitted vehicle_type means automobiles; motorcycle/2 selects motorcycles only. Brand flags cars/motorcycles define membership; shared brands can occur in both scopes. Legacy rows without a vehicle type/brand car flag count as automobiles only. Unknown, inactive or wrong-type parents return empty data. These are shared dictionaries, not subscription inventory; a dictionary entry does not guarantee available listings. Requires api_key and an active subscription.\n\nPaged responses are {data, meta}. Default/maximum per_page=100; minimum 1. Numeric ID ascending order gives stable traversal for an unchanged catalogue, including query results. meta.total is exact; with after_id it counts remaining matches after that ID. meta.page and last_page are relative to the remaining set in cursor mode. Follow next_page with the same filters for offset pagination, or follow next_after_id as after_id with page omitted for full traversal. At the 10k offset boundary next_page is null but has_more and next_after_id still allow continuation. Stop when has_more=false. There is no frozen snapshot across requests: updates can change totals; restart periodically when synchronizing. Invalid values, conflicting pagination or an excessive offset return 422. Elasticsearch unavailability or an incomplete/stale configuration publication returns 503 with Retry-After: 5. Examples use synthetic IDs.\n\nReturns active generations from the generation index; retired/deleted rows are excluded. query also searches ordinal and code. from_year/to_year are production years, unlike embedded legacy generation from/to fields.","parameters":[{"name":"model_id","in":"path","required":true,"description":"Positive model_id from the preceding dictionary for the same vehicle_type.","schema":{"type":"integer","minimum":1},"example":201},{"name":"vehicle_type","in":"query","required":false,"description":"Dictionary scope: automobile/1 (default), motorcycle/2. Explicit empty or invalid values return 422. Keep the same type throughout brand → model → generation → variant/trim lookups and in inventory filters.","schema":{"type":"string","enum":["automobile","motorcycle","1","2"],"default":"automobile"}},{"name":"query","in":"query","required":false,"description":"Optional name or synonym phrase. Blank disables search. Prefix/substring matching is case-insensitive; * and ? are literal characters. Paged results stay ordered by numeric ID, not relevance.","schema":{"type":"string","maxLength":200}},{"name":"page","in":"query","required":false,"description":"Offset page. page × per_page must be ≤ 10000. Cannot be combined with after_id. Sending page enables the paged envelope on /brands and /models.","schema":{"type":"integer","minimum":1,"maximum":10000,"default":1}},{"name":"per_page","in":"query","required":false,"description":"Page size, default/maximum 100. Sending per_page enables the paged envelope on /brands and /models. Use per_page, not inventory-search perPage.","schema":{"type":"integer","minimum":1,"maximum":100,"default":100}},{"name":"after_id","in":"query","required":false,"description":"Cursor: return IDs greater than the last returned ID. Start with page=1 or per_page=100, then send meta.next_after_id as after_id, omitting page and keeping other filters unchanged. No 10k traversal limit. Sending after_id enables the paged envelope on legacy endpoints.","schema":{"type":"integer","minimum":1}},{"name":"lang","in":"query","required":false,"description":"Response locale. Option translations are also limited by the account languages. The page selects its current language automatically.","schema":{"type":"string","enum":["en","ru","sq","pl","uk","bg"]}}],"responses":{"200":{"description":"Always a paged envelope; empty for unknown or wrong-type parents.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/VehicleGeneration"}},"meta":{"$ref":"#/components/schemas/VehicleDictionaryMeta"}},"required":["data","meta"]},"examples":{"page":{"summary":"First page","value":{"data":[{"id":301,"name":"Example generation","brand_id":101,"model_id":201,"vehicle_type":1,"from_year":2020,"to_year":null,"ordinal":null,"code":"EX1"}],"meta":{"vehicle_type":1,"page":1,"per_page":100,"total":1,"last_page":1,"has_more":false,"next_page":null,"next_after_id":null}}},"empty":{"summary":"No matches","value":{"data":[],"meta":{"vehicle_type":1,"page":1,"per_page":100,"total":0,"last_page":1,"has_more":false,"next_page":null,"next_after_id":null}}}}}}},"403":{"description":"API key, subscription, source access or IP restriction. Correct the account/access condition before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missingKey":{"summary":"API key is missing","value":{"error":"please add your api_key in get param"}},"invalidKey":{"summary":"API key is invalid","value":{"error":"wrong api key"}},"expiredSubscription":{"summary":"Subscription has expired","value":{"error":"your api subscription has expired"}},"inactiveSubscription":{"summary":"Subscription is inactive","value":{"error":"your api subscription is not active"}},"ipNotAllowed":{"summary":"Request IP is not allowlisted","value":{"error":"ip address is not in whitelist","ip":"203.0.113.10"}},"noSources":{"summary":"Subscription has no enabled sources","value":{"error":"you don't have any data in your subscription"}}}}}},"422":{"description":"Invalid vehicle type, parent ID, query, page size, conflicting page/after_id or excessive offset.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"examples":{"vehicleType":{"summary":"Unsupported type","value":{"errors":{"vehicle_type":["The selected vehicle type is invalid."]}}},"pageSize":{"summary":"Page size exceeds 100","value":{"errors":{"per_page":["The per page field must not be greater than 100."]}}},"window":{"summary":"Offset exceeds 10000","value":{"errors":{"page":["The page × per_page result window must not exceed 10000."]}}}}}}},"503":{"description":"Search service is temporarily unavailable. Retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Search unavailable","value":{"error":"search service temporarily unavailable"}}}}},"headers":{"Retry-After":{"schema":{"type":"string","example":"5"},"description":"Delay in seconds."}}},"default":{"description":"Unexpected upstream/infrastructure failure (including an upstream 429 or 5xx). JSON and HTML/text bodies are possible. No universal requests-per-minute limit is configured on these public routes; account/upstream limits can still apply. Respect Retry-After when returned and use bounded backoff for temporary failures. The examples illustrate possible envelopes, not a guarantee of exact infrastructure text.","headers":{"Retry-After":{"description":"Optional retry delay in seconds or an HTTP date.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Framework failure","value":{"message":"Server Error"}},"rateLimit":{"summary":"Upstream rate limit","value":{"message":"Too Many Attempts."}}}},"text/html":{"schema":{"type":"string"},"examples":{"gateway":{"summary":"Gateway failure","value":"<html><body>502 Bad Gateway</body></html>"}}}}}}}},"/trims/{generation_id}":{"get":{"operationId":"trims","tags":["Dictionaries"],"summary":"Vehicle trims","description":"All reads use the published Elasticsearch catalogue. Omitted vehicle_type means automobiles; motorcycle/2 selects motorcycles only. Brand flags cars/motorcycles define membership; shared brands can occur in both scopes. Legacy rows without a vehicle type/brand car flag count as automobiles only. Unknown, inactive or wrong-type parents return empty data. These are shared dictionaries, not subscription inventory; a dictionary entry does not guarantee available listings. Requires api_key and an active subscription.\n\nPaged responses are {data, meta}. Default/maximum per_page=100; minimum 1. Numeric ID ascending order gives stable traversal for an unchanged catalogue, including query results. meta.total is exact; with after_id it counts remaining matches after that ID. meta.page and last_page are relative to the remaining set in cursor mode. Follow next_page with the same filters for offset pagination, or follow next_after_id as after_id with page omitted for full traversal. At the 10k offset boundary next_page is null but has_more and next_after_id still allow continuation. Stop when has_more=false. There is no frozen snapshot across requests: updates can change totals; restart periodically when synchronizing. Invalid values, conflicting pagination or an excessive offset return 422. Elasticsearch unavailability or an incomplete/stale configuration publication returns 503 with Retry-After: 5. Examples use synthetic IDs.\n\nReturns active trims from the trim index. Trims are equipment grades. Retired/deleted trims are excluded. A trim and variant belonging to the same generation are not automatically a verified compatible combination.","parameters":[{"name":"generation_id","in":"path","required":true,"description":"Positive generation_id from the preceding dictionary for the same vehicle_type.","schema":{"type":"integer","minimum":1},"example":301},{"name":"vehicle_type","in":"query","required":false,"description":"Dictionary scope: automobile/1 (default), motorcycle/2. Explicit empty or invalid values return 422. Keep the same type throughout brand → model → generation → variant/trim lookups and in inventory filters.","schema":{"type":"string","enum":["automobile","motorcycle","1","2"],"default":"automobile"}},{"name":"query","in":"query","required":false,"description":"Optional name or synonym phrase. Blank disables search. Prefix/substring matching is case-insensitive; * and ? are literal characters. Paged results stay ordered by numeric ID, not relevance.","schema":{"type":"string","maxLength":200}},{"name":"page","in":"query","required":false,"description":"Offset page. page × per_page must be ≤ 10000. Cannot be combined with after_id. Sending page enables the paged envelope on /brands and /models.","schema":{"type":"integer","minimum":1,"maximum":10000,"default":1}},{"name":"per_page","in":"query","required":false,"description":"Page size, default/maximum 100. Sending per_page enables the paged envelope on /brands and /models. Use per_page, not inventory-search perPage.","schema":{"type":"integer","minimum":1,"maximum":100,"default":100}},{"name":"after_id","in":"query","required":false,"description":"Cursor: return IDs greater than the last returned ID. Start with page=1 or per_page=100, then send meta.next_after_id as after_id, omitting page and keeping other filters unchanged. No 10k traversal limit. Sending after_id enables the paged envelope on legacy endpoints.","schema":{"type":"integer","minimum":1}},{"name":"lang","in":"query","required":false,"description":"Response locale. Option translations are also limited by the account languages. The page selects its current language automatically.","schema":{"type":"string","enum":["en","ru","sq","pl","uk","bg"]}}],"responses":{"200":{"description":"Always a paged envelope; empty for unknown or wrong-type parents.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/VehicleConfigurationEntry"}},"meta":{"$ref":"#/components/schemas/VehicleDictionaryMeta"}},"required":["data","meta"]},"examples":{"page":{"summary":"First page","value":{"data":[{"id":401,"name":"Example trim","brand_id":101,"model_id":201,"generation_id":301,"vehicle_type":1}],"meta":{"vehicle_type":1,"page":1,"per_page":100,"total":1,"last_page":1,"has_more":false,"next_page":null,"next_after_id":null}}},"empty":{"summary":"No matches","value":{"data":[],"meta":{"vehicle_type":1,"page":1,"per_page":100,"total":0,"last_page":1,"has_more":false,"next_page":null,"next_after_id":null}}}}}}},"403":{"description":"API key, subscription, source access or IP restriction. Correct the account/access condition before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missingKey":{"summary":"API key is missing","value":{"error":"please add your api_key in get param"}},"invalidKey":{"summary":"API key is invalid","value":{"error":"wrong api key"}},"expiredSubscription":{"summary":"Subscription has expired","value":{"error":"your api subscription has expired"}},"inactiveSubscription":{"summary":"Subscription is inactive","value":{"error":"your api subscription is not active"}},"ipNotAllowed":{"summary":"Request IP is not allowlisted","value":{"error":"ip address is not in whitelist","ip":"203.0.113.10"}},"noSources":{"summary":"Subscription has no enabled sources","value":{"error":"you don't have any data in your subscription"}}}}}},"422":{"description":"Invalid vehicle type, parent ID, query, page size, conflicting page/after_id or excessive offset.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"examples":{"vehicleType":{"summary":"Unsupported type","value":{"errors":{"vehicle_type":["The selected vehicle type is invalid."]}}},"pageSize":{"summary":"Page size exceeds 100","value":{"errors":{"per_page":["The per page field must not be greater than 100."]}}},"window":{"summary":"Offset exceeds 10000","value":{"errors":{"page":["The page × per_page result window must not exceed 10000."]}}}}}}},"503":{"description":"Search service is temporarily unavailable. Retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Search unavailable","value":{"error":"search service temporarily unavailable"}}}}},"headers":{"Retry-After":{"schema":{"type":"string","example":"5"},"description":"Delay in seconds."}}},"default":{"description":"Unexpected upstream/infrastructure failure (including an upstream 429 or 5xx). JSON and HTML/text bodies are possible. No universal requests-per-minute limit is configured on these public routes; account/upstream limits can still apply. Respect Retry-After when returned and use bounded backoff for temporary failures. The examples illustrate possible envelopes, not a guarantee of exact infrastructure text.","headers":{"Retry-After":{"description":"Optional retry delay in seconds or an HTTP date.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Framework failure","value":{"message":"Server Error"}},"rateLimit":{"summary":"Upstream rate limit","value":{"message":"Too Many Attempts."}}}},"text/html":{"schema":{"type":"string"},"examples":{"gateway":{"summary":"Gateway failure","value":"<html><body>502 Bad Gateway</body></html>"}}}}}}}},"/variants/{generation_id}":{"get":{"operationId":"variants","tags":["Dictionaries"],"summary":"Vehicle variants","description":"All reads use the published Elasticsearch catalogue. Omitted vehicle_type means automobiles; motorcycle/2 selects motorcycles only. Brand flags cars/motorcycles define membership; shared brands can occur in both scopes. Legacy rows without a vehicle type/brand car flag count as automobiles only. Unknown, inactive or wrong-type parents return empty data. These are shared dictionaries, not subscription inventory; a dictionary entry does not guarantee available listings. Requires api_key and an active subscription.\n\nPaged responses are {data, meta}. Default/maximum per_page=100; minimum 1. Numeric ID ascending order gives stable traversal for an unchanged catalogue, including query results. meta.total is exact; with after_id it counts remaining matches after that ID. meta.page and last_page are relative to the remaining set in cursor mode. Follow next_page with the same filters for offset pagination, or follow next_after_id as after_id with page omitted for full traversal. At the 10k offset boundary next_page is null but has_more and next_after_id still allow continuation. Stop when has_more=false. There is no frozen snapshot across requests: updates can change totals; restart periodically when synchronizing. Invalid values, conflicting pagination or an excessive offset return 422. Elasticsearch unavailability or an incomplete/stale configuration publication returns 503 with Retry-After: 5. Examples use synthetic IDs.\n\nReturns active variants from the current approved rows_v2 configuration snapshot in Elasticsearch. Variants describe factory powertrain/model versions. Names and saved variant aliases are searched case-insensitively by literal substring within the bounded snapshot (maximum 2000 variants); pagination is applied to that matching list. Historical snapshot revisions are never enumerated. An active generation without a published configuration returns an empty page; an invalid/stale publication returns 503. This response exposes identities only, not factory facts, private evidence or compatibility pairs.","parameters":[{"name":"generation_id","in":"path","required":true,"description":"Positive generation_id from the preceding dictionary for the same vehicle_type.","schema":{"type":"integer","minimum":1},"example":301},{"name":"vehicle_type","in":"query","required":false,"description":"Dictionary scope: automobile/1 (default), motorcycle/2. Explicit empty or invalid values return 422. Keep the same type throughout brand → model → generation → variant/trim lookups and in inventory filters.","schema":{"type":"string","enum":["automobile","motorcycle","1","2"],"default":"automobile"}},{"name":"query","in":"query","required":false,"description":"Optional name or synonym phrase. Blank disables search. Prefix/substring matching is case-insensitive; * and ? are literal characters. Paged results stay ordered by numeric ID, not relevance.","schema":{"type":"string","maxLength":200}},{"name":"page","in":"query","required":false,"description":"Offset page. page × per_page must be ≤ 10000. Cannot be combined with after_id. Sending page enables the paged envelope on /brands and /models.","schema":{"type":"integer","minimum":1,"maximum":10000,"default":1}},{"name":"per_page","in":"query","required":false,"description":"Page size, default/maximum 100. Sending per_page enables the paged envelope on /brands and /models. Use per_page, not inventory-search perPage.","schema":{"type":"integer","minimum":1,"maximum":100,"default":100}},{"name":"after_id","in":"query","required":false,"description":"Cursor: return IDs greater than the last returned ID. Start with page=1 or per_page=100, then send meta.next_after_id as after_id, omitting page and keeping other filters unchanged. No 10k traversal limit. Sending after_id enables the paged envelope on legacy endpoints.","schema":{"type":"integer","minimum":1}},{"name":"lang","in":"query","required":false,"description":"Response locale. Option translations are also limited by the account languages. The page selects its current language automatically.","schema":{"type":"string","enum":["en","ru","sq","pl","uk","bg"]}}],"responses":{"200":{"description":"Always a paged envelope; empty for unknown or wrong-type parents.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/VehicleConfigurationEntry"}},"meta":{"$ref":"#/components/schemas/VehicleDictionaryMeta"}},"required":["data","meta"]},"examples":{"page":{"summary":"First page","value":{"data":[{"id":501,"name":"Example variant","brand_id":101,"model_id":201,"generation_id":301,"vehicle_type":1}],"meta":{"vehicle_type":1,"page":1,"per_page":100,"total":1,"last_page":1,"has_more":false,"next_page":null,"next_after_id":null}}},"empty":{"summary":"No matches","value":{"data":[],"meta":{"vehicle_type":1,"page":1,"per_page":100,"total":0,"last_page":1,"has_more":false,"next_page":null,"next_after_id":null}}}}}}},"403":{"description":"API key, subscription, source access or IP restriction. Correct the account/access condition before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missingKey":{"summary":"API key is missing","value":{"error":"please add your api_key in get param"}},"invalidKey":{"summary":"API key is invalid","value":{"error":"wrong api key"}},"expiredSubscription":{"summary":"Subscription has expired","value":{"error":"your api subscription has expired"}},"inactiveSubscription":{"summary":"Subscription is inactive","value":{"error":"your api subscription is not active"}},"ipNotAllowed":{"summary":"Request IP is not allowlisted","value":{"error":"ip address is not in whitelist","ip":"203.0.113.10"}},"noSources":{"summary":"Subscription has no enabled sources","value":{"error":"you don't have any data in your subscription"}}}}}},"422":{"description":"Invalid vehicle type, parent ID, query, page size, conflicting page/after_id or excessive offset.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"examples":{"vehicleType":{"summary":"Unsupported type","value":{"errors":{"vehicle_type":["The selected vehicle type is invalid."]}}},"pageSize":{"summary":"Page size exceeds 100","value":{"errors":{"per_page":["The per page field must not be greater than 100."]}}},"window":{"summary":"Offset exceeds 10000","value":{"errors":{"page":["The page × per_page result window must not exceed 10000."]}}}}}}},"503":{"description":"Search service is temporarily unavailable. Retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Search unavailable","value":{"error":"search service temporarily unavailable"}}}}},"headers":{"Retry-After":{"schema":{"type":"string","example":"5"},"description":"Delay in seconds."}}},"default":{"description":"Unexpected upstream/infrastructure failure (including an upstream 429 or 5xx). JSON and HTML/text bodies are possible. No universal requests-per-minute limit is configured on these public routes; account/upstream limits can still apply. Respect Retry-After when returned and use bounded backoff for temporary failures. The examples illustrate possible envelopes, not a guarantee of exact infrastructure text.","headers":{"Retry-After":{"description":"Optional retry delay in seconds or an HTTP date.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Framework failure","value":{"message":"Server Error"}},"rateLimit":{"summary":"Upstream rate limit","value":{"message":"Too Many Attempts."}}}},"text/html":{"schema":{"type":"string"},"examples":{"gateway":{"summary":"Gateway failure","value":"<html><body>502 Bad Gateway</body></html>"}}}}}}}},"/countries":{"get":{"operationId":"countries","tags":["Dictionaries"],"summary":"Country dictionary and search","description":"Requires the same valid api_key and active subscription as other public endpoints. These are shared geographic dictionaries, not the list of countries/cities with cars in your subscription. A dictionary entry does not guarantee available vehicles.\n\n**Pagination and complete lists:** results are always ordered by numeric id ascending, including search and ids[] requests. per_page defaults to 100 (1–1000). Start without after_id; while meta.has_more is true, send meta.next_after_id as after_id, preserving all filters and lang. Stop when has_more is false (next_after_id is null). No page, perPage, scroll_id or total is provided. This traversal has no 10,000-result offset limit and no cursor expiry, but is not a frozen snapshot: during updates, new records with IDs below the cursor can be missed; restart periodically when synchronizing a local dictionary.\n\n**Search and batching:** query is optional, at most 200 characters; blank text means no text filter. Search matches name prefixes, including stored alternative names in any language; country search also matches native names, ISO/ISO3 prefixes and phrase prefixes in stored translation fields (br, cn, de, es, fa, fr, hr, it, ja, kr, nl, pt plus the configured supported API locales). Matching is case-insensitive using the index normalization. It does not promise substring, typo-tolerant or automatic translation search. The characters * and ? are literal text, not operators. lang selects the returned display name, not the language to search. ids[]=2001&ids[]=3001 selects up to 100 distinct positive IDs; comma-separated ids is not accepted. All supplied filters are intersected. Batch results omit missing IDs, are sorted by ID rather than input order and use the same pagination. Build a map keyed by id.\n\n**Display a listing location:** every vehicle endpoint now includes listings[].location_details: country is {id, name, iso}; region, district and place are {id, name}; absent components are null. Use these names directly without extra client requests. The server collects all unique IDs in the response and resolves them in bulk before serialization. Unresolved IDs keep their ID with name:null; textual source labels without IDs use id:null. The legacy location field remains unchanged for compatibility. For independent lookup, resolve a numeric listings[].location.country through /countries/{id}; resolve numeric location_id, location_admin_1 and location_admin_2 through /locations/{id}, or collect unique IDs and use /locations?ids[]=... . These are separate country/location ID namespaces. /cars, /cars/{car_id} and /cars/vin/{vin} already attempt to replace these fields with localized strings; /search and /listing normally expose stored IDs. Preserve existing names and do not submit them as IDs. location_admin_3 and dictionary admin3/admin4/admin5 are source codes, not guaranteed location IDs. A region may refer to itself through admin1 (and a district through admin2): deduplicate labels by ID. Omit missing components, allow a country-only location and handle an empty location array. Coordinates may be null; zero is a valid coordinate. Use the listing position for the actual listing pin when present; dictionary coordinates describe the geographic entry. Cache dictionary entries by both ID namespace and lang. Examples here are synthetic; replace IDs with values from your own API responses.\n\n**Language:** explicitly send lang=en, ru, sq, pl, uk or bg for repeatable results. Otherwise existing locale middleware uses a supported locale cookie, then Accept-Language, then the configured application locale. An unsupported lang falls through that selection. name is localized with fallback; original_name is unchanged. Country names use a stored translation, then a nonhistoric alternative name for the locale, then name/native; en uses name/native directly. Locations use a nonhistoric alternative name for the locale or without a language, preferring is_preferred, then the stored name; en uses the stored name directly. Missing translations do not cause an error. Unlike equipment translation maps, these display names are not filtered by the account language list.","parameters":[{"name":"query","in":"query","required":false,"description":"Optional literal name-prefix search. Countries also search native names, ISO codes and stored translations. Blank text disables this filter.","schema":{"type":"string","maxLength":200},"example":"Chi"},{"name":"ids[]","in":"query","required":false,"description":"Batch lookup. Repeat ids[]=2001&ids[]=3001; not a comma-separated string. Unknown IDs are omitted. Intersects other filters.","schema":{"type":"array","minItems":1,"maxItems":100,"uniqueItems":true,"items":{"type":"integer","minimum":1}},"style":"form","explode":true},{"name":"per_page","in":"query","required":false,"description":"Maximum returned records. Empty, noninteger or out-of-range values return 422.","schema":{"type":"integer","minimum":1,"maximum":1000,"default":100}},{"name":"after_id","in":"query","required":false,"description":"Exclusive ID cursor. Omit initially; then use meta.next_after_id with unchanged filters. Not a page number. Empty or nonpositive values return 422.","schema":{"type":"integer","minimum":1}},{"name":"lang","in":"query","required":false,"description":"Response locale. Option translations are also limited by the account languages. The page selects its current language automatically.","schema":{"type":"string","enum":["en","ru","sq","pl","uk","bg"]}}],"responses":{"200":{"description":"Dictionary page. All listed item fields are always present; unavailable values are null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountryPage"},"examples":{"page":{"summary":"Synthetic final page","value":{"data":[{"id":101,"name":"Example country","original_name":"Example country","native":"Example native name","iso":"XX","iso3":"XXX"}],"meta":{"per_page":100,"has_more":false,"next_after_id":null}}},"more":{"summary":"Synthetic page with more results","value":{"data":[{"id":101,"name":"Example country","original_name":"Example country","native":"Example native name","iso":"XX","iso3":"XXX"}],"meta":{"per_page":1,"has_more":true,"next_after_id":101}}},"empty":{"summary":"No matches, unknown IDs/filter, or end of traversal","value":{"data":[],"meta":{"per_page":100,"has_more":false,"next_after_id":null}}}}}}},"403":{"description":"API key, subscription, source access or IP restriction. Correct the account/access condition before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missingKey":{"summary":"API key is missing","value":{"error":"please add your api_key in get param"}},"invalidKey":{"summary":"API key is invalid","value":{"error":"wrong api key"}},"expiredSubscription":{"summary":"Subscription has expired","value":{"error":"your api subscription has expired"}},"inactiveSubscription":{"summary":"Subscription is inactive","value":{"error":"your api subscription is not active"}},"ipNotAllowed":{"summary":"Request IP is not allowlisted","value":{"error":"ip address is not in whitelist","ip":"203.0.113.10"}},"noSources":{"summary":"Subscription has no enabled sources","value":{"error":"you don't have any data in your subscription"}}}}}},"422":{"description":"Invalid query, ID array, pagination or geographic filter. errors is keyed by field; no message property is added by this validator.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"examples":{"invalid":{"summary":"Invalid page size","value":{"errors":{"per_page":["The per page field must be at least 1."]}}},"ids":{"summary":"Comma-separated IDs are not supported","value":{"errors":{"ids":["The ids field must be an array."]}}}}}}},"503":{"description":"Search service is temporarily unavailable. Retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Search unavailable","value":{"error":"search service temporarily unavailable"}}}}},"headers":{"Retry-After":{"schema":{"type":"string","example":"5"},"description":"Delay in seconds."}}},"default":{"description":"Unexpected upstream/infrastructure failure (including an upstream 429 or 5xx). JSON and HTML/text bodies are possible. No universal requests-per-minute limit is configured on these public routes; account/upstream limits can still apply. Respect Retry-After when returned and use bounded backoff for temporary failures. The examples illustrate possible envelopes, not a guarantee of exact infrastructure text.","headers":{"Retry-After":{"description":"Optional retry delay in seconds or an HTTP date.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Framework failure","value":{"message":"Server Error"}},"rateLimit":{"summary":"Upstream rate limit","value":{"message":"Too Many Attempts."}}}},"text/html":{"schema":{"type":"string"},"examples":{"gateway":{"summary":"Gateway failure","value":"<html><body>502 Bad Gateway</body></html>"}}}}}}}},"/countries/{id}":{"get":{"operationId":"countryById","tags":["Dictionaries"],"summary":"Resolve one country ID","description":"Returns one dictionary entry wrapped in data, with the same fields and language behavior as /countries. id must be a positive integer. Numeric IDs in the two dictionaries are independent. Extra list filters are ignored on this detail endpoint. An absent record returns 404; an invalid ID returns 422. Use numeric listings[].location.country or a location country_id.","parameters":[{"name":"id","in":"path","required":true,"description":"Country ID from /countries or numeric listing location.country.","schema":{"type":"integer","minimum":1}},{"name":"lang","in":"query","required":false,"description":"Response locale. Option translations are also limited by the account languages. The page selects its current language automatically.","schema":{"type":"string","enum":["en","ru","sq","pl","uk","bg"]}}],"responses":{"200":{"description":"One dictionary entry.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Country"}},"required":["data"]},"examples":{"item":{"summary":"Synthetic entry","value":{"data":{"id":101,"name":"Example country","original_name":"Example country","native":"Example native name","iso":"XX","iso3":"XXX"}}}}}}},"403":{"description":"API key, subscription, source access or IP restriction. Correct the account/access condition before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missingKey":{"summary":"API key is missing","value":{"error":"please add your api_key in get param"}},"invalidKey":{"summary":"API key is invalid","value":{"error":"wrong api key"}},"expiredSubscription":{"summary":"Subscription has expired","value":{"error":"your api subscription has expired"}},"inactiveSubscription":{"summary":"Subscription is inactive","value":{"error":"your api subscription is not active"}},"ipNotAllowed":{"summary":"Request IP is not allowlisted","value":{"error":"ip address is not in whitelist","ip":"203.0.113.10"}},"noSources":{"summary":"Subscription has no enabled sources","value":{"error":"you don't have any data in your subscription"}}}}}},"404":{"description":"No dictionary entry with this positive integer ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"Entry not found","value":{"error":"country not found"}}}}}},"422":{"description":"id must be a positive integer, including when supplied in the path.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"examples":{"invalid":{"summary":"Invalid ID","value":{"errors":{"id":["The id field must be an integer."]}}}}}}},"503":{"description":"Search service is temporarily unavailable. Retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Search unavailable","value":{"error":"search service temporarily unavailable"}}}}},"headers":{"Retry-After":{"schema":{"type":"string","example":"5"},"description":"Delay in seconds."}}},"default":{"description":"Unexpected upstream/infrastructure failure (including an upstream 429 or 5xx). JSON and HTML/text bodies are possible. No universal requests-per-minute limit is configured on these public routes; account/upstream limits can still apply. Respect Retry-After when returned and use bounded backoff for temporary failures. The examples illustrate possible envelopes, not a guarantee of exact infrastructure text.","headers":{"Retry-After":{"description":"Optional retry delay in seconds or an HTTP date.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Framework failure","value":{"message":"Server Error"}},"rateLimit":{"summary":"Upstream rate limit","value":{"message":"Too Many Attempts."}}}},"text/html":{"schema":{"type":"string"},"examples":{"gateway":{"summary":"Gateway failure","value":"<html><body>502 Bad Gateway</body></html>"}}}}}}}},"/locations":{"get":{"operationId":"locations","tags":["Dictionaries"],"summary":"Locations, regions, districts and populated places","description":"Requires the same valid api_key and active subscription as other public endpoints. These are shared geographic dictionaries, not the list of countries/cities with cars in your subscription. A dictionary entry does not guarantee available vehicles.\n\n**Pagination and complete lists:** results are always ordered by numeric id ascending, including search and ids[] requests. per_page defaults to 100 (1–1000). Start without after_id; while meta.has_more is true, send meta.next_after_id as after_id, preserving all filters and lang. Stop when has_more is false (next_after_id is null). No page, perPage, scroll_id or total is provided. This traversal has no 10,000-result offset limit and no cursor expiry, but is not a frozen snapshot: during updates, new records with IDs below the cursor can be missed; restart periodically when synchronizing a local dictionary.\n\n**Search and batching:** query is optional, at most 200 characters; blank text means no text filter. Search matches name prefixes, including stored alternative names in any language; country search also matches native names, ISO/ISO3 prefixes and phrase prefixes in stored translation fields (br, cn, de, es, fa, fr, hr, it, ja, kr, nl, pt plus the configured supported API locales). Matching is case-insensitive using the index normalization. It does not promise substring, typo-tolerant or automatic translation search. The characters * and ? are literal text, not operators. lang selects the returned display name, not the language to search. ids[]=2001&ids[]=3001 selects up to 100 distinct positive IDs; comma-separated ids is not accepted. All supplied filters are intersected. Batch results omit missing IDs, are sorted by ID rather than input order and use the same pagination. Build a map keyed by id.\n\n**Display a listing location:** every vehicle endpoint now includes listings[].location_details: country is {id, name, iso}; region, district and place are {id, name}; absent components are null. Use these names directly without extra client requests. The server collects all unique IDs in the response and resolves them in bulk before serialization. Unresolved IDs keep their ID with name:null; textual source labels without IDs use id:null. The legacy location field remains unchanged for compatibility. For independent lookup, resolve a numeric listings[].location.country through /countries/{id}; resolve numeric location_id, location_admin_1 and location_admin_2 through /locations/{id}, or collect unique IDs and use /locations?ids[]=... . These are separate country/location ID namespaces. /cars, /cars/{car_id} and /cars/vin/{vin} already attempt to replace these fields with localized strings; /search and /listing normally expose stored IDs. Preserve existing names and do not submit them as IDs. location_admin_3 and dictionary admin3/admin4/admin5 are source codes, not guaranteed location IDs. A region may refer to itself through admin1 (and a district through admin2): deduplicate labels by ID. Omit missing components, allow a country-only location and handle an empty location array. Coordinates may be null; zero is a valid coordinate. Use the listing position for the actual listing pin when present; dictionary coordinates describe the geographic entry. Cache dictionary entries by both ID namespace and lang. Examples here are synthetic; replace IDs with values from your own API responses.\n\n**Language:** explicitly send lang=en, ru, sq, pl, uk or bg for repeatable results. Otherwise existing locale middleware uses a supported locale cookie, then Accept-Language, then the configured application locale. An unsupported lang falls through that selection. name is localized with fallback; original_name is unchanged. Country names use a stored translation, then a nonhistoric alternative name for the locale, then name/native; en uses name/native directly. Locations use a nonhistoric alternative name for the locale or without a language, preferring is_preferred, then the stored name; en uses the stored name directly. Missing translations do not cause an error. Unlike equipment translation maps, these display names are not filtered by the account language list.\n\n**Dependent selectors:** first load /countries. For a country ID C, load /locations?country_id=C&feature_class=A&feature_code=ADM1 for regions. For region ID R, load /locations?country_id=C&admin1=R&feature_class=A&feature_code=ADM2 for districts. For populated places use /locations?country_id=C&admin1=R&feature_class=P (optionally admin2=D). Add query for autocomplete. Follow pagination for each selector. P includes towns and villages, not just cities. The country/region filters are optional; all geographic entries in the index are enumerable. Different countries have different administrative structures; empty districts are valid. An unknown country/region or incompatible combination returns 200 with empty data, not 404.","parameters":[{"name":"query","in":"query","required":false,"description":"Optional literal name-prefix search. Countries also search native names, ISO codes and stored translations. Blank text disables this filter.","schema":{"type":"string","maxLength":200},"example":"Chi"},{"name":"ids[]","in":"query","required":false,"description":"Batch lookup. Repeat ids[]=2001&ids[]=3001; not a comma-separated string. Unknown IDs are omitted. Intersects other filters.","schema":{"type":"array","minItems":1,"maxItems":100,"uniqueItems":true,"items":{"type":"integer","minimum":1}},"style":"form","explode":true},{"name":"per_page","in":"query","required":false,"description":"Maximum returned records. Empty, noninteger or out-of-range values return 422.","schema":{"type":"integer","minimum":1,"maximum":1000,"default":100}},{"name":"after_id","in":"query","required":false,"description":"Exclusive ID cursor. Omit initially; then use meta.next_after_id with unchanged filters. Not a page number. Empty or nonpositive values return 422.","schema":{"type":"integer","minimum":1}},{"name":"country_id","in":"query","required":false,"description":"Internal country ID from /countries. Optional; omit to enumerate all countries.","schema":{"type":"integer","minimum":1}},{"name":"admin1","in":"query","required":false,"description":"First-level administrative location ID, not a country ID or source code.","schema":{"type":"integer","minimum":1}},{"name":"admin2","in":"query","required":false,"description":"Second-level administrative location ID.","schema":{"type":"integer","minimum":1}},{"name":"feature_class","in":"query","required":false,"description":"Case-insensitive source class: A for administrative areas, P for populated places (not only cities). Unknown well-formed values return an empty list.","schema":{"type":"string","pattern":"^[A-Za-z]$"}},{"name":"feature_code","in":"query","required":false,"description":"Case-insensitive source code: ADM1 for regions, ADM2 for districts. Unknown well-formed values return an empty list.","schema":{"type":"string","pattern":"^[A-Za-z][A-Za-z0-9]{0,9}$"}},{"name":"lang","in":"query","required":false,"description":"Response locale. Option translations are also limited by the account languages. The page selects its current language automatically.","schema":{"type":"string","enum":["en","ru","sq","pl","uk","bg"]}}],"responses":{"200":{"description":"Dictionary page. All listed item fields are always present; unavailable values are null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationPage"},"examples":{"page":{"summary":"Synthetic final page","value":{"data":[{"id":3001,"name":"Example city","original_name":"Example city","ascii_name":null,"country_id":101,"admin1":2001,"admin2":null,"admin3":null,"admin4":null,"admin5":null,"feature_class":"P","feature_code":"PPL","latitude":12.34,"longitude":56.78,"population":null}],"meta":{"per_page":100,"has_more":false,"next_after_id":null}}},"more":{"summary":"Synthetic page with more results","value":{"data":[{"id":3001,"name":"Example city","original_name":"Example city","ascii_name":null,"country_id":101,"admin1":2001,"admin2":null,"admin3":null,"admin4":null,"admin5":null,"feature_class":"P","feature_code":"PPL","latitude":12.34,"longitude":56.78,"population":null}],"meta":{"per_page":1,"has_more":true,"next_after_id":3001}}},"empty":{"summary":"No matches, unknown IDs/filter, or end of traversal","value":{"data":[],"meta":{"per_page":100,"has_more":false,"next_after_id":null}}}}}}},"403":{"description":"API key, subscription, source access or IP restriction. Correct the account/access condition before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missingKey":{"summary":"API key is missing","value":{"error":"please add your api_key in get param"}},"invalidKey":{"summary":"API key is invalid","value":{"error":"wrong api key"}},"expiredSubscription":{"summary":"Subscription has expired","value":{"error":"your api subscription has expired"}},"inactiveSubscription":{"summary":"Subscription is inactive","value":{"error":"your api subscription is not active"}},"ipNotAllowed":{"summary":"Request IP is not allowlisted","value":{"error":"ip address is not in whitelist","ip":"203.0.113.10"}},"noSources":{"summary":"Subscription has no enabled sources","value":{"error":"you don't have any data in your subscription"}}}}}},"422":{"description":"Invalid query, ID array, pagination or geographic filter. errors is keyed by field; no message property is added by this validator.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"examples":{"invalid":{"summary":"Invalid page size","value":{"errors":{"per_page":["The per page field must be at least 1."]}}},"ids":{"summary":"Comma-separated IDs are not supported","value":{"errors":{"ids":["The ids field must be an array."]}}}}}}},"503":{"description":"Search service is temporarily unavailable. Retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Search unavailable","value":{"error":"search service temporarily unavailable"}}}}},"headers":{"Retry-After":{"schema":{"type":"string","example":"5"},"description":"Delay in seconds."}}},"default":{"description":"Unexpected upstream/infrastructure failure (including an upstream 429 or 5xx). JSON and HTML/text bodies are possible. No universal requests-per-minute limit is configured on these public routes; account/upstream limits can still apply. Respect Retry-After when returned and use bounded backoff for temporary failures. The examples illustrate possible envelopes, not a guarantee of exact infrastructure text.","headers":{"Retry-After":{"description":"Optional retry delay in seconds or an HTTP date.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Framework failure","value":{"message":"Server Error"}},"rateLimit":{"summary":"Upstream rate limit","value":{"message":"Too Many Attempts."}}}},"text/html":{"schema":{"type":"string"},"examples":{"gateway":{"summary":"Gateway failure","value":"<html><body>502 Bad Gateway</body></html>"}}}}}}}},"/locations/{id}":{"get":{"operationId":"locationById","tags":["Dictionaries"],"summary":"Resolve one location ID","description":"Returns one dictionary entry wrapped in data, with the same fields and language behavior as /locations. id must be a positive integer. Numeric IDs in the two dictionaries are independent. Extra list filters are ignored on this detail endpoint. An absent record returns 404; an invalid ID returns 422. Use numeric location_id, location_admin_1 or location_admin_2. Do not use location_admin_3 as a guaranteed ID.","parameters":[{"name":"id","in":"path","required":true,"description":"Location ID from /locations or numeric listing location fields.","schema":{"type":"integer","minimum":1}},{"name":"lang","in":"query","required":false,"description":"Response locale. Option translations are also limited by the account languages. The page selects its current language automatically.","schema":{"type":"string","enum":["en","ru","sq","pl","uk","bg"]}}],"responses":{"200":{"description":"One dictionary entry.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Location"}},"required":["data"]},"examples":{"item":{"summary":"Synthetic entry","value":{"data":{"id":3001,"name":"Example city","original_name":"Example city","ascii_name":null,"country_id":101,"admin1":2001,"admin2":null,"admin3":null,"admin4":null,"admin5":null,"feature_class":"P","feature_code":"PPL","latitude":12.34,"longitude":56.78,"population":null}}}}}}},"403":{"description":"API key, subscription, source access or IP restriction. Correct the account/access condition before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missingKey":{"summary":"API key is missing","value":{"error":"please add your api_key in get param"}},"invalidKey":{"summary":"API key is invalid","value":{"error":"wrong api key"}},"expiredSubscription":{"summary":"Subscription has expired","value":{"error":"your api subscription has expired"}},"inactiveSubscription":{"summary":"Subscription is inactive","value":{"error":"your api subscription is not active"}},"ipNotAllowed":{"summary":"Request IP is not allowlisted","value":{"error":"ip address is not in whitelist","ip":"203.0.113.10"}},"noSources":{"summary":"Subscription has no enabled sources","value":{"error":"you don't have any data in your subscription"}}}}}},"404":{"description":"No dictionary entry with this positive integer ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"Entry not found","value":{"error":"location not found"}}}}}},"422":{"description":"id must be a positive integer, including when supplied in the path.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"examples":{"invalid":{"summary":"Invalid ID","value":{"errors":{"id":["The id field must be an integer."]}}}}}}},"503":{"description":"Search service is temporarily unavailable. Retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Search unavailable","value":{"error":"search service temporarily unavailable"}}}}},"headers":{"Retry-After":{"schema":{"type":"string","example":"5"},"description":"Delay in seconds."}}},"default":{"description":"Unexpected upstream/infrastructure failure (including an upstream 429 or 5xx). JSON and HTML/text bodies are possible. No universal requests-per-minute limit is configured on these public routes; account/upstream limits can still apply. Respect Retry-After when returned and use bounded backoff for temporary failures. The examples illustrate possible envelopes, not a guarantee of exact infrastructure text.","headers":{"Retry-After":{"description":"Optional retry delay in seconds or an HTTP date.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Framework failure","value":{"message":"Server Error"}},"rateLimit":{"summary":"Upstream rate limit","value":{"message":"Too Many Attempts."}}}},"text/html":{"schema":{"type":"string"},"examples":{"gateway":{"summary":"Gateway failure","value":"<html><body>502 Bad Gateway</body></html>"}}}}}}}},"/car-option-sections":{"get":{"operationId":"carOptionSections","tags":["Dictionaries"],"summary":"Equipment sections","description":"Up to 1000 nondeleted sections, ordered by sort order then ID. Localized name uses lang with fallbacks; translations are restricted to account languages.","parameters":[{"name":"lang","in":"query","required":false,"description":"Response locale. Option translations are also limited by the account languages. The page selects its current language automatically.","schema":{"type":"string","enum":["en","ru","sq","pl","uk","bg"]}}],"responses":{"200":{"description":"Sections wrapped in data.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/OptionSection"}}},"required":["data"]},"examples":{"sections":{"summary":"Sections","value":{"data":[{"id":10,"name":"Comfort","translations":{"name":{"en":"Comfort","ru":"Комфорт"}}}]}},"empty":{"summary":"No sections","value":{"data":[]}}}}}},"403":{"description":"API key, subscription, source access or IP restriction. Correct the account/access condition before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missingKey":{"summary":"API key is missing","value":{"error":"please add your api_key in get param"}},"invalidKey":{"summary":"API key is invalid","value":{"error":"wrong api key"}},"expiredSubscription":{"summary":"Subscription has expired","value":{"error":"your api subscription has expired"}},"inactiveSubscription":{"summary":"Subscription is inactive","value":{"error":"your api subscription is not active"}},"ipNotAllowed":{"summary":"Request IP is not allowlisted","value":{"error":"ip address is not in whitelist","ip":"203.0.113.10"}},"noSources":{"summary":"Subscription has no enabled sources","value":{"error":"you don't have any data in your subscription"}}}}}},"default":{"description":"Unexpected upstream/infrastructure failure (including an upstream 429 or 5xx). JSON and HTML/text bodies are possible. No universal requests-per-minute limit is configured on these public routes; account/upstream limits can still apply. Respect Retry-After when returned and use bounded backoff for temporary failures. The examples illustrate possible envelopes, not a guarantee of exact infrastructure text.","headers":{"Retry-After":{"description":"Optional retry delay in seconds or an HTTP date.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Framework failure","value":{"message":"Server Error"}},"rateLimit":{"summary":"Upstream rate limit","value":{"message":"Too Many Attempts."}}}},"text/html":{"schema":{"type":"string"},"examples":{"gateway":{"summary":"Gateway failure","value":"<html><body>502 Bad Gateway</body></html>"}}}}}}}},"/car-options":{"get":{"operationId":"carOptions","tags":["Dictionaries"],"summary":"Equipment options","description":"Two response modes: without query/page/per_page/perPage/section_id/ids, returns popular options grouped by section. Supplying any of those selects flat paginated search. Only approved, nondeleted options are returned. Resolve car and listing option_ids here; arrays of names/descriptions are limited by account languages. page × per_page must not exceed 10000.","parameters":[{"name":"query","in":"query","required":false,"description":"Search equipment names, descriptions and locations.","schema":{"type":"string"}},{"name":"page","in":"query","required":false,"description":"Flat search page. Values below 1 are clamped to 1. Explicitly sending page selects flat mode.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"per_page","in":"query","required":false,"description":"Flat page size, clamped to 1–100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"perPage","in":"query","required":false,"description":"Alias of per_page; per_page takes precedence.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"limit","in":"query","required":false,"description":"Popular mode only: options per section, clamped to 1–25.","schema":{"type":"integer","minimum":1,"maximum":25,"default":5}},{"name":"section_id","in":"query","required":false,"description":"Restrict flat search to a section from /car-option-sections.","schema":{"type":"integer"},"x-autofill":"sections"},{"name":"ids","in":"query","required":false,"description":"Comma-separated option IDs, e.g. 101,102. Also accepts ids[]=101&ids[]=102. Invalid/nonpositive IDs are discarded; avoid an empty filter.","schema":{"type":"string"},"example":"101,102"},{"name":"lang","in":"query","required":false,"description":"Response locale. Option translations are also limited by the account languages. The page selects its current language automatically.","schema":{"type":"string","enum":["en","ru","sq","pl","uk","bg"]}}],"responses":{"200":{"description":"Grouped popular options or flat search page, depending on parameters.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/PopularOptions"},{"$ref":"#/components/schemas/OptionPage"}]},"examples":{"popular":{"summary":"No filters: popular by section","value":{"data":[{"id":10,"name":"Comfort","translations":{"name":{"en":"Comfort","ru":"Комфорт"}},"options":[{"id":101,"section_id":10,"parent_option_id":null,"name":"Heated seats","description":null,"location":null,"translations":{"name":{"en":"Heated seats"},"description":[],"location":[]},"section":{"id":10,"name":"Comfort","translations":{"name":{"en":"Comfort","ru":"Комфорт"}}},"parent_option":null}]}],"meta":{"mode":"popular_by_section","limit_per_section":5}}},"search":{"summary":"With page=1: flat results","value":{"data":[{"id":101,"section_id":10,"parent_option_id":null,"name":"Heated seats","description":null,"location":null,"translations":{"name":{"en":"Heated seats"},"description":[],"location":[]},"section":{"id":10,"name":"Comfort","translations":{"name":{"en":"Comfort","ru":"Комфорт"}}},"parent_option":null}],"meta":{"page":1,"per_page":25,"total":1}}},"empty":{"summary":"Flat search without matches","value":{"data":[],"meta":{"page":1,"per_page":25,"total":0}}},"emptyPopular":{"summary":"No popular options","value":{"data":[],"meta":{"mode":"popular_by_section","limit_per_section":5}}}}}}},"403":{"description":"API key, subscription, source access or IP restriction. Correct the account/access condition before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missingKey":{"summary":"API key is missing","value":{"error":"please add your api_key in get param"}},"invalidKey":{"summary":"API key is invalid","value":{"error":"wrong api key"}},"expiredSubscription":{"summary":"Subscription has expired","value":{"error":"your api subscription has expired"}},"inactiveSubscription":{"summary":"Subscription is inactive","value":{"error":"your api subscription is not active"}},"ipNotAllowed":{"summary":"Request IP is not allowlisted","value":{"error":"ip address is not in whitelist","ip":"203.0.113.10"}},"noSources":{"summary":"Subscription has no enabled sources","value":{"error":"you don't have any data in your subscription"}}}}}},"422":{"description":"Flat search result window exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"},"examples":{"offset":{"summary":"Offset above 10,000","value":{"message":"Max num of offset is 10k","errors":{"offset":["Max num of offset is 10k"]}}}}}}},"default":{"description":"Unexpected upstream/infrastructure failure (including an upstream 429 or 5xx). JSON and HTML/text bodies are possible. No universal requests-per-minute limit is configured on these public routes; account/upstream limits can still apply. Respect Retry-After when returned and use bounded backoff for temporary failures. The examples illustrate possible envelopes, not a guarantee of exact infrastructure text.","headers":{"Retry-After":{"description":"Optional retry delay in seconds or an HTTP date.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Framework failure","value":{"message":"Server Error"}},"rateLimit":{"summary":"Upstream rate limit","value":{"message":"Too Many Attempts."}}}},"text/html":{"schema":{"type":"string"},"examples":{"gateway":{"summary":"Gateway failure","value":"<html><body>502 Bad Gateway</body></html>"}}}}}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"query","name":"api_key","description":"Use the API-key field on the page. In external OpenAPI clients, authorize here."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"ip":{"type":"string"},"car_id":{"type":"string"},"vin":{"type":"string"},"domain_id":{"type":"integer"},"listing_id":{"type":"string"},"scrollId":{"type":"string"},"code":{"type":"integer"},"your_value":{"type":"integer"},"default_value":{"type":"integer"}}},"ValidationError":{"type":"object","properties":{"message":{"type":"string","description":"Present for framework validation and /cars; omitted by search and VIN validators."},"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"required":["errors"]},"DictionaryItem":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true}},"required":["id","name"]},"Country":{"type":"object","properties":{"id":{"type":"integer","description":"Internal country ID. Matches numeric listings[].location.country and Location.country_id; not a location/GeoNames ID."},"name":{"type":"string","description":"Display name selected using lang, with source-name fallback.","nullable":true},"original_name":{"type":"string","description":"Unlocalized stored name.","nullable":true},"native":{"type":"string","nullable":true},"iso":{"type":"string","description":"Uppercase two-letter ISO code.","nullable":true},"iso3":{"type":"string","description":"Uppercase three-letter ISO code.","nullable":true}},"required":["id","name","original_name","native","iso","iso3"]},"Location":{"type":"object","properties":{"id":{"type":"integer","description":"Location dictionary ID. Use for numeric location_id, location_admin_1 and location_admin_2 values."},"name":{"type":"string","description":"Display name selected using lang. English uses the stored name. Other locales prefer nonhistoric alternative names in the requested language or without a language, ordered by is_preferred, then fall back to the stored name.","nullable":true},"original_name":{"type":"string","nullable":true},"ascii_name":{"type":"string","nullable":true},"country_id":{"type":"integer","description":"Internal country ID, resolved through /countries.","nullable":true},"admin1":{"type":"integer","description":"First-level administrative location ID; may equal this record ID.","nullable":true},"admin2":{"type":"integer","description":"Second-level administrative location ID; may equal this record ID.","nullable":true},"admin3":{"type":"string","description":"Source administrative code, not a guaranteed location ID. Preserve as a string.","nullable":true},"admin4":{"type":"string","description":"Source administrative code, not a guaranteed location ID. Preserve as a string.","nullable":true},"admin5":{"type":"string","description":"Source administrative code, not a guaranteed location ID. Preserve as a string.","nullable":true},"feature_class":{"type":"string","description":"Uppercase source feature class. A = administrative area; P = populated place.","nullable":true},"feature_code":{"type":"string","description":"Uppercase source feature code. ADM1 = first-level region; ADM2 = second-level district.","nullable":true},"latitude":{"type":"number","nullable":true},"longitude":{"type":"number","nullable":true},"population":{"type":"integer","nullable":true}},"required":["id","name","original_name","ascii_name","country_id","admin1","admin2","admin3","admin4","admin5","feature_class","feature_code","latitude","longitude","population"]},"ListingLocationDetails":{"type":"object","properties":{"country":{"type":"object","properties":{"id":{"type":"integer","description":"Internal country ID, resolved through /countries.","nullable":true},"name":{"type":"string","description":"Localized country name.","nullable":true},"iso":{"type":"string","description":"Uppercase country ISO code, or null when unavailable.","nullable":true}},"required":["id","name","iso"],"nullable":true},"region":{"type":"object","properties":{"id":{"type":"integer","description":"Original location ID, or null for a source-owned textual label.","nullable":true},"name":{"type":"string","description":"Localized name, or null when unresolved.","nullable":true}},"required":["id","name"],"nullable":true},"district":{"type":"object","properties":{"id":{"type":"integer","description":"Original location ID, or null for a source-owned textual label.","nullable":true},"name":{"type":"string","description":"Localized name, or null when unresolved.","nullable":true}},"required":["id","name"],"nullable":true},"place":{"type":"object","properties":{"id":{"type":"integer","description":"Original location ID, or null for a source-owned textual label.","nullable":true},"name":{"type":"string","description":"Localized name, or null when unresolved.","nullable":true}},"required":["id","name"],"nullable":true}},"required":["country","region","district","place"]},"LocationDictionaryMeta":{"type":"object","properties":{"per_page":{"type":"integer","description":"Requested page size, default 100, maximum 1000."},"has_more":{"type":"boolean"},"next_after_id":{"type":"integer","description":"When has_more is true, pass this as after_id with the same filters and locale. Null at the end.","nullable":true}},"required":["per_page","has_more","next_after_id"]},"CountryPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Country"}},"meta":{"$ref":"#/components/schemas/LocationDictionaryMeta"}},"required":["data","meta"]},"LocationPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Location"}},"meta":{"$ref":"#/components/schemas/LocationDictionaryMeta"}},"required":["data","meta"]},"SteeringWheelPosition":{"type":"object","properties":{"id":{"type":"integer","enum":[1,2]},"name":{"type":"string","enum":["left","right"]}},"required":["id","name"],"nullable":true,"description":"1 = left (left-hand drive); 2 = right (right-hand drive). The response is an id/name object; the search filter accepts the integer ID. Omitted when unavailable, or null when the stored value cannot be resolved.","example":{"id":1,"name":"left"}},"ListingImage":{"type":"object","properties":{"downloaded":{"type":"string","description":"URL of the image copy downloaded to our image storage. Returned only when both the stored file path and image server are available; the URL uses the image host configured for the API domain."},"preview":{"type":"string","description":"Preview image URL supplied by the listing source. Passed through unchanged; usually suitable for thumbnails. Dimensions are not guaranteed."},"original":{"type":"string","description":"Original image URL supplied by the listing source. Passed through unchanged; it points to the source image rather than our downloaded copy."}},"minProperties":1,"description":"Available URLs for one listing image. Each field is optional and omitted when unavailable. Entries without any URL are excluded; the images array can be empty. No fixed dimensions or availability of all three variants are guaranteed."},"Domain":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true},"base_url":{"type":"string","description":"Source hostname, without protocol.","nullable":true}},"required":["id","name","base_url"]},"Brand":{"type":"object","properties":{"id":{"type":"integer","description":"Brand ID. Internal catalogue documents without an ID are excluded."},"name":{"type":"string","nullable":true},"icon_url":{"type":"string","description":"Omitted on api.auctionsapi.com.","nullable":true}},"required":["id","name"]},"Model":{"type":"object","properties":{"id":{"type":"integer","nullable":true},"name":{"type":"string","nullable":true},"generations":{"type":"array","items":{"$ref":"#/components/schemas/Generation"}}},"required":["id","name","generations"]},"Generation":{"type":"object","properties":{"name":{"type":"string","nullable":true},"from":{"type":"integer","nullable":true},"to":{"type":"integer","nullable":true}}},"VehicleGeneration":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true},"brand_id":{"type":"integer"},"model_id":{"type":"integer"},"vehicle_type":{"type":"integer","enum":[1,2]},"from_year":{"type":"integer","nullable":true},"to_year":{"type":"integer","nullable":true},"ordinal":{"type":"string","nullable":true},"code":{"type":"string","nullable":true}},"required":["id","name","brand_id","model_id","vehicle_type","from_year","to_year","ordinal","code"]},"VehicleConfigurationEntry":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"brand_id":{"type":"integer"},"model_id":{"type":"integer"},"generation_id":{"type":"integer"},"vehicle_type":{"type":"integer","enum":[1,2]}},"required":["id","name","brand_id","model_id","generation_id","vehicle_type"]},"VehicleDictionaryMeta":{"type":"object","properties":{"vehicle_type":{"type":"integer","enum":[1,2]},"page":{"type":"integer"},"per_page":{"type":"integer"},"total":{"type":"integer","description":"Exact matches remaining after after_id when supplied; otherwise exact matches for all filters."},"last_page":{"type":"integer"},"has_more":{"type":"boolean"},"next_page":{"type":"integer","nullable":true},"next_after_id":{"type":"integer","nullable":true}},"required":["vehicle_type","page","per_page","total","last_page","has_more","next_page","next_after_id"]},"VehicleGenerationFilter":{"type":"object","properties":{"id":{"type":"integer","minimum":1},"variants":{"type":"array","items":{"type":"integer","minimum":1},"maxItems":100},"trims":{"type":"array","items":{"type":"integer","minimum":1},"maxItems":100}},"required":["id"],"additionalProperties":false,"description":"One generation AND its optional variant/trim lists. Sibling generation entries are OR alternatives."},"VehicleModelFilter":{"type":"object","properties":{"id":{"type":"integer","minimum":1},"generations":{"type":"array","items":{"$ref":"#/components/schemas/VehicleGenerationFilter"},"maxItems":100}},"required":["id"],"additionalProperties":false},"VehicleBrandFilter":{"type":"object","properties":{"id":{"type":"integer","minimum":1},"models":{"type":"array","items":{"oneOf":[{"type":"integer","minimum":1},{"$ref":"#/components/schemas/VehicleModelFilter"}]},"nullable":true,"maxItems":100}},"required":["id"],"additionalProperties":false},"VehicleSelectionFilter":{"type":"object","properties":{"interior_colors":{"type":"array","items":{"type":"integer","minimum":1},"maxItems":100,"uniqueItems":true},"cylinders":{"type":"array","items":{"type":"integer","minimum":1,"maximum":99},"maxItems":99,"uniqueItems":true},"vehicle_type":{"type":"string","enum":["automobile","motorcycle","1","2"],"default":"automobile"},"brands":{"type":"array","items":{"$ref":"#/components/schemas/VehicleBrandFilter"},"maxItems":100}}},"OptionSection":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true},"translations":{"type":"object","properties":{"name":{"oneOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"array","maxItems":0,"items":{"type":"string"}}],"description":"Language-to-text map. PHP serializes an empty map as []."}}}},"required":["id","name","translations"]},"Option":{"type":"object","properties":{"id":{"type":"integer"},"section_id":{"type":"integer","nullable":true},"parent_option_id":{"type":"integer","nullable":true},"name":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"location":{"type":"string","nullable":true},"translations":{"type":"object","properties":{"name":{"oneOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"array","maxItems":0,"items":{"type":"string"}}],"description":"Language-to-text map. PHP serializes an empty map as []."},"description":{"oneOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"array","maxItems":0,"items":{"type":"string"}}],"description":"Language-to-text map. PHP serializes an empty map as []."},"location":{"oneOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"array","maxItems":0,"items":{"type":"string"}}],"description":"Language-to-text map. PHP serializes an empty map as []."}}},"section":{"type":"object","properties":{"id":{"type":"integer","nullable":true},"name":{"type":"string","nullable":true},"translations":{"type":"object","properties":{"name":{"oneOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"array","maxItems":0,"items":{"type":"string"}}],"description":"Language-to-text map. PHP serializes an empty map as []."}},"required":["name"]}},"required":["id","name","translations"],"nullable":true},"parent_option":{"type":"object","properties":{"id":{"type":"integer","nullable":true},"name":{"type":"string","nullable":true},"translations":{"type":"object","properties":{"name":{"oneOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"array","maxItems":0,"items":{"type":"string"}}],"description":"Language-to-text map. PHP serializes an empty map as []."}},"required":["name"]}},"required":["id","name","translations"],"nullable":true}}},"PopularOptions":{"type":"object","properties":{"data":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/OptionSection"},{"type":"object","properties":{"options":{"type":"array","items":{"$ref":"#/components/schemas/Option"}}},"required":["options"]}]}},"meta":{"type":"object","properties":{"mode":{"type":"string","enum":["popular_by_section"]},"limit_per_section":{"type":"integer"}},"required":["mode","limit_per_section"]}},"required":["data","meta"]},"OptionPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Option"}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"per_page":{"type":"integer"},"total":{"type":"integer"}},"required":["page","per_page","total"]}},"required":["data","meta"]},"ReportTranslations":{"type":"object","properties":{"language":{"type":"string"},"fallback_language":{"type":"string"},"terms":{"type":"object","additionalProperties":{"type":"object","additionalProperties":{"type":"string"}},"description":"Labels by taxonomy type and canonical key: terms[type][key]. Empty dictionary is {}."},"missing":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"key":{"type":"string"},"fallback_language":{"type":"string","nullable":true}},"required":["type","key","fallback_language"]}},"taxonomy_available":{"type":"boolean"},"source_text_translated":{"type":"boolean"}},"required":["language","fallback_language","terms","missing","taxonomy_available","source_text_translated"]},"Inspection":{"type":"object","properties":{"schema_version":{"type":"integer","nullable":true},"mapper_contract_version":{"type":"integer","nullable":true},"report_id":{"type":"string","nullable":true},"status":{"type":"string","nullable":true},"visibility":{"type":"string","nullable":true},"language":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time","nullable":true},"system_updated_at":{"type":"string","format":"date-time","nullable":true},"vehicle_ref":{"type":"object","properties":{"domain_id":{"type":"integer"},"listing_id":{"type":"string"},"site_car_id":{"type":"integer","nullable":true},"vin":{"type":"string","nullable":true}}},"vehicle_snapshot":{"oneOf":[{"type":"object","properties":{"title":{"type":"string","nullable":true},"brand":{"type":"string","nullable":true},"model":{"type":"string","nullable":true},"generation":{"type":"string","nullable":true},"badge":{"type":"string","nullable":true},"vin":{"type":"string","nullable":true},"listing_id":{"type":"string","nullable":true},"source_domain":{"type":"string","nullable":true},"fuel_type":{"type":"string","nullable":true},"transmission":{"type":"string","nullable":true},"engine_type":{"type":"string","nullable":true},"engine_code":{"type":"string","nullable":true},"first_registered_at":{"type":"string","nullable":true},"color":{"type":"string","nullable":true},"body_style":{"type":"string","nullable":true},"year":{"type":"integer","nullable":true},"engine_volume_cc":{"type":"integer","nullable":true},"mileage_km":{"type":"number","nullable":true}}},{"type":"array","maxItems":0,"items":{}}],"description":"Object, or [] if the stored PHP object is empty. Missing report objects are returned as {}."},"source":{"oneOf":[{"type":"object","properties":{"source_key":{"type":"string","nullable":true},"source_type":{"type":"string","nullable":true},"source_report_id":{"type":"string","nullable":true},"source_language":{"type":"string","nullable":true},"mapper_version":{"type":"string","nullable":true},"imported_at":{"type":"string","format":"date-time","nullable":true}}},{"type":"array","maxItems":0,"items":{}}],"description":"Object, or [] if the stored PHP object is empty. Missing report objects are returned as {}."},"access":{"oneOf":[{"type":"object","properties":{"attach_to_listing":{"type":"boolean"}}},{"type":"array","maxItems":0,"items":{}}],"description":"Object, or [] if the stored PHP object is empty. Missing report objects are returned as {}."},"media":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","nullable":true},"type_key":{"type":"string","nullable":true},"external_url":{"type":"string","nullable":true},"local_path":{"type":"string","nullable":true},"original_name":{"type":"string","nullable":true},"extension":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"block_id":{"type":"string","nullable":true},"checked_item_id":{"type":"string","nullable":true},"server_id":{"type":"integer","nullable":true},"sort_order":{"type":"integer","nullable":true}}}},"files":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","nullable":true},"type_key":{"type":"string","nullable":true},"external_url":{"type":"string","nullable":true},"local_path":{"type":"string","nullable":true},"original_name":{"type":"string","nullable":true},"extension":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"block_id":{"type":"string","nullable":true},"checked_item_id":{"type":"string","nullable":true},"server_id":{"type":"integer","nullable":true},"sort_order":{"type":"integer","nullable":true}}}},"limitations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","nullable":true},"type_key":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"source_label":{"type":"string","nullable":true}}}},"translations":{"$ref":"#/components/schemas/ReportTranslations"},"uuid":{"type":"string","nullable":true},"inspected_at":{"type":"string","format":"date-time","nullable":true},"valid_until":{"type":"string","format":"date-time","nullable":true},"updated_at":{"type":"string","format":"date-time","nullable":true},"participants":{"type":"array","items":{"type":"object","properties":{"role_key":{"type":"string","nullable":true},"name":{"type":"string","nullable":true},"source_label":{"type":"string","nullable":true},"company_id":{"type":"integer","nullable":true},"user_id":{"type":"integer","nullable":true}}}},"conclusions":{"oneOf":[{"type":"object","properties":{"overall_result_key":{"type":"string","nullable":true},"accident_status_key":{"type":"string","nullable":true},"water_damage_status_key":{"type":"string","nullable":true},"fire_damage_status_key":{"type":"string","nullable":true},"chemical_damage_status_key":{"type":"string","nullable":true},"biohazard_status_key":{"type":"string","nullable":true},"evaluation_score":{"type":"string","nullable":true},"notes":{"type":"string","nullable":true}}},{"type":"array","maxItems":0,"items":{}}],"description":"Object, or [] if the stored PHP object is empty. Missing report objects are returned as {}."},"source_claims":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","nullable":true},"type_key":{"type":"string","nullable":true},"result_key":{"type":"string","nullable":true},"source_code":{"type":"string","nullable":true},"source_label":{"type":"string","nullable":true},"description":{"type":"string","nullable":true}}}},"inspection_blocks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","nullable":true},"key":{"type":"string","nullable":true},"result_key":{"type":"string","description":"Inspection result taxonomy key. Common values: ok, issue, not_checked, not_applicable, not_equipped, unknown. New approved keys may appear.","nullable":true},"source_code":{"type":"string","nullable":true},"source_label":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"sort_order":{"type":"integer","nullable":true},"checked_count":{"type":"integer","nullable":true},"passed_count":{"type":"integer","nullable":true},"issue_count":{"type":"integer","nullable":true},"not_checked_count":{"type":"integer","nullable":true}}}},"checked_items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","nullable":true},"block_id":{"type":"string","nullable":true},"block_key":{"type":"string","nullable":true},"part_key":{"type":"string","nullable":true},"part_label":{"type":"string","nullable":true},"location_key":{"type":"string","nullable":true},"location_label":{"type":"string","nullable":true},"severity_key":{"type":"string","nullable":true},"damage_rank_key":{"type":"string","nullable":true},"accident_relevance_key":{"type":"string","nullable":true},"recommendation_key":{"type":"string","nullable":true},"clarification":{"type":"string","nullable":true},"visual_map_id":{"type":"string","nullable":true},"visual_marker_id":{"type":"string","nullable":true},"visual_marker_label":{"type":"string","nullable":true},"visual_shape_key":{"type":"string","nullable":true},"source_code":{"type":"string","nullable":true},"source_label":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"result_key":{"type":"string","description":"Inspection result taxonomy key. Common values: ok, issue, not_checked, not_applicable, not_equipped, unknown. New approved keys may appear.","nullable":true},"issue_type_keys":{"type":"array","items":{"type":"string"}},"evidence_media_ids":{"type":"array","items":{"type":"string"}},"visual_x":{"type":"number","nullable":true},"visual_y":{"type":"number","nullable":true},"visual_width":{"type":"number","nullable":true},"visual_height":{"type":"number","nullable":true},"measurements":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","nullable":true},"type_key":{"type":"string","nullable":true},"value_text":{"type":"string","nullable":true},"unit_key":{"type":"string","nullable":true},"result_key":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"value_number":{"type":"number","nullable":true}}}}}}},"diagnostic_errors":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","nullable":true},"system_key":{"type":"string","nullable":true},"system_label":{"type":"string","nullable":true},"code":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"status_key":{"type":"string","nullable":true},"severity_key":{"type":"string","nullable":true},"source_label":{"type":"string","nullable":true}}}}},"description":"Only public, published reports. Canonical *_key values are translation keys; IDs and source labels are not. unknown never means ok. Open-ended taxonomies require a fallback for new keys. See the inspection guide on this page."},"VehicleHistory":{"type":"object","properties":{"schema_version":{"type":"integer","nullable":true},"mapper_contract_version":{"type":"integer","nullable":true},"report_id":{"type":"string","nullable":true},"status":{"type":"string","nullable":true},"visibility":{"type":"string","nullable":true},"language":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time","nullable":true},"system_updated_at":{"type":"string","format":"date-time","nullable":true},"vehicle_ref":{"type":"object","properties":{"domain_id":{"type":"integer"},"listing_id":{"type":"string"},"site_car_id":{"type":"integer","nullable":true},"vin":{"type":"string","nullable":true}}},"vehicle_snapshot":{"oneOf":[{"type":"object","properties":{"title":{"type":"string","nullable":true},"brand":{"type":"string","nullable":true},"model":{"type":"string","nullable":true},"generation":{"type":"string","nullable":true},"badge":{"type":"string","nullable":true},"vin":{"type":"string","nullable":true},"listing_id":{"type":"string","nullable":true},"source_domain":{"type":"string","nullable":true},"fuel_type":{"type":"string","nullable":true},"transmission":{"type":"string","nullable":true},"engine_type":{"type":"string","nullable":true},"engine_code":{"type":"string","nullable":true},"first_registered_at":{"type":"string","nullable":true},"color":{"type":"string","nullable":true},"body_style":{"type":"string","nullable":true},"year":{"type":"integer","nullable":true},"engine_volume_cc":{"type":"integer","nullable":true},"mileage_km":{"type":"number","nullable":true}}},{"type":"array","maxItems":0,"items":{}}],"description":"Object, or [] if the stored PHP object is empty. Missing report objects are returned as {}."},"source":{"oneOf":[{"type":"object","properties":{"source_key":{"type":"string","nullable":true},"source_type":{"type":"string","nullable":true},"source_report_id":{"type":"string","nullable":true},"source_language":{"type":"string","nullable":true},"mapper_version":{"type":"string","nullable":true},"imported_at":{"type":"string","format":"date-time","nullable":true}}},{"type":"array","maxItems":0,"items":{}}],"description":"Object, or [] if the stored PHP object is empty. Missing report objects are returned as {}."},"access":{"oneOf":[{"type":"object","properties":{"attach_to_listing":{"type":"boolean"}}},{"type":"array","maxItems":0,"items":{}}],"description":"Object, or [] if the stored PHP object is empty. Missing report objects are returned as {}."},"media":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","nullable":true},"type_key":{"type":"string","nullable":true},"external_url":{"type":"string","nullable":true},"local_path":{"type":"string","nullable":true},"original_name":{"type":"string","nullable":true},"extension":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"block_id":{"type":"string","nullable":true},"checked_item_id":{"type":"string","nullable":true},"server_id":{"type":"integer","nullable":true},"sort_order":{"type":"integer","nullable":true}}}},"files":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","nullable":true},"type_key":{"type":"string","nullable":true},"external_url":{"type":"string","nullable":true},"local_path":{"type":"string","nullable":true},"original_name":{"type":"string","nullable":true},"extension":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"block_id":{"type":"string","nullable":true},"checked_item_id":{"type":"string","nullable":true},"server_id":{"type":"integer","nullable":true},"sort_order":{"type":"integer","nullable":true}}}},"limitations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","nullable":true},"type_key":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"source_label":{"type":"string","nullable":true}}}},"translations":{"$ref":"#/components/schemas/ReportTranslations"},"checked_at":{"type":"string","format":"date-time","nullable":true},"coverage":{"oneOf":[{"type":"object","properties":{"completeness_key":{"type":"string","nullable":true},"period_start":{"type":"string","nullable":true},"period_end":{"type":"string","nullable":true},"section_keys":{"type":"array","items":{"type":"string"}}}},{"type":"array","maxItems":0,"items":{}}],"description":"Object, or [] if the stored PHP object is empty. Missing report objects are returned as {}."},"summary":{"oneOf":[{"type":"object","properties":{"first_registered_at":{"type":"string","nullable":true},"currency":{"type":"string","nullable":true},"owner_change_count":{"type":"integer","nullable":true},"registration_change_count":{"type":"integer","nullable":true},"insurance_claim_count":{"type":"integer","nullable":true},"vehicle_damage_claim_count":{"type":"integer","nullable":true},"third_party_damage_claim_count":{"type":"integer","nullable":true},"total_loss_count":{"type":"integer","nullable":true},"flood_total_loss_count":{"type":"integer","nullable":true},"flood_partial_loss_count":{"type":"integer","nullable":true},"theft_count":{"type":"integer","nullable":true},"vehicle_damage_claim_cost":{"type":"number","nullable":true},"third_party_damage_claim_cost":{"type":"number","nullable":true}}},{"type":"array","maxItems":0,"items":{}}],"description":"Object, or [] if the stored PHP object is empty. Missing report objects are returned as {}."},"checks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","nullable":true},"type_key":{"type":"string","nullable":true},"evidence_type_key":{"type":"string","nullable":true},"verification_key":{"type":"string","nullable":true},"source_code":{"type":"string","nullable":true},"source_label":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"result_key":{"type":"string","enum":["present","not_present","unknown","not_applicable"]},"count":{"type":"integer","nullable":true}}}},"events":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","nullable":true},"type_key":{"type":"string","nullable":true},"subtype_key":{"type":"string","nullable":true},"occurred_at":{"type":"string","nullable":true},"ended_at":{"type":"string","nullable":true},"status_key":{"type":"string","nullable":true},"evidence_type_key":{"type":"string","nullable":true},"verification_key":{"type":"string","nullable":true},"organization_name":{"type":"string","nullable":true},"organization_role_key":{"type":"string","nullable":true},"currency":{"type":"string","nullable":true},"source_code":{"type":"string","nullable":true},"source_label":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"date_precision_key":{"type":"string","enum":["datetime","day","month","year","unknown"]},"mileage_km":{"type":"number","nullable":true},"amount_total":{"type":"number","nullable":true},"amount_insurance_benefit":{"type":"number","nullable":true},"amount_parts":{"type":"number","nullable":true},"amount_labor":{"type":"number","nullable":true},"amount_painting":{"type":"number","nullable":true},"details":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","nullable":true},"value_text":{"type":"string","nullable":true},"value_date":{"type":"string","nullable":true},"unit_key":{"type":"string","nullable":true},"source_code":{"type":"string","nullable":true},"source_label":{"type":"string","nullable":true},"value_number":{"type":"number","nullable":true}}}}}}}},"description":"History belongs to the exact domain_id + listing_id in vehicle_ref. Do not copy it to another listing. Missing or empty reports do not prove an accident-free history. Taxonomies can grow; preserve unknown keys and source evidence."},"ListingFieldCondition":{"type":"object","additionalProperties":false,"properties":{"eq":{},"in":{"type":"array","minItems":1,"maxItems":100,"items":{}},"gt":{},"gte":{},"lt":{},"lte":{},"exists":{"type":"boolean"},"currency":{"type":"string","pattern":"^[A-Za-z]{3}$"}},"description":"Operators, scalar types and constraints are authorized at runtime by /listing-fields. eq/in/exists are alternatives to ranges; native currency is mandatory only for money comparisons."},"ListingFieldTranslations":{"type":"object","additionalProperties":false,"properties":{"en":{"type":"object","properties":{"label":{"type":"string"},"description":{"type":"string"}}},"ru":{"type":"object","properties":{"label":{"type":"string"},"description":{"type":"string"}}},"uk":{"type":"object","properties":{"label":{"type":"string"},"description":{"type":"string"}}},"pl":{"type":"object","properties":{"label":{"type":"string"},"description":{"type":"string"}}},"bg":{"type":"object","properties":{"label":{"type":"string"},"description":{"type":"string"}}},"sq":{"type":"object","properties":{"label":{"type":"string"},"description":{"type":"string"}}},"ro":{"type":"object","properties":{"label":{"type":"string"},"description":{"type":"string"}}}},"description":"Explicit localized names and descriptions. Select the current UI locale; canonical label and description remain source text."},"ListingFieldDefinition":{"type":"object","properties":{"translations":{"$ref":"#/components/schemas/ListingFieldTranslations"},"id":{"type":"integer"},"key":{"type":"string"},"label":{"type":"string"},"description":{"type":"string","nullable":true},"examples":{"type":"array","items":{}},"type":{"type":"string","enum":["string","integer","decimal","boolean","date","url","json"]},"is_array":{"type":"boolean"},"is_money":{"type":"boolean"},"constraints":{"type":"object","additionalProperties":true},"state":{"type":"string"},"indexed":{"type":"boolean"},"filterable":{"type":"boolean"},"storage_path":{"type":"string"},"operators":{"type":"array","items":{"type":"string"}},"domain_ids":{"type":"array","items":{"type":"integer"}}},"required":["id","key","type","filterable","operators","domain_ids"]},"ListingFieldCatalogue":{"type":"object","properties":{"schema_version":{"type":"integer","enum":[1]},"revision":{"type":"string","description":"Monotonic catalogue revision; keep as a string."},"fields":{"type":"array","items":{"$ref":"#/components/schemas/ListingFieldDefinition"}},"bindings":{"type":"array","items":{"type":"object","properties":{"domain_id":{"type":"integer"},"field_id":{"type":"integer"},"description":{"type":"string","nullable":true},"translations":{"type":"object","additionalProperties":false,"properties":{"en":{"type":"object","properties":{"description":{"type":"string"}}},"ru":{"type":"object","properties":{"description":{"type":"string"}}},"uk":{"type":"object","properties":{"description":{"type":"string"}}},"pl":{"type":"object","properties":{"description":{"type":"string"}}},"bg":{"type":"object","properties":{"description":{"type":"string"}}},"sq":{"type":"object","properties":{"description":{"type":"string"}}},"ro":{"type":"object","properties":{"description":{"type":"string"}}}},"description":"Explicit translations of domain-specific notes, keyed by UI locale."}},"required":["domain_id","field_id"]}}},"required":["schema_version","revision","fields","bindings"]},"Listing":{"type":"object","properties":{"custom_fields":{"type":"object","additionalProperties":true,"description":"Published indexed values for this specific listing and its enabled domain bindings. Discover authorized keys/types/constraints through GET /listing-fields. Preserve zero, false and homogeneous arrays. Missing values are omitted. Stored-only fields stay in source_data; no historical backfill."},"external":{"type":"object","properties":{"id":{"type":"string","description":"Source listing ID; distinct from the internal car ID."},"domain":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true}},"required":["id","name"]},"url":{"type":"string"}},"required":["id","domain","url"]},"archived":{"type":"boolean"},"title":{"oneOf":[{"type":"object","additionalProperties":{"type":"string"},"nullable":true},{"type":"array","maxItems":0,"items":{"type":"string"}}],"description":"Language-to-title map, returned without selecting a language from lang. Keys are locale codes (for example en or ko); use an available translation as a fallback. Returns null when missing, or [] for an empty stored PHP map.","example":{"en":"Example vehicle"}},"odometer":{"type":"number","nullable":true},"location":{"oneOf":[{"type":"object","properties":{"iso":{"type":"string","nullable":true},"postal_code":{"type":"string","nullable":true},"country":{"oneOf":[{"type":"integer"},{"type":"string"}]},"location_admin_1":{"oneOf":[{"type":"integer"},{"type":"string"}]},"location_admin_2":{"oneOf":[{"type":"integer"},{"type":"string"}]},"location_id":{"oneOf":[{"type":"integer"},{"type":"string"}]},"location_admin_3":{"oneOf":[{"type":"integer"},{"type":"string"}],"description":"Source administrative value; not a guaranteed location dictionary ID."},"position":{"type":"object","properties":{"lat":{"type":"number"},"lon":{"type":"number"}}}}},{"type":"array","maxItems":0,"items":{}}],"description":"Legacy location object, or [] when unavailable. Use location_details for a uniform ID/name format across all vehicle endpoints. /search and /listing normally expose stored IDs; /cars, /cars/{car_id} and /cars/vin/{vin} attempt to replace country, location_admin_1, location_admin_2 and location_id with localized names, so values can be strings or unresolved IDs. Resolve numeric country via /countries/{id}; resolve numeric location_id, location_admin_1 and location_admin_2 via /locations/{id}, or batch them with ids[]. Do not send already localized names as IDs. See the location dictionary endpoints."},"location_details":{"allOf":[{"$ref":"#/components/schemas/ListingLocationDetails"}],"description":"Always present on every listing in /search, /cars, car ID/VIN and listing lookups. Same additive shape everywhere; legacy location is preserved. country maps from country_id, region from location_admin_1, district from location_admin_2, place from location_id. Each missing component is null. A known positive ID remains present with name:null if unresolved; an existing textual source label has id:null. No city/parent inference or reverse geocoding is performed. place is the referenced geographic entry, not necessarily a city. Read names here for display; no extra client lookup is needed. Names follow lang and dictionary fallback rules. All unique country/location IDs are collected from visible listings across the response before bulk lookup, in batches of at most 1000 dictionary documents. Empty ID sets need no lookup; there are no per-car location requests. Regional self-references may produce duplicate IDs; deduplicate labels by ID within the location namespace."},"images":{"type":"array","items":{"$ref":"#/components/schemas/ListingImage"}},"video":{"type":"array","items":{"type":"string"},"nullable":true,"description":"Video URLs. Returns an array (including []), or null when unavailable; never a single URL string.","example":["https://cars.example.com/videos/example.mp4"]},"created_at":{"type":"string","format":"date-time","nullable":true},"last_seen_at":{"type":"string","format":"date-time","nullable":true},"updated_at":{"type":"string","format":"date-time","nullable":true},"auction_at":{"type":"string","format":"date-time","nullable":true},"price":{"type":"object","properties":{"price":{"type":"number","nullable":true},"currency":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true}},"required":["id","name"],"nullable":true},"negotiable":{"type":"boolean","nullable":true},"history":{"type":"array","items":{"$ref":"#/components/schemas/PriceHistoryEntry"},"nullable":true}}},"seller_type":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true}},"required":["id","name"],"nullable":true},"availability":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true}},"required":["id","name"],"nullable":true},"condition":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true}},"required":["id","name"],"nullable":true},"damage":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true}},"required":["id","name"],"nullable":true},"second_damage":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true}},"required":["id","name"],"nullable":true},"airbag_state":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true}},"required":["id","name"],"nullable":true},"document_id":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true}},"required":["id","name"],"nullable":true},"option_ids":{"type":"array","items":{"type":"integer"}},"is_auction":{"type":"boolean","nullable":true},"current_bid":{"type":"number","nullable":true},"keys_available":{"type":"boolean","nullable":true},"is_manufacturer_certified":{"type":"boolean","nullable":true},"has_history_reports":{"type":"boolean","description":"Always included, as true or false: whether this listing has at least one public vehicle history report."},"is_leasing":{"type":"boolean","description":"Listing leasing flag; omitted when the source has no boolean value. The is_leasing=false query filter includes missing and null source values."},"source_data":{"oneOf":[{"type":"object","additionalProperties":true,"description":"Source-owned fields may evolve. Preserve unknown properties."},{"type":"array","items":{}}],"description":"Source-owned passthrough object or array; omitted when unavailable or empty. Registered stored-only fields are described by authenticated GET /listing-fields, including their types and storage paths; explicit null clears a typed stored value. Preserve unknown fields. Historical comparison estimates do not replace listing prices; never infer their currency."},"has_registration":{"type":"boolean"},"description":{"type":"string"}},"required":["external","archived","location_details","images","option_ids","has_history_reports"]},"PriceHistoryEntry":{"type":"object","properties":{"price":{"type":"number","nullable":true},"currency_id":{"type":"integer","nullable":true},"created_at":{"type":"string","format":"date-time","nullable":true}}},"Car":{"type":"object","properties":{"id":{"type":"string","description":"Opaque internal car identifier. Preserve it as a string."},"has_inspections":{"type":"boolean","description":"Always included, as true or false. true when the car has at least one public, published inspection on one of its listings; false when it has none. /search, /cars and /cars/{car_id} return the stored flag, so it can be true while inspections is empty (for example when the report belongs to a listing outside your source scope). /listing/{domain_id}/{listing_id} recomputes it from that listing only. Render reports from the inspections array; use the flag for badges and filters."},"has_history_reports":{"type":"boolean","description":"Always included, as true or false. true when at least one public vehicle history report is linked to a listing in your scope; false otherwise. Detailed endpoints recompute it from the returned vehicle_history_reports. For a per-source badge, use listings[].has_history_reports."},"year":{"type":"integer"},"month":{"type":"integer"},"engine_volume":{"type":"integer"},"cylinders":{"type":"integer"},"doors":{"type":"integer"},"seats":{"type":"integer"},"transmission_steps":{"type":"integer"},"power_hp":{"type":"integer"},"battery_capacity_kwh":{"type":"number"},"vin":{"type":"string"},"brand":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true}},"required":["id","name"]},"model":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true}},"required":["id","name"]},"interior_color":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true}},"required":["id","name"],"nullable":true,"description":"Interior color of the vehicle, normalized with the same color IDs as exterior color. Omitted when unknown."},"vehicle_type":{"type":"integer","enum":[1,2],"description":"Stored vehicle type: 1 automobile, 2 motorcycle. Missing legacy type is returned as 1."},"generation_id":{"type":"integer","description":"Stored generation ID; null when not normalized. Use /generations/{model_id} to resolve it.","nullable":true},"variant_id":{"type":"integer","description":"Stored variant ID; null when not normalized. Use /variants/{generation_id} to resolve it.","nullable":true},"trim_id":{"type":"integer","description":"Stored trim ID; null when not normalized. Use /trims/{generation_id} to resolve it.","nullable":true},"body_type":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true}},"required":["id","name"],"nullable":true},"transmission":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true}},"required":["id","name"],"nullable":true},"fuel":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true}},"required":["id","name"],"nullable":true},"color":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true}},"required":["id","name"],"nullable":true},"market_origin":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true}},"required":["id","name"],"nullable":true},"drive_wheels":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true}},"required":["id","name"],"nullable":true},"emission_standard":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true}},"required":["id","name"],"nullable":true},"steering_wheel_position":{"$ref":"#/components/schemas/SteeringWheelPosition"},"badge":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"option_ids":{"type":"array","items":{"type":"integer"}},"listings":{"type":"array","items":{"$ref":"#/components/schemas/Listing"}},"inspections":{"type":"array","items":{"$ref":"#/components/schemas/Inspection"}},"vehicle_history_reports":{"type":"array","items":{"$ref":"#/components/schemas/VehicleHistory"}},"hash":{"type":"string","description":"SHA-256 of serialized vehicle data excluding root created_at/updated_at and listing created_at/last_seen_at/updated_at. Includes location_details, so adding this field or changing localized names can change the hash.","nullable":true}},"required":["id","vehicle_type","generation_id","variant_id","trim_id","has_inspections","has_history_reports","option_ids","listings","hash"],"description":"Unavailable root attributes are often omitted. Nested values may be null. /search returns availability flags without full report arrays; /cars and exact lookups attach reports. Listings are restricted to the key/domain scope but may include other listings of the same merged car. Never assume the first listing is the requested one."},"CarDetail":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Car"}},"required":["data"]},"CarPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Car"}},"links":{"type":"object","properties":{"first":{"type":"string"},"last":{"type":"string"},"prev":{"type":"string","nullable":true},"next":{"type":"string","nullable":true}}},"meta":{"type":"object","properties":{"current_page":{"type":"integer"},"from":{"type":"integer","nullable":true},"last_page":{"type":"integer"},"links":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","nullable":true},"label":{"type":"string"},"active":{"type":"boolean"}}}},"path":{"type":"string"},"per_page":{"type":"integer"},"to":{"type":"integer","nullable":true},"total":{"type":"integer","description":"Search total can stop at 10000. Treat 10000 as a lower bound; use /search/count with the same filters for an exact count."}}}},"required":["data","links","meta"]},"CarScroll":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Car"}},"next_url":{"type":"string","description":"HTTPS URL on the current public API host; legacy or unknown hosts fall back to api.carstat.dev. Follow unchanged, including the domain scope. Contains your API key; do not publish it."},"scroll_id":{"type":"string","nullable":true},"total":{"type":"integer","description":"May be null when the cached total is unavailable.","nullable":true},"message":{"type":"string","description":"No more data when the scroll is complete; next_url is then omitted."}},"required":["data","scroll_id","total"]},"Count":{"type":"object","properties":{"count":{"type":"integer","minimum":0}},"required":["count"]}}}}