A read-only, advert-only feed of your live for-sale stock, built for syndicating to your own website. Each listing carries only public advert data - never cost, funding, purchase, reserve or customer information.
Use /vehicles to manage your stock (create, update, price, publish), and /listings to publish it. The listing is a curated, stable subset of the vehicle object, scoped to what should appear in an advert, so it is safe to hand to third-parties without exposing your business data - even where a key would otherwise be over-granted.
null where the vehicle has no value, so your parsing never breaks.Looking to integrate a marketplace or third-party service? This endpoint is linked to the website sales channel, using this means no independent control for your specific sales channel and no promotion of your service within MotorDesk. Please contact us to discuss your integration.
Listings require the single listings:read scope. Issue a key with only that scope for a syndication partner: it can read listings and nothing else.
A listing uses the same field names and structure as a vehicle, grouped under data. data.vehicle, data.history, data.option and data.spec mirror the vehicle response; data.stock carries only advertised pricing and identity; data.finance carries the advertised representative finance example (headline monthly plus the full breakdown).
{
"id": 84213,
"tag": "AB12CDEF",
"country": "UK",
"status": { "id": 2, "name": "for-sale", "label": "For Sale" },
"registration": "EO68NRJ",
"url_full": "https://example-motors.co.uk/vehicles/AB12CDEF/bmw-3-series/",
"data": {
"vehicle": { "type": "Car", "make": "BMW", "model": "3 Series", "derivative": "320i M Sport 4dr Auto", "fuel": "Petrol", "transmission": "Automatic", "mileage": 38450, "colour": "Black", "...": "..." },
"history": { "year": 2020, "condition": "Used", "service_history": "Full", "...": null },
"stock": { "price_website": "18995.00", "price_rrp": "42000.00", "vin": "WBA8E9105HK000000" },
"finance": { "example_monthly": "507.75", "example": { "cash_price": "20000.00", "total_deposit": "2000.00", "monthly_payment": "507.75", "total_monthly_payments": 25, "final_payment": "7856.00", "term": 27, "representative_apr": 10.9, "...": "..." } },
"option": { "option_custom": [], "attention": "Full Service History", "feature": {} },
"spec": { "engine": {}, "fuel": {}, "size": {} }
},
"media": [ { "url": "...", "type": "image", "position": 0 } ],
"updated": 1781303332,
"hash": "9b1d4c7a8f2e4a1b"
}
The full field list is in the reference below. status.name tells you whether a listing is for-sale, reserved, sold or complete.
The recommended pattern is snapshot once, then react to events, and reconcile periodically - far cheaper than re-polling the whole feed:
GET /listings (cursor pagination) to build your copy.vehicle.created, vehicle.updated, vehicle.sold, vehicle.deleted). On a change, fetch GET /listings/{id}; on sold/deleted, remove it.GET /listings/manifest and diff it against your copy to self-heal any missed events.To pull only what changed since your last sync, pass updated_since (a Unix timestamp; updated_before is also supported) with cursor pagination. Each listing's updated field is your high-water mark.
GET /2.0/listings?updated_since=1781300000
A delta only returns changed records - it cannot tell you what was removed. Use the manifest (or the sold/deleted webhooks) for removals.
GET /listings/manifest returns a lightweight { id, updated, hash } entry for every live listing. Diff it against your store: ids you don't have are new, a changed hash means refetch, and ids absent from the manifest have left stock. The same hash appears on the full listing, so you can compare without recomputing.
The manifest supports conditional requests: it returns an ETag, and a subsequent request sending If-None-Match gets a 304 Not Modified when nothing has changed since your last sync, so routine polls are nearly free.
Generated from the OpenAPI schema. Always matches the live API.
| Attribute | Type | Required | Description | Example |
|---|---|---|---|---|
id | integer | - | Vehicle id. | 84213 |
tag | string or null | - | AB12CDEF | |
country | string or null | - | UK | |
status | object | - | Type-aware status, as GET /vehicles returns it. | |
status.id | integer | - | 2 | |
status.name | string | - | Status slug (e.g. for-sale, reserved, sold, complete). | for-sale |
status.label | string | - | For Sale | |
registration | string or null | - | EO68NRJ | |
url_full | string or null | - | Public listing (VDP) URL on the dealer website. | https://example-motors.co.uk/vehicles/AB12CDEF/bmw-3-series/ |
data | object | - | Advert data, grouped as GET /vehicles groups it. Listed fields are always present (null when the vehicle has no value). | |
data.vehicle | object | - | Vehicle attributes. | |
data.vehicle.type | string or null | - | Vehicle class. | Car |
data.vehicle.make | string or null | - | BMW | |
data.vehicle.model | string or null | - | 3 Series | |
data.vehicle.generation | string or null | - | Saloon (2019 - 2023) | |
data.vehicle.derivative | string or null | - | 320i M Sport 4dr Auto | |
data.vehicle.trim | string or null | - | M Sport | |
data.vehicle.body | string or null | - | Saloon | |
data.vehicle.fuel | string or null | - | Petrol | |
data.vehicle.transmission | string or null | - | Automatic | |
data.vehicle.drivetrain | string or null | - | RWD | |
data.vehicle.doors | integer or null | - | 4 | |
data.vehicle.seats | integer or null | - | 5 | |
data.vehicle.colour | string or null | - | Black | |
data.vehicle.colour_name | string or null | - | Manufacturer colour name. | Sapphire Black |
data.vehicle.engine_size | string or null | - | 2.0 | |
data.vehicle.mileage | integer or null | - | 38450 | |
data.vehicle.registered | string or null | - | First registration date (YYYY-MM-DD). | 2020-03-01 |
data.vehicle.driver_position | string or null | - | RHD | |
data.vehicle.interior_upholstery | string or null | - | Leather | |
data.vehicle.interior_colour | string or null | - | Black | |
data.vehicle.exterior_finish | string or null | - | Metallic | |
data.vehicle.bedroom_layout | string or null | - | Bedroom layout (caravans/motorhomes). | |
data.vehicle.end_layout | string or null | - | End layout (caravans/motorhomes). | |
data.vehicle.bedroom | integer or null | - | Bedrooms (caravans/motorhomes). | 2 |
data.vehicle.berth | integer or null | - | Berths (caravans/motorhomes). | 4 |
data.vehicle.seat_belt | integer or null | - | Belted seats (caravans/motorhomes). | 4 |
data.vehicle.wheelchair | string or null | - | Wheelchair accessible (Yes/No). | No |
data.history | object | - | ||
data.history.year | integer or null | - | 2020 | |
data.history.condition | string or null | - | Used | |
data.history.keys | integer or null | - | Number of keys supplied. | 2 |
data.history.service_history | string or null | - | Full | |
data.stock | object | - | ||
data.stock.price_website | string or null | - | Advertised website price (2dp decimal string), or null for POA. | 18995.00 |
data.stock.price_rrp | string or null | - | Manufacturer RRP (2dp decimal string). | 42000.00 |
data.stock.vin | string or null | - | WBA8E9105HK000000 | |
data.finance | object | - | Representative finance, as GET /vehicles data.finance returns it. Always present; example_monthly and example are null when the vehicle has no finance example. | |
data.finance.example_monthly | string or null | - | Advertised representative monthly payment (2dp decimal string); null when finance is not enabled. | 507.75 |
data.finance.example | object or null | - | Representative finance example as shown on the advert; null when none has been generated. Figures are illustrative and subject to status. | |
data.finance.example.cash_price | string or null | - | Cash price. | 20000.00 |
data.finance.example.total_deposit | string or null | - | Total deposit. | 2000.00 |
data.finance.example.total_credit | string or null | - | Total amount of credit. | 18000.00 |
data.finance.example.first_payment | string or null | - | First payment. | 507.75 |
data.finance.example.monthly_payment | string or null | - | Regular monthly payment. | 507.75 |
data.finance.example.total_monthly_payments | integer or null | - | Number of monthly payments. | 25 |
data.finance.example.final_payment | string or null | - | Final payment. | 7856.00 |
data.finance.example.term | integer or null | - | Agreement duration in months. | 27 |
data.finance.example.admin_fee | string or null | - | Admin fee. | 0.00 |
data.finance.example.option_purchase_fee | string or null | - | Option to purchase fee. | 10.00 |
data.finance.example.interest_charge | string or null | - | Total interest charges. | 3057.50 |
data.finance.example.total_payable | string or null | - | Total amount payable. | 23057.50 |
data.finance.example.fixed_interest_rate | number or null | - | Annual fixed interest rate (percent). | 10.36 |
data.finance.example.representative_apr | number or null | - | Representative APR (percent). | 10.9 |
data.option | object | - | Full option section, as GET /vehicles data.option (option_custom, attention, description, website, feature). | |
data.spec | object | - | Full spec section, as GET /vehicles data.spec (performance, engine, battery, fuel, size, insurance, other). | |
media | array of object | - | Ordered advert media, as GET /vehicles returns it. | |
updated | integer | - | Unix timestamp last updated (use for delta sync). | 1781303332 |
hash | string | - | Change token, identical to the manifest entry hash for this listing. | 9b1d4c7a8f2e4a1b |
{
"id": 84213,
"tag": "AB12CDEF",
"country": "UK",
"status": {
"id": 2,
"name": "for-sale",
"label": "For Sale"
},
"registration": "EO68NRJ",
"url_full": "https://example-motors.co.uk/vehicles/AB12CDEF/bmw-3-series/",
"data": {
"vehicle": {
"type": "Car",
"make": "BMW",
"model": "3 Series",
"generation": "Saloon (2019 - 2023)",
"derivative": "320i M Sport 4dr Auto",
"trim": "M Sport",
"body": "Saloon",
"fuel": "Petrol",
"transmission": "Automatic",
"drivetrain": "RWD",
"doors": 4,
"seats": 5,
"colour": "Black",
"colour_name": "Sapphire Black",
"engine_size": "2.0",
"mileage": 38450,
"registered": "2020-03-01",
"driver_position": "RHD",
"interior_upholstery": "Leather",
"interior_colour": "Black",
"exterior_finish": "Metallic",
"bedroom_layout": "",
"end_layout": "",
"bedroom": 2,
"berth": 4,
"seat_belt": 4,
"wheelchair": "No"
},
"history": {
"year": 2020,
"condition": "Used",
"keys": 2,
"service_history": "Full"
},
"stock": {
"price_website": "18995.00",
"price_rrp": "42000.00",
"vin": "WBA8E9105HK000000"
},
"finance": {
"example_monthly": "507.75",
"example": {
"cash_price": "20000.00",
"total_deposit": "2000.00",
"total_credit": "18000.00",
"first_payment": "507.75",
"monthly_payment": "507.75",
"total_monthly_payments": 25,
"final_payment": "7856.00",
"term": 27,
"admin_fee": "0.00",
"option_purchase_fee": "10.00",
"interest_charge": "3057.50",
"total_payable": "23057.50",
"fixed_interest_rate": 10.36,
"representative_apr": 10.9
}
},
"option": {},
"spec": {}
},
"media": [
{}
],
"updated": 1781303332,
"hash": "9b1d4c7a8f2e4a1b"
}GET /2.0/listings · scope listings:read
Public advert view of for-sale, reserved and recently-sold stock for syndication. Supports delta sync (updated_since + cursor). Excludes all business, cost, funding and customer data by construction.
| Parameter | In | Type | Required | Description | Example |
|---|---|---|---|---|---|
page | query | integer | - | Page number, starting at 1 (offset pagination). | |
per_page | query | integer | - | Results per page (maximum 500). | |
cursor | query | string | - | Cursor pagination: pass the previous page's meta.pagination.next_cursor to continue from that point instead of page. Stable while the set changes underneath, so preferred for delta sync; a null next_cursor means the end. | |
make | query | string | - | Exact match, or use % for wildcard matching (requires search:wildcard, minimum 3 characters). | BMW |
model | query | string | - | Exact match, or use % for wildcard matching (requires search:wildcard). | 3 Series |
fuel | query | string | - | Exact match, or use % for wildcard matching (requires search:wildcard). | Petrol |
transmission | query | string | - | Exact match, or use % for wildcard matching (requires search:wildcard). | Automatic |
body | query | string | - | Exact match, or use % for wildcard matching (requires search:wildcard). | Saloon |
colour | query | string | - | Exact match, or use % for wildcard matching (requires search:wildcard). | Black |
year | query | string | - | Exact match, or a two-element array [from, to] for a range (e.g. year[]=2020&year[]=2023). An empty bound is open-ended. | |
mileage | query | string | - | Exact match, or a two-element array [from, to] for a range. An empty bound is open-ended. | |
price | query | string | - | Advertised website price. Exact match, or a two-element array [from, to] for a range. An empty bound is open-ended. | |
updated_since | query | integer | - | Unix timestamp; only listings changed at or after this time (delta sync). | |
updated_before | query | integer | - | Unix timestamp; only listings changed before this time. | |
cursor | query | string | - | Keyset pagination cursor from a previous response's meta.pagination.next_cursor. When supplied, page/total are not returned. | |
fields | query | string | - | Comma-separated dot-paths to return only those fields, e.g. id,data.stock.price_channel. |
| Status | Description |
|---|---|
200 OK | Paginated listings |
Failures use the standard error responses (4xx/5xx) with the shared error envelope.
{
"success": true,
"data": [
{
"id": 84213,
"tag": "AB12CDEF",
"country": "UK",
"status": {
"id": 2,
"name": "for-sale",
"label": "For Sale"
},
"registration": "EO68NRJ",
"url_full": "https://example-motors.co.uk/vehicles/AB12CDEF/bmw-3-series/",
"data": {
"vehicle": {
"type": "Car",
"make": "BMW",
"model": "3 Series",
"generation": "Saloon (2019 - 2023)",
"derivative": "320i M Sport 4dr Auto",
"trim": "M Sport",
"body": "Saloon",
"fuel": "Petrol",
"transmission": "Automatic",
"drivetrain": "RWD",
"doors": 4,
"seats": 5,
"colour": "Black",
"colour_name": "Sapphire Black",
"engine_size": "2.0",
"mileage": 38450,
"registered": "2020-03-01",
"driver_position": "RHD",
"interior_upholstery": "Leather",
"interior_colour": "Black",
"exterior_finish": "Metallic",
"bedroom_layout": "",
"end_layout": "",
"bedroom": 2,
"berth": 4,
"seat_belt": 4,
"wheelchair": "No"
},
"history": {
"year": 2020,
"condition": "Used",
"keys": 2,
"service_history": "Full"
},
"stock": {
"price_website": "18995.00",
"price_rrp": "42000.00",
"vin": "WBA8E9105HK000000"
},
"finance": {
"example_monthly": "507.75",
"example": {
"cash_price": "20000.00",
"total_deposit": "2000.00",
"total_credit": "18000.00",
"first_payment": "507.75",
"monthly_payment": "507.75",
"total_monthly_payments": 25,
"final_payment": "7856.00",
"term": 27,
"admin_fee": "0.00",
"option_purchase_fee": "10.00",
"interest_charge": "3057.50",
"total_payable": "23057.50",
"fixed_interest_rate": 10.36,
"representative_apr": 10.9
}
},
"option": {},
"spec": {}
},
"media": [
{}
],
"updated": 1781303332,
"hash": "9b1d4c7a8f2e4a1b"
}
],
"meta": {
"pagination": {
"page": 0,
"per_page": 0,
"total": 0,
"total_pages": 0,
"next_cursor": ""
}
}
}GET /2.0/listings/{id} · scope listings:read
Retrieve a single listing by vehicle id.
| Parameter | In | Type | Required | Description | Example |
|---|---|---|---|---|---|
id | path | string | Yes | Resource identifier in the path. | |
fields | query | string | - | Comma-separated dot-paths to return only those fields, e.g. id,data.stock.price_channel. |
| Status | Description |
|---|---|
200 OK | Get a Stock Listing |
Failures use the standard error responses (4xx/5xx) with the shared error envelope.
{
"success": true,
"data": {
"id": 84213,
"tag": "AB12CDEF",
"country": "UK",
"status": {
"id": 2,
"name": "for-sale",
"label": "For Sale"
},
"registration": "EO68NRJ",
"url_full": "https://example-motors.co.uk/vehicles/AB12CDEF/bmw-3-series/",
"data": {
"vehicle": {
"type": "Car",
"make": "BMW",
"model": "3 Series",
"generation": "Saloon (2019 - 2023)",
"derivative": "320i M Sport 4dr Auto",
"trim": "M Sport",
"body": "Saloon",
"fuel": "Petrol",
"transmission": "Automatic",
"drivetrain": "RWD",
"doors": 4,
"seats": 5,
"colour": "Black",
"colour_name": "Sapphire Black",
"engine_size": "2.0",
"mileage": 38450,
"registered": "2020-03-01",
"driver_position": "RHD",
"interior_upholstery": "Leather",
"interior_colour": "Black",
"exterior_finish": "Metallic",
"bedroom_layout": "",
"end_layout": "",
"bedroom": 2,
"berth": 4,
"seat_belt": 4,
"wheelchair": "No"
},
"history": {
"year": 2020,
"condition": "Used",
"keys": 2,
"service_history": "Full"
},
"stock": {
"price_website": "18995.00",
"price_rrp": "42000.00",
"vin": "WBA8E9105HK000000"
},
"finance": {
"example_monthly": "507.75",
"example": {
"cash_price": "20000.00",
"total_deposit": "2000.00",
"total_credit": "18000.00",
"first_payment": "507.75",
"monthly_payment": "507.75",
"total_monthly_payments": 25,
"final_payment": "7856.00",
"term": 27,
"admin_fee": "0.00",
"option_purchase_fee": "10.00",
"interest_charge": "3057.50",
"total_payable": "23057.50",
"fixed_interest_rate": 10.36,
"representative_apr": 10.9
}
},
"option": {},
"spec": {}
},
"media": [
{}
],
"updated": 1781303332,
"hash": "9b1d4c7a8f2e4a1b"
}
}GET /2.0/listings/manifest · scope listings:read
Lightweight {id, updated, hash} for every live listing, for cheap reconciliation: diff against your copy to find adds, changes and removals (absent ids are gone).
| Parameter | In | Type | Required | Description | Example |
|---|---|---|---|---|---|
cursor | query | string | - | Keyset pagination cursor from a previous response's meta.pagination.next_cursor. When supplied, page/total are not returned. | |
fields | query | string | - | Comma-separated dot-paths to return only those fields, e.g. id,data.stock.price_channel. |
| Status | Description |
|---|---|
200 OK | Stock Listing Manifest |
Failures use the standard error responses (4xx/5xx) with the shared error envelope.
{
"success": true,
"data": [
{
"id": 84213,
"updated": 1781303332,
"hash": "9b1d4c7a8f2e4a1b"
}
],
"meta": {
"pagination": {
"page": 0,
"per_page": 0,
"total": 0,
"total_pages": 0,
"next_cursor": ""
}
}
}