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. The result is 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_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.
Test fixtures
projects/ai_stellantis/tests/data/us/inventory_sample.json is a live Jeep search page for
CUJ202610, trimmed to three vehicles spread across the dealers in the locator fixture. Refresh
with uv run python tests/capture.py; capturing it needs a residential IP, since the same
bot-block applies.
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.
COSY image URL generation requires a valid Stellantis brand. 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.
Co-occurring Customer-Preferred Package codes on Wranglers
A vehicle's options string sometimes lists two Customer-Preferred Package codes that cannot
both be installed: on Wrangler trims (model_code starting JLJL or JLJS) the
automatic-transmission CPP (22* / 24*) appears alongside the manual-transmission CPP of the
same trim level (23*). Only one CPP is ever installed, so the manual code is spurious.
Impact: feature_refs is built from options, and the public source has priority 1 for
feature_refs in consolidated inventory. Both codes therefore resolve to feature_ids, and
every downstream consumer (take rates, vehicle attributes, ordering) sees a manual-transmission
package on an automatic vehicle.
StellantisInventoryTransformedComponent
(ai_stellantis/components/transformed.py) strips the superseded code from feature_refs in
the transformed tier. Rules are (model_pattern, if_present, drop) triples declared once in
the feature_co_occurrence_removals template var; add a rule there when a new pair is found.
Rules match on the vehicle's own model_code, and every trigger is evaluated against the
incoming list, so the rules apply simultaneously.
All three inventory feeds are configured, not just the public one. inventory_api_inventory
builds feature_refs from options; inventory_from_dealerconnect_bq_active and ..._sold
build it the same way from poc_option_codes. Consolidated merges the three by priority
(public 1, dc_active 2, dc_sold 3), so a feed left unconfigured would reintroduce the pair for
any VIN the higher-priority feeds do not carry. In-transit and in-production units never
appear in the public scrape at all, and sold history rows outlive it.
Existing partitions are not corrected. The removal is built into the transformed Iceberg
write, so partitions materialized before it shipped still carry both codes. Consolidated scans a
trailing history_days window (default 365) of transformed partitions, so a vehicle whose last
observation predates the fix keeps the spurious code until those partitions are rebuilt.
Reaching the full window requires backfilling transformed → consolidated → enriched.
The record self-identifies the installed package. mackevisionData.ulp names the upper-level
package, and llp the lower-level one. Across 700 live 2026 Jeep + Ram vehicles, ulp was
populated on every record, always appeared in options, and always appeared in the COSY sa=
list carried by extImage / intImage. The superseded partner, by contrast, appeared in sa=
on none of the 108 vehicles that carried more than one package-formatted code.
Membership in that package set is what the raw record does not carry. Code format is not a
substitute — 553 of the 700 vehicles carry two or more codes matching \d\d[A-Z] (52Z, 51G),
and restricting to the trim letter still leaves non-package codes in scope. The set is named in
the features taxonomy instead: equipment-categories options whose description reads
Customer Preferred Package <code> (category 112, "Do Not Display"), covering both the 2T*
lower-level and 2[234]* upper-level forms.