Mazda Public API Sources
All Mazda US data comes from first-party endpoints on https://www.mazdausa.com.
There is no authentication, no API key, and no token on any endpoint — a
desktop User-Agent is sufficient. All four entities reproduce headless via
curl --compressed. Akamai Bot Manager is present (_abck, bm_sz, ak_bmsc
cookies; periodic sensor beacons) but did not block clean curl GET/POST during
exploration. If a 403 appears later, the fix is ai_core.http.browser_session
TLS impersonation seeded at https://www.mazdausa.com/.
Verified contract. The facts below are the resolved, probe-verified contract from
discovery-contract.md(all hard gates PASS or user-approved OVERRIDE). The two contract decisions an implementer must not deviate from: inventory uses a single oversized fetch per dealer-set, neverResultsStartpaging (see Inventory pagination); the inventory→models FK must be canonicalized (+↔space) before matching (see Cross-source join keys).MODELS and FEATURES both derive from the configurator (
/api/bp): MODELS is one row per trim (keyedtrim_code), FEATURES is one row per available option per trim (keyedfeature_code, trim_code). The/api/bp/mscatalog is a raw-only enumerator (no transformed tier) that sources the model-code universe.
Endpoints
Ingested
| Source | Entity | Method | URL | Shipped raw asset |
|---|---|---|---|---|
| Build & Price model catalog | models (enumerator) | GET | https://www.mazdausa.com/api/bp/ms | mazda/us/raw/build_price_models |
| Build & Price trim series | trims (raw-only driver) | GET | https://www.mazdausa.com/api/bp/ts?m={modelCode} | mazda/us/raw/build_price_trims |
| Build & Price configurator | configurator | GET | https://www.mazdausa.com/api/bp?m={modelCode}&t={trimCode} | mazda/us/raw/build_price_configurator |
| Inventory search | inventory | POST | https://www.mazdausa.com/api/inventorysearch | mazda/us/raw/inventory_search_inventory |
| Dealer locator | dealers | GET | https://www.mazdausa.com/handlers/dealer.ajax?p={page} (no zip = national) | mazda/us/raw/dealer_locator_dealers |
| Incentives (raw-only) | incentives | GET | https://www.mazdausa.com/api/incentives/{zip} | mazda/us/raw/incentives_incentives |
The Build & Price assets form a raw chain: build_price_models (model-code
enumerator) → build_price_trims (one /api/bp/ts per model, resolving each model's
trim t) → build_price_configurator (one /api/bp per resolved (model, trim)).
The configurator raw asset is the single source of two transformed entities —
MODELS (one row per trim) and FEATURES (one row per option per trim). dealers,
models, features, and inventory each have a transformed + consolidated table
(mazda/us/transformed/{dealer_locator_dealers,build_price_models,build_price_features,inventory_search_inventory}
→ mazda/us/consolidated/{dealers,models,features,inventory}). build_price_models,
build_price_trims, and incentives are raw-only (no transformed/consolidated
table): the first two are the configurator's enumerator/driver chain; incentives is
regional offer data.
A model whose /api/bp/ts returns an empty {"response":{}} (e.g. the US MX-5
soft-top 26MX5, broken upstream) is stored verbatim in build_price_trims but
yields no (model, trim) pair, so the configurator simply doesn't fetch it — a
successful empty response, not a failure.
Supporting (non-entity) endpoints
| Endpoint | Method | URL | What it provides |
|---|---|---|---|
| Vehicle count for zip | GET | /api/buildandprice/vehiclecountforzip?... | {response:{vehicleCount, inventorySearchUrl}} — bridges configurator → inventory; the returned inventorySearchUrl carries the dlrIds, Carline, ModelCode params the results page replays into /api/inventorysearch. Used to derive the dealer-id set for a zip. |
| Zip validation | GET | /handlers/zip.ajax?zip={zip} | {message, success} — pre-flight only. |
| Dealer accolades | GET | /handlers/DealerAccolade.ajax?onlyshowfilteraccolades=true | Dealer-program code reference list. |
| Payment estimator | GET | /api/paymentestimator?... | Finance estimator; returns 400 without a valid dealerId. Not needed for the four entities. |
Build & Price model catalog — models (raw-only enumerator)
GET https://www.mazdausa.com/api/bp/ms
A single unfiltered call returns the complete current model lineup. This is the
model + year enumerator — no separate year endpoint exists. The model codes
live at response.categories[].modelItemContainers[].newModel.modelCode (12 codes
across 3 body-style categories, verified live); the flat response.models[] array
does not carry a clean modelCode field, so enumerate from the categories[]
path. Read the model set live every run — do not hardcode codes.
Raw-only. This asset has no transformed tier; it exists solely to source the model-code universe for the configurator and inventory fetches. The MODELS entity is extracted from the configurator (next-but-one section), not from this catalog.
Required headers
| Header | Value |
|---|---|
User-Agent | desktop UA |
Accept | application/json |
Response shape
Records live at response.categories[].modelItemContainers[].newModel (grouped by
body-style category); a flat response.models[] array carries the same entries.
{
"response": {
"models": [
{
"modelCode": "26C70",
"year": 2026,
"modelName": "MAZDA CX-70",
"subTitle": "<p>Starting at $...</p>",
"imageUrl": "...",
"cta": {"url": "/shopping-tools/build-and-price#/26C70"}
}
],
"categories": [{"modelItemContainers": [{"newModel": {"modelCode": "26C70"}}]}],
"disclaimers": [],
"redirectUrls": [],
"btoRestrictedTrims": []
}
}
Field consumed (enumerator)
| API field | Use | Notes |
|---|---|---|
newModel.modelCode | model-code enumerator | e.g. 26C70. Leading 26 = model year 2026. Drives the configurator fan-out and (minus the 26 prefix → C70) the inventory Carline filter. |
Other newModel fields (year, modelName, subTitle) are not extracted — the
MODELS entity is built from the configurator's per-trim trims[], not this catalog.
Enumeration captured (MY2026, 12 model codes)
26C70 CX-70, 26C7P CX-70 PHEV, 26C90 CX-90, 26C9P CX-90 PHEV,
26C30 CX-30, 26CX5 CX-5, 26C50 CX-50, 2650H CX-50 HYBRID,
26M3H MAZDA3 HATCHBACK, 26M3S MAZDA3 SEDAN, 26MXR MX-5 MIATA RF,
26MX5 MX-5 MIATA.
Current-year-only catalog (verified).
/api/bp/mspublishes one model year at a time (newModel.year=2026live). Prior-year codes (e.g.25C70) return HTTP 200 with an empty/null ~15-byte body on both/api/bp/ts?m=25C70and/api/bp?m=25C70&t=...— there is no historical-year fan-out. Because theyearfield is read live, the pipeline auto-tracks whatever model year Mazda publishes; no year is hardcoded.
Build & Price trim series — trims (raw-only driver)
GET https://www.mazdausa.com/api/bp/ts?m={modelCode}
The trim enumerator: response.trims[].code gives every trim code for the model.
Shipped as the raw-only asset build_price_trims (upstream build_price_models, one
call per model) — it resolves the valid t the configurator (/api/bp) requires,
which 404s without one. It is lighter than /api/bp (marketing spec copy in
accordionHeaders[] HTML, no machine-readable per-trim prices or FK), so MODELS and
FEATURES are extracted from the configurator, not from this response. A model whose
page is broken upstream returns {"response":{}} (no trims); it is stored verbatim
and simply yields no (model, trim) pair for the configurator.
Query parameters
| Param | Value | Notes |
|---|---|---|
m | modelCode | e.g. 26C70 |
Field mapping
| API field | Canonical field | Notes |
|---|---|---|
trims[].code | trim_code | e.g. 26C70PF |
trims[].title | trim_name | e.g. 3.3 Turbo Preferred |
trims[].startingPrice | starting price | HTML (parse). |
Trim-code enumeration for 26C70: 26C70PF, 26C70PR, 26C70PP, 26C70SPR,
26C70SPP.
Build & Price configurator — configurator (sources MODELS + FEATURES)
GET https://www.mazdausa.com/api/bp?m={modelCode}&t={trimCode}
The full Build & Price configurator payload — the richest source, and the single
origin of both MODELS and FEATURES. The t param picks which trim screen loads,
but one response carries everything for the model regardless of t:
response.trims[]— every trim, each withcode,inventorySearchModelCode(the inventory FK), drivetrain/engine/fuel/transmission codes, structuredbasePrice, andstandardFeatures. → MODELS (one row per trim).response.optionTrees[]— one tree per trim; walking a trim's tree yields theexteriorColor/interiorColor/accessorycodes that trim makes available. Option detail (title, price, image) is joined from the model-level catalogsexterior.exteriorColors.options,interior.interiorColors.options, andpackagesAccessories.accessories. → FEATURES (one row per option per trim).
Query parameters
| Param | Value | Notes |
|---|---|---|
m | modelCode | e.g. 26C70 |
t | trimCode | e.g. 26C70PP — selects the loaded trim screen |
Response shape (relevant fields)
{
"response": {
"year": 2026,
"carlineCode": "C70",
"trims": [
{
"code": "26C70PF",
"title": "...",
"inventorySearchModelCode": "C70++PF+XA++",
"trimConfigurationCode": "C70PFXA",
"drivetrainCode": "AWD",
"engineCode": "P",
"fuelCode": "G",
"transmissionCode": "Automatic",
"basePrice": {"amount": 42750, "destinationFee": 1530, "destinationFeeAlaska": 1575},
"standardFeatures": ["..."]
}
],
"exterior": {"exteriorColors": {"options": [{"title": "...", "code": "51K", "price": 595, "iconUrl": "https://...jpg"}]}},
"interior": {"interiorColors": {"options": [{"title": "...", "code": "L_KJ2", "price": 0, "iconUrl": "https://...png"}]}},
"packagesAccessories": {
"packages": [{"title": "...", "name": "accessory", "code": "1PT", "price": 900, "categories": []}],
"accessories": [{"title": "...", "code": "WLK", "price": 75, "iconUrl": null, "asset": {"assetUrl": "/siteassets/...jpg"}}]
},
"optionTrees": [
{"name": "trim", "code": "26C70PF", "availableOptions": [
{"name": "exteriorColor", "code": "51K", "availableOptions": [
{"name": "interiorColor", "code": "L_KJ2"}]},
{"name": "accessory", "code": "WLK"}]}
]
}
}
Field mapping — MODELS (one row per trims[])
| API field | Canonical field | Notes |
|---|---|---|
trims[].code | trim_code | key, e.g. 26C70PF (model + year + trim). |
response.carlineCode | carline | e.g. C70. |
last-2(response.year) + carlineCode | model_code | e.g. 26C70. |
trims[].inventorySearchModelCode | inventory_search_code | e.g. C70++PF+XA++ (canonicalized) — trim-level FK to inventory. |
response.vehicleTitle | model_name | e.g. MAZDA CX-70. |
trims[].title | trim_name | e.g. 3.3 Turbo Preferred. |
trims[].basePrice.amount / .destinationFee | base_price / destination_fee | integer USD. |
trims[].{drivetrain,engine,fuel,transmission}Code | *_code | trim powertrain codes. |
trims[].standardFeatures | standard_features | list of strings. |
Field mapping — FEATURES (one row per available option per trim)
| API field | Canonical field | Notes |
|---|---|---|
option code | feature_code | key part, e.g. 51K / L_KJ2 / WLK. |
optionTrees[].code | trim_code | key part + FK to models; the trim whose option tree offers the option. |
| option group | category | exterior / interior / accessory. |
option title | description | e.g. Soul Red Crystal Metallic. |
option price | price | integer USD; 0 = no charge. |
option iconUrl or asset.assetUrl | image_url | colors use iconUrl (absolute); accessories use asset.assetUrl (relative → absolutized). |
Per-trim availability comes from optionTrees (one tree per trim); option detail is
joined from the model-level catalogs. hexValue is not available from /api/bp
(it exists only on /api/bp/ts color swatches) — FEATURES carries no hex value.
Package pricing note
Mazda's configurator does expose priced option packages:
packagesAccessories.packages[] and .accessories[] carry a name:"accessory"
tag with an integer USD price (e.g. 900, 0). Unlike Hyundai (where packages
are only no-charge seating choices), Mazda packages are genuine priced add-ons.
Color premiums and accessory prices are also integer USD on the option objects.
Inventory search — inventory
POST https://www.mazdausa.com/api/inventorysearch
VIN-level new-vehicle search. Form-urlencoded POST (not JSON). Dealer-scoped:
Vehicle[DealerId][] is effectively required — the search returns "vehicles at
these dealers". The dealer-id set for a zip comes from dealer.ajax or the
vehiclecountforzip inventorySearchUrl.
Required headers
| Header | Value |
|---|---|
User-Agent | desktop UA |
Content-Type | application/x-www-form-urlencoded |
X-Requested-With | XMLHttpRequest |
Accept | application/json |
Request body (verified minimal working form)
ResultsPageSize=20&ResultsStart=1 # ResultsPageSize must be >= TotalVehicles; ResultsStart stays 1 (see pagination below)
&Vehicle[DealerId][]=42031&Vehicle[DealerId][]=42231&Vehicle[DealerId][]=42166
&Vehicle[Type][]=n&Vehicle[cond][]=n
&Vehicle[Carline][]=C70 # OR Vehicle[ModelCode][]=C70++PP+XA++ for one trim
&GetNearMatch=true
Vehicle[DealerId][]repeats once per dealer id.Vehicle[Carline][]=C70returns all trims of a carline (17 in test); swap toVehicle[ModelCode][]with the+-encodedinventorySearchModelCode(C70++PP+XA++) for a single trim configuration (2 in test).- The site also sends
ResultsSortAttribute,ResultsSortOrder,resultsSortParameter[n][...],sortVal,sortTitle,IsIntransitDisplay,IsEVMarket— all optional for a basic query.
Response shape (relevant fields)
{
"response": {
"TotalVehicles": 17,
"Vehicles": [
{
"Vin": "JM3KJEHD8T1208787",
"Price": 51375,
"BaseMsrp": 52375,
"DestinationFee": 1530,
"Mileage": 0,
"Status": "...",
"Type": "n",
"DealerId": 42166,
"DealerName": "CULVER CITY MAZDA",
"Carline": "C70",
"Colors": {"ExteriorCode": "48T", "InteriorCode": "L_KJ2", "ExteriorDescription": "..."},
"Model": {
"Code": "C70 PP XA ",
"InventorySearchCode": "C70 PP XA ",
"Msc": "KMRANAA",
"TrimName": "...",
"Year": 2026,
"Engine": {"Horsepower": 0, "FuelType": "..."},
"Transmission": {"Speed": 0, "Type": "..."},
"Options": [{"Code": "...", "Name": "...", "Price": 0}],
"Packages": [{"Code": "...", "Name": "...", "Price": 0}]
}
}
],
"NearVehicles": []
}
}
Field mapping
| API field | Canonical field | Notes |
|---|---|---|
Vehicles[].Vin | vin | Primary key (17-char). |
Vehicles[].DealerId | dealer_code | FK to dealers (integer dealer code). |
Vehicles[].Carline | carline | e.g. C70. Informational (model-level); not a resolved FK — models is trim-grained. |
Vehicles[].Model.InventorySearchCode | inventory_search_code | e.g. C70 PP XA — trim-level FK to models. Same value as the configurator's inventorySearchModelCode in a different encoding (spaces here, + there). The join must canonicalize (+→space, collapse whitespace runs, strip) on both sides before matching — see Cross-source join keys. |
Vehicles[].Price | price | non-zero USD. |
Vehicles[].BaseMsrp | base_msrp | non-zero USD. |
Vehicles[].Colors.ExteriorCode / .InteriorCode | feature_refs[].feature_code | per-vehicle color codes; the list FK to features. Match configurator option codes and resolve within the vehicle's trim. (Factory Model.Options/Packages codes are excluded — not catalog features.) |
Pagination and coverage (verified)
ResultsStartpaging is lossy — DO NOT page. Use a single oversized fetch. (User-approved OVERRIDEpagination:inventory, 2026-06-11.)ResultsStartadvances but never assembles the complete set: withResultsPageSize=5pages 1 and 2 overlap 4 of 5 VINs and the full walk yields only 11/17 unique; withResultsPageSize=12the walk yields 12/17 (page 2 is all duplicates of page 1). This is silent truncation.Verified contract — count, then one unpaged fetch per dealer-set:
- Issue a small probe call to read
response.TotalVehiclesfor the dealer-set.- Issue one request with
ResultsStart=1andResultsPageSize >= TotalVehicles. This returns the complete, distinct set (verifiedPageSize=20→17/17, andPageSize=500/1000→113/113 on a 10-dealer NY set with no size cap hit).- If the count grew between probe and fetch, refetch with a larger
ResultsPageSize.Never iterate
ResultsStart. De-dupe defensively onVinregardless. Because inventory is dealer-scoped, per-dealer-set counts are small and known up front, so count-then-single-fetch is sound at scale.
Inventory is dealer-scoped — there is no global "all inventory" call. The inventory fan-out is driven by dealer enumeration: national dealer list (no-zip enumerator) → dealer ids (chunked) → per-(carline, dealer-chunk) count-then-oversized fetch.
Dealer locator — dealers
GET https://www.mazdausa.com/handlers/dealer.ajax?p={page}
The single dealer source. It backs the Build & Price nearest-dealer preview, the inventory dealer set, and the Find-a-Dealer page. Coordinates are populated (no all-zero failure). No richer dealer endpoint exists.
Query parameters
| Param | Value | Notes |
|---|---|---|
p | 1-based page | 20 dealers/page |
zip | origin zip (optional) | omit for national coverage; if set, scopes + radius-caps results |
maxDistance | radius in miles (optional) | only with zip |
Response shape
{
"body": {
"total": 5,
"results": [
{
"id": 42031,
"name": "...",
"address1": "...",
"city": "...",
"state": "CA",
"zip": "...",
"lat": 34.128,
"long": -118.255,
"dayPhone": "...",
"webUrl": "...",
"inventoryUrl": "...",
"driveDistMi": 5.0,
"marketCd": "...", "districtCd": "...", "regionCd": "...",
"accolades": [],
"alternateLocations": []
}
]
},
"header": {"status": "..."},
"recaptcha": {}
}
Field mapping
| API field | Canonical field | Notes |
|---|---|---|
body.results[].id | dealer_code | integer dealer code, e.g. 42031. |
body.results[].name | name | |
body.results[].address1 | street | |
body.results[].city | city | |
body.results[].state | region | two-letter state code. |
body.results[].zip | zip_code | |
body.results[].lat | latitude | populated (e.g. 34.128). |
body.results[].long | longitude | populated (e.g. -118.255). |
body.results[].dayPhone | phone | |
body.results[].webUrl | website_url |
Coverage
Called with no zip param, dealer.ajax is a national enumerator — paginate
p (20/page) to body.total. Verified live 2026-06-12: 548 dealers, 28 pages,
49 states (matches external ~547). The raw fetch is plain pagination, no zip grid.
A zip param scopes results and radius-caps them (total scales with radius then
plateaus origin-dependently), so it's omitted for full coverage.
Incentives (raw-only) — incentives
GET https://www.mazdausa.com/api/incentives/{zip}
Zip-scoped regional incentives (lease / purchase / CPO / special offers). No auth —
the recaptcha field in the response wrapper gates the lead-submit POST, not this GET
read. A desktop User-Agent + curl --compressed is sufficient.
Raw-tier only. This entity is ingested at the RAW tier only — there is no transformed or consolidated table for incentives. The
carlineCode/modelCodeWithYearFK below is informational (it links to the same keys the models and inventory entities use), not a resolved cross-source identity key.
Path parameters
| Param | Value | Notes |
|---|---|---|
zip | origin zip | e.g. 90071 |
There is also a per-model variant GET /api/incentives/{zip}/{modelCode}/{n} — the
trailing {n} segment is insignificant; zip is the real scope.
Required headers
| Header | Value |
|---|---|
User-Agent | desktop UA |
Accept | application/json |
Response shape
Offers live under body.regionalIncentives:
{
"body": {
"regionalIncentives": {
"leaseOffers": [
{
"carlineCode": "C70",
"modelCode": "26C70",
"modelCodeWithYear": "26C70",
"modelYear": 2026,
"marketingId": "...",
"modelName": "MAZDA CX-70",
"leaseOffers": [{"...": "terms"}],
"specs": {}
}
],
"purchaseOffers": [],
"cpoPurchaseOffers": {},
"specialOffers": {},
"specialOffersWithVehicles": []
}
},
"header": {},
"recaptcha": {}
}
Each offer object carries carlineCode, modelCode, modelCodeWithYear, modelYear,
marketingId, modelName, nested leaseOffers / terms, and specs. Example: zip
90071 → 12 lease + 12 purchase + 33 specialOffersWithVehicles (live capture,
fixture projects/ai_mazda/tests/data/incentives_sample.json).
FK (informational)
| API field | Links to | Notes |
|---|---|---|
carlineCode | inventory Carline / configurator carlineCode | e.g. C70. Informational — raw-tier only, not a resolved identity key. |
modelCodeWithYear | models newModel.modelCode / inventory model code | e.g. 26C70. Informational — raw-tier only. |
Coverage / fan-out
Zip-scoped — zip is a required path segment (/api/incentives 404s), so the raw
dealers asset is an upstream dependency and incentives is queried once per
distinct dealer zip, deduped on marketingId. This pins offer coverage to real
dealer locations. Unlike dealers, incentives has no national no-arg call.
Cross-source join keys (FK)
| FK | Referencing field | Target field | Stable key | Example value |
|---|---|---|---|---|
| inventory → dealers | inventory Vehicles[].DealerId (int) | dealers results[].id (int) | DealerId ≡ dealer id (identical integer type both feeds) | 42166 |
| inventory → models | inventory Vehicles[].Model.InventorySearchCode | models inventory_search_code (← configurator trims[].inventorySearchModelCode) | canonicalized inventory-search code (see rule below); trim-level, unique per trim | C70 PP XA ≡ C70++PP+XA++ |
| features → models | features trim_code (← configurator optionTrees[].code) | models trim_code (← configurator trims[].code) | identical trim_code (both from the same configurator response) | 26C70PP |
| inventory → features (list) | inventory (inventory_search_code, feature_refs[].feature_code) | features (inventory_search_code, feature_code) | trim-scoped option code; one-to-many → feature_ids list | C70 PP XA + 48T |
Canonicalization rule (inventory → models) — required. The inventory
Model.InventorySearchCodeand the configuratorinventorySearchModelCodeare the same value in two encodings: inventory uses spaces (C70 PP XA), the configurator uses+(C70++PP+XA++). The join MUST canonicalize both sides before matching — replace+→space, collapse whitespace runs, strip leading/trailing whitespace — yielding the canonical keyC70 PP XA. This is a trim-level join. Do not match the raw strings; they will never be equal.
carline is no longer a resolved FK: MODELS is trim-grained, so Carline (C70,
model-level) is non-unique against it — the trim-unique inventory_search_code is
the join key instead.
inventory → features is a one-to-many list FK. The inventory transform builds a
feature_refs list from each vehicle's Colors.ExteriorCode / Colors.InteriorCode.
The consolidated tier explodes it and joins each (inventory_search_code, feature_code) against features, collecting the matched feature_ids into a
feature_ids list — these color codes are Build & Price catalog entries keyed to the
vehicle's trim, so they resolve. The vehicle's factory option/package codes
(Model.Options/Packages — AE1 emissions, SA3, 1PP) are a different taxonomy
not in the configurator catalog and are excluded from feature_refs (they would
never resolve).
Data relationships
inventory ──DealerId (int) ───────────────────────────────→ dealers (results[].id)
inventory ──Model.InventorySearchCode (canonicalize +↔ )──→ models (trim inventorySearchModelCode)
inventory ──(InventorySearchCode, feature_refs[].code) ───→ features (inventory_search_code, feature_code) [list]
features ──trim_code ─────────────────────────────────────→ models (trim_code)
The configurator is the single model-side source: MODELS (per trim) carries the
trim-level FK (inventorySearchModelCode) that joins inventory to a specific trim,
plus structured prices; FEATURES (per option per trim) joins back to MODELS on
trim_code. The model catalog (/api/bp/ms) is the raw-only enumerator; the trim
series (/api/bp/ts) resolves a valid t at fetch time. Inventory and dealers are
each single-source.
Coverage strategy
- Dealers (national, no-arg): call
dealer.ajaxwith nozipand pagep(20/page) tobody.total— 548 dealers nationally. No zip grid needed. - Inventory (per-dealer-set): feed the deduped dealer-id set into
/api/inventorysearch(dealer-scoped). For each dealer-set, readTotalVehiclesthen issue one fetch withResultsPageSize >= TotalVehicles— never page viaResultsStart(it silently truncates; see pagination).vehiclecountforzipcan bridge a configured vehicle to the dealer-id set for a zip. - Models / features: one unfiltered
/api/bp/mscall enumerates the current-year model codes (read live — current-year-only, no historical fan-out); fan out per model to/api/bp/ts(resolve a valid first trim) then/api/bp?m=&t=(the configurator), whose one response yields both MODELS (per trim) and FEATURES (per option per trim).
Environment variables
No Mazda-specific environment variables are required beyond the standard platform
variables (ICEBERG_CATALOG_URI, ICEBERG_WAREHOUSE, RAW_STORAGE_URI).
Postman
All endpoints (plus the vehiclecountforzip bridge) are recorded in the Public OEM APIs
collection under Mazda / US:
Public OEM APIs.
Ingested source folders are promoted with their shipped raw asset key:
| Postman folder | Shipped raw asset |
|---|---|
1. Build & Price model catalog (mazda/us/raw/build_price_models) | mazda/us/raw/build_price_models |
2. Build & Price trim series (mazda/us/raw/build_price_trims) | mazda/us/raw/build_price_trims |
3. Build & Price configurator (mazda/us/raw/build_price_configurator) | mazda/us/raw/build_price_configurator |
4. Inventory search (mazda/us/raw/inventory_search_inventory) | mazda/us/raw/inventory_search_inventory |
5. Dealer locator (mazda/us/raw/dealer_locator_dealers) | mazda/us/raw/dealer_locator_dealers |
6. Incentives (raw-only) (mazda/us/raw/incentives_incentives) | mazda/us/raw/incentives_incentives |