Public Inventory Source
The inventory source fetches active dealer inventory from the Stellantis brand public web APIs
(jeep.com, dodge.com, ramtrucks.com, chrysler.com). It is specific to the Stellantis
project (projects/ai_stellantis).
Endpoint Pattern
https://www.<brand-domain>/hostd/inventory/getinventoryresults.json
Pagination uses pageNumber (1-based) and pageSize query params. Total record count is read
from result.data.metadata.totalcount in the first page response.
Partitioning by dealer (100k offset cap)
The search returns only the first 100,000 results per query — pages past that offset return
HTTP 500 (an HTML maintenance page, not JSON). A single high-volume modelYearCode (e.g. a Ram
model year code reports ~100k nationwide) therefore cannot be retrieved by one nationwide query.
To capture everything, the fetch partitions by dealer: every vehicle belongs to exactly one
dealer, so the asset queries small comma-joined dealerCodes chunks (DEALER_CHUNK_SIZE, default
10) per model year code and unions them — complete and duplicate-free, with each query far below
the cap. Comma is the only multi-value separator the endpoint honors. The dealer list comes from
the brand's dealer_locator raw asset, so the inventory asset declares two upstreams
(vehicle_data_<brand> for model year codes, dealer_locator_<brand> for dealer codes). With
dealerCodes set, zip/radius are required-but-ignored placeholders.
Required Environment Variables
| Variable | Default | Description |
|---|---|---|
STELLANTIS_INVENTORY_ZIP | US geographic center | Placeholder center ZIP (ignored when dealerCodes is set) |
STELLANTIS_INVENTORY_RADIUS | US nationwide radius | Placeholder radius in miles (ignored when dealerCodes is set) |
STELLANTIS_INVENTORY_DEALER_CHUNK | 10 | Dealers per comma-joined dealerCodes query |
STELLANTIS_INVENTORY_MODEL_WORKERS | 20 | Concurrent request pool size across all (model, chunk, page) requests |
STELLANTIS_INVENTORY_THROTTLE_INTERVAL | 0.20 | Min seconds between requests pool-wide (~5 req/s) |
STELLANTIS_INVENTORY_TIMEOUT | 60.0 | Per-request timeout in seconds (covers connect + read) |
STELLANTIS_INVENTORY_MAX_RETRIES | 3 | Retries per request on transient errors / bot-block pages |
STELLANTIS_INVENTORY_RETRY_BACKOFF | 2.0 | Initial backoff in seconds; doubles each attempt |
STELLANTIS_INVENTORY_MAX_PER_MODEL | (unset) | Cap total records per query (dev/testing) |
Authentication
No credentials required — the endpoint is a public API used by the brand consumer websites.
However, it bot-blocks datacenter IPs (e.g. the production ECS egress) with HTTP 403 while
serving residential IPs normally. Requests therefore go through AkamaiSessionFactory
(ai_core.http): a curl_cffi browser TLS impersonation that seeds ak_bmsc / bm_sv cookies
from the brand homepage and rotates the session on a block before retrying.
Known Data Quality Issues
Incorrect brand field on Jeep vehicles
The Jeep inventory API occasionally returns a small number of records (~7 per affected day) where
the brand field contains a non-Stellantis value such as "Toyota", "Ford", or "Lexus".
Inspection of the affected records confirms these are genuine Jeep vehicles — VINs start with
1C4 (Chrysler/Jeep WMI) and the Stellantis-internal extImage/intImage fields carry
brand=J. The corrupted brand value originates in the Stellantis backend and is returned
verbatim by the API.
Impact: COSY image URL generation requires a valid Stellantis brand. An unknown brand
previously caused a KeyError crash that blocked the transformed asset for ~60 affected
partition dates over the year.
Fix applied: make_cosy_image_urls in ai_stellantis/cosy.py validates the brand against
the set of values accepted by the COSY generator (StellantisBrand Literal type). Records with
an unrecognized brand are written to the output with null image URLs and a warning is logged;
the partition does not fail.
If the upstream data quality improves or a reliable correction rule can be determined from the VIN WMI prefix, this behavior can be revisited.