contract 2026-09-03
Security

Authentication & scopes

Three interchangeable ways to present a key, the restrictions a key can carry, and the scope groups that gate each endpoint.

Every endpoint except the two liveness probes (/api/health/live and /api/health/ready) requires an API key. Present the key in one of these ways:

MethodHeader or parameterNotes
HeaderX-API-Key: <key>Recommended for server-to-server calls.
BearerAuthorization: Bearer <key>Equivalent to X-API-Key.
Query string?api_key=<key>Disabled by default; use only when explicitly enabled for your key. Keys in URLs end up in logs and referrers.
bash
# Header — the normal case
curl -H "X-API-Key: $API_KEY" "https://api.thecarapi.com/api/sites"

# Bearer — identical behaviour, useful when your HTTP layer already speaks OAuth
curl -H "Authorization: Bearer $API_KEY" "https://api.thecarapi.com/api/sites"

Key restrictions

RestrictionEffect when violated
IP or CIDR allowlistRequests from outside the list return 403.
Origin allowlistBrowser requests from other origins return 403.
Expiry dateRequests after the date return 401.
Status (revoked, suspended)All requests return 403.
Scope setA request to a route your key does not cover returns 403 with {"success": false, "error": "API key is not authorized for this route"}. There is no machine-readable error code in the body — branch on the status, not on the message text.

Five failed authentication attempts from one IP trigger a temporary brute-force lockout: every subsequent request from that address answers 429 for 15 minutes, including requests carrying a valid key. A successful authentication clears the counter, so a client that fixes its key on the first or second failure never reaches the threshold. Do not retry a 401 in a loop.

Published scope groups

ScopePublished access
searchInventory search, filter facets (individually or combined via /api/facets), sources, and the full model catalog
catalogManufacturer and model-group catalog
seoPopular searches and brand/model slug resolution
auctionsAuction detail, images, price history, and VIN history
detailsFull vehicle details, including upstream fetches
top-offersAuctions priced below their market reference
classifiedsEuropean classifieds feed, facets, and models (theparking remains a legacy alias)
archiveHistorical inventory search, stored detail and coverage statistics; granted separately
marketCars.bg and auction market price snapshots
calculatorImport cost calculator and supported countries
opsService health, the contract, and the API index

* grants every route. A scope may also be a literal URL rule rather than a group. public is a legacy compatibility bundle — search facets, catalog, SEO, auctions, calculator and health — preserved for older integrations; new keys are issued against the groups above.

Field grants

GroupFieldsDefault
listingIdentity, specifications, images, timing and VAT schemeAlways retained
source_pricescurrent_price, buy_now_price, start_price, final_priceIncluded
landed_pricescurrent_final, buynow_final, public_price_eur, current_bgn, buynow_bgnIncluded
house_valuationestimated_value_eurIncluded where available
vehicle_identitychassis_number, car_id, vin_ocrIncluded where available; VIN-history route access is separate
crawl_metacreated_at, updated_at, first_seen_at, last_seen_at, last_available_at, last_changed_atIncluded where available
landed_breakdowncurrent_tax, buynow_tax, current_tax_delivery, buynow_tax_deliverySeparate grant
market_referenceis_top_offer, top_offer_savings, top_offer_savings_pct, market_referenceSeparate grant
korea_mergesource_comparison, canonical_offerSeparate grant

These are provisioning defaults, not a promise about an existing key. Endpoint access does not automatically grant every response field: for example, top-offers can be callable while its market_reference block is omitted. Examples show illustrative fields; use the OpenAPI schema and handle omitted optional fields. Private bidder data and account credentials remain excluded regardless of field grants.

What a new key gets by default

Scopes are granted per endpoint, and a new customer key is issued with the common surface enabled and the rest switched off. If a route answers 403 on your key, it is not broken — it was not granted, and the operator can enable it.

Endpoints
Enabled by default/api/search, /api/brands, /api/models, /api/types, /api/years, /api/production-years, /api/fuels, /api/countries, /api/gearboxes, /api/sites, /load-models, /api/facets, /api/catalog/*, /api/seo/*, /api/auction/*, /api/auction-images/*, /api/calculator/*, /api/top-offers, /api/classifieds/*, /api/car-details, /api/contract, /api/health, /
Granted on request/api/archive/*, /api/vin/{vin}/history, /api/cars-bg-market, /api/auction-market, /api/listVehicles (and /listVehicles), /api/search/auction-ids

/api/health/live and /api/health/ready need no key and are unaffected by scopes.