Vehicle watches
Saved vehicle searches matched against every auction source your key can use and, if it has classifieds, the European classifieds — scanned every 10 minutes, with new matches delivered by polling or a signed webhook. Scope: watches. Granted per contract — not on a new key by default. Up to 10 criteria per watch and 25 active watches per key.
From a watch to a match
- 1Create the watch with POST /api/watches and keep the webhook_secret from the response — it is shown only here and when rotated.
- 2The first scan records what already matches, flagged initial: true. Later scans add only cars listed since.
- 3Either poll GET /api/watches/{watch_id}/matches with after_id set to the last next_after_id you saw, or receive each batch of new matches on your webhook_url.
- 4Verify every webhook delivery: X-Watch-Signature is sha256=<hex HMAC-SHA256 of "<X-Watch-Timestamp>.<raw body>"> under your webhook_secret.
The calling key’s watches, with their match counts.
Requires the watches scope.
Example request
GET https://api.thecarapi.com/api/watchesExample response
{
"success": true,
"watches": [
{
"id": 7,
"name": "Diesel 3 Series under 20k",
"criteria": [
{
"make": "BMW",
"model": "3 Series",
"fuel": "Diesel",
"year_from": 2018,
"max_price": 20000
}
],
"include_classifieds": true,
"webhook_url": "https://example.com/hooks/watch",
"webhook_enabled": true,
"active": true,
"match_count": 132
}
],
"contract_version": "2026-10-05"
}Save a vehicle configuration to keep searching for.
Requires the watches scope.
Parameters
criteriaobject | object[] · JSON bodyrequiredOne criterion or a list of up to 10; a car matching any of them matches the watch. Each needs make, and may give model, fuel, gearbox, country (ISO or europe), year_from / year_to, kilometers_from / kilometers_to, horsepower_from / horsepower_to (auctions only) and price_from / max_price.
Example {"make": "BMW", "model": "3 Series", "fuel": "Diesel", "year_from": 2018, "max_price": 20000}·Where the value comes from /api/brands, /api/models, /api/fuels, /api/gearboxes
namestring · JSON bodyFree text.
Example Diesel 3 Series under 20k·Where the value comes from Your label.
include_classifiedsboolean · JSON bodyDefault true. Also scan the European classifieds — only when the key has the classifieds scope.
Example true·Where the value comes from Your choice.
webhook_urlstring · JSON bodyhttps on a public address. Each batch of new matches is POSTed here, signed.
Example https://example.com/hooks/watch·Where the value comes from Your receiver.
Example request
POST https://api.thecarapi.com/api/watches
{"name": "Diesel 3 Series under 20k", "criteria": [{"make": "BMW", "model": "3 Series", "fuel": "Diesel", "year_from": 2018, "max_price": 20000}], "webhook_url": "https://example.com/hooks/watch"}Example response
{
"success": true,
"watch": {
"id": 7,
"name": "Diesel 3 Series under 20k",
"criteria": [
{
"make": "BMW",
"model": "3 Series",
"fuel": "Diesel",
"year_from": 2018,
"max_price": 20000
}
],
"include_classifieds": true,
"webhook_url": "https://example.com/hooks/watch",
"webhook_enabled": true,
"webhook_secret": "3f9c…",
"active": true
},
"contract_version": "2026-10-05"
}One watch.
Requires the watches scope.
Parameters
watch_idinteger · in the URL pathrequiredThe watch id.
Example 7·Where the value comes from /api/watches -> watches[].id
Example request
GET https://api.thecarapi.com/api/watches/7Example response
{
"success": true,
"watch": {
"id": 7,
"name": "Diesel 3 Series under 20k",
"active": true,
"match_count": 132
},
"contract_version": "2026-10-05"
}Change a watch.
Requires the watches scope.
Parameters
watch_idinteger · in the URL pathrequiredThe watch id.
Example 7·Where the value comes from /api/watches -> watches[].id
name / criteria / include_classifiedsstring | object[] | boolean · JSON bodyNew criteria restart the baseline: the next scan records what matches then as initial.
Example criteria·Where the value comes from As on create.
webhook_url / webhook_enabledstring | boolean · JSON bodyAn empty webhook_url removes it.
Example ""·Where the value comes from Your receiver.
activeboolean · JSON bodyPause or resume scanning.
Example false·Where the value comes from Your choice.
rotate_secretboolean · JSON bodytrue issues a new webhook_secret, returned in this response only.
Example true·Where the value comes from Your choice.
Example requests
PATCH https://api.thecarapi.com/api/watches/7
{"active": false}PATCH https://api.thecarapi.com/api/watches/7
{"rotate_secret": true}Example response
{
"success": true,
"watch": {
"id": 7,
"active": false
},
"contract_version": "2026-10-05"
}Delete a watch and its matches.
Requires the watches scope.
Parameters
watch_idinteger · in the URL pathrequiredThe watch id.
Example 7·Where the value comes from /api/watches -> watches[].id
Example request
DELETE https://api.thecarapi.com/api/watches/7Example response
{
"success": true,
"contract_version": "2026-10-05"
}Matches found for a watch, in the order they were found.
Requires the watches scope.
Parameters
watch_idinteger · in the URL pathrequiredThe watch id.
Example 7·Where the value comes from /api/watches -> watches[].id
after_idinteger · query stringStable cursor, so nothing is missed or repeated. Default 0.
Example 0·Where the value comes from The last next_after_id you received.
include_initialboolean · query stringDefault true. false skips what already matched when the watch was created.
Example false·Where the value comes from Your choice.
sourceenum · query stringOnly matches from one side.
Example auction·Where the value comes from auction or classified.
limitinteger · query stringDefault 100, maximum 500.
Example 100·Where the value comes from Page size.
Example requests
GET https://api.thecarapi.com/api/watches/7/matches?after_id=0GET https://api.thecarapi.com/api/watches/7/matches?after_id=1880&include_initial=falseExample response
{
"success": true,
"matches": [
{
"id": 1881,
"source": "auction",
"initial": false,
"matched_at": "2026-10-18T09:20:00Z",
"vehicle": {
"site": "openlane",
"auction_id": 11409652,
"title": "BMW 320d Touring",
"price_eur": 16900,
"landed_price_eur": 18450,
"api_url": "/api/auction/openlane/11409652"
}
}
],
"next_after_id": 1881,
"has_more": false,
"contract_version": "2026-10-05"
}What you get back
matches[].vehicleobjectThe car as it looked when found, with api_url (auctions) or url (classifieds, the original ad) to read it now.
next_after_id / has_moreinteger / booleanSend next_after_id as after_id next time; has_more says whether to ask again straight away.