Discovery Contract — jlr (us)
The vetting gate between discovery and coding. This file is the human-written description + probe evidence; the authoritative gate state lives in the sidecar
discovery-contract.gate.json, whichpublic-api-implementchecks viacheck_contract_gate.py. Keep this table in sync with the sidecar.
- OEM / market:
jlr/us(Land Rover + Jaguar) - Discovered:
2026-06-12; updated2026-07-28(per-product fetch, Jaguar coverage, brand derivation) - Gate status: 🟢 PASS — all hard gates pass; identity_key inventory→models OVERRIDE user-approved (2026-06-12)
Gate summary
| # | Gate | Entity / param | Status | Evidence |
|---|---|---|---|---|
| 1 | Pagination contract | inventory | ✅ PASS | total=289, perPage=20, page2∩page1=0 VINs |
| 2 | Enumerator (model/nameplate) | models | ✅ PASS | base URL 302→version; root_config PRODUCT decomposition; 7 LR + Jag nameplates live |
| 3 | Enumerator (dealer) | dealers | ✅ PASS | multi-zip sweep per brand → LR + Jaguar ciCodes |
| 4 | Multi-value filter | inventory | ⬜ N/A | per-dealer NetDirector query, no combined filter |
| 5 | Body shape / bot-block | inventory | ✅ PASS | NetDirector JSON with static auth header; no dealer-page bot bypass |
| 6 | Body shape / bot-block | features (configurator) | ✅ PASS | JSONP rcjson(...), 200, strips cleanly |
| 7 | Data quality / plausibility | inventory | ✅ PASS | valid unique VINs, real prices $52-53k, mmc populated |
| 8 | Data quality / plausibility | dealers | ✅ PASS | real NYC coords (not 0.0), ciCode+name 100% |
| 9 | Data quality / plausibility | models | ✅ PASS | PRODUCT A-S-P300-110 @ $63,500 w/ 5000Code |
| 10 | Data quality / plausibility | features | ✅ PASS | 124 priced/described leaf features |
| 11 | Cross-source identity key | inventory→dealers | ✅ PASS | ccid→ciCode; dealer.location name match |
| 12 | Cross-source identity key | inventory→models | ✅ PASS | NetDirector modelCode → configurator manufacturer_model_code + model_year; ~44% null model codes unresolved |
| 13 | Cross-source identity key | features→models | ✅ PASS | shared programme_code, model_year_code, product_id key |
| 14 | Real fixture (no synthetic) | inventory | ✅ PASS | jlr_netdirector_sample.json |
| 15 | Real fixture (no synthetic) | dealers | ✅ PASS | jlr_retailerlocator_sample.json |
| 16 | Real fixture (no synthetic) | models | ✅ PASS | jlr_scs_sample.json (LIVE) |
| 17 | Real fixture (no synthetic) | features | ✅ PASS | jlr_scs_sample.json (LIVE) |
| 18 | Postman record | inventory | ✅ PASS | Collection uid 53897914-9cdbecc6-...a5e1 |
| 19 | Postman record | dealers | ✅ PASS | same collection |
| 20 | Postman record | models | ✅ PASS | same collection |
| 21 | Postman record | features | ✅ PASS | same collection |
Per-entity endpoints
| Entity | Endpoint (method + URL) | Auth / protocol | Fixture | Notes |
|---|---|---|---|---|
| dealers | GET https://retailerlocator.jaguarlandrover.com/dealers?postCode=&requestMarketLocale=en_us&brand={brand}&filter=dealer&radius=500&unitOfMeasure=Miles&country=us | Public; needs Origin/Referer per brand | tests/data/jlr/jlr_retailerlocator_sample.json | Fetched per brand (Land Rover, Jaguar). Key = ciCode. Jaguar codes 0→J transformed. |
| models | GET https://rules.config.landrover.com/rc/{brand_path}/en_us/{nameplate}_{my}/{ver}/.jsonp (root_config) | Public JSONP | tests/data/jlr/jlr_configurator_sample.json | Root config only. PRODUCT decomposition → model entities. |
| features | GET https://rules.config.landrover.com{product_query_href} (per-PRODUCT body_style_config) | Public JSONP | tests/data/jlr/jlr_configurator_sample.json | One request per PRODUCT. Non-structural categories extracted (excludes BODYSTYLE, MODEL, ENGINE, PRODUCT, CHARGES, CURATEDCHOICES). |
| inventory | POST https://production-api-oregon.search-api.netdirector.auto/api/vehicle-search | Static authorization header + brand-specific uuid param | jlr_netdirector_sample.json | Both brands. Per-dealer query; Jaguar dealer codes 0→J transformed. |
Cross-source identity / FK alignment (HARD)
| FK | Referencing entity.field | Target entity.field | Example value | Verified |
|---|---|---|---|---|
| inventory→dealers | inventory.dealer_code (location.manufacturerDealerNumber) | dealers.dealer_code (ciCode, Jaguar 0→J) | R0627 / J5806 | ✅ |
| inventory→models | inventory.manufacturer_model_code + model_year | models.manufacturer_model_code + model_year | AT663 + 2026 | ✅ |
| features→models | programme_code, model_year_code, product_id | same | L663, k26, a-xdyn-hse-p400-110 | ✅ |
Probe evidence
1. Pagination contract — inventory
paste pagination_probe block
2–3. Enumerators (model / dealer)
paste enumerator_probe blocks
4. Multi-value filter — inventory
N/A — inventory is scraped per dealer; no combined multi-value filter endpoint.
5–6. Body shape / bot-block
paste body_shape_probe blocks
7–10. Data quality / plausibility
paste data_quality_probe blocks per entity
11–13. Cross-source identity keys
paste value-match evidence for every FK listed in the sidecar requirements
14–17. Real fixtures
list every fixture path and the live request it came from
18–21. Postman records
list the Postman request/folder URL for every discovered endpoint
Probe results (verified 2026-06-12)
- Pagination (inventory): NetDirector is queried per dealer with
currentPage=1andpageSize=5000; the current fetcher does not page beyond the first per-dealer response. - Enumerator (model): base nameplate
/rc/lr/en_us/l663_k26/.jsonp→ 302 →/4cvli.jsonp; root_config PRODUCT decomposition enumerates all products per nameplate. Both/lr/and/jag/brand paths. All nameplates resolve live. - Enumerator (dealer): multi-zip locator sweep per brand (Land Rover + Jaguar), dedupe by
ciCode. Jaguar dealer codes transformed 0→J for NetDirector compatibility. - Body shape (inventory): NetDirector GraphQL returns JSON with the static
authorizationheader anduuidparameter; no dealer-page Cloudflare/Akamai scrape is required for the current inventory source. - Body shape (configurator): JSONP
rcjson(...), HTTP 200, 112KB, strips to JSON. No bot block. - Data quality: dealers real NYC coords (not 0.0); inventory valid unique VINs, real prices; models PRODUCT @ $63,500; features 124 priced leaves. ~44% of new-inventory records have null
modelCode(stub allocations).
Overrides
None currently documented.