Skip to main content

Audi Public API Sources

Audi exposes its data through three public APIs used by the ai_audi pipeline. No API keys or partner credentials are required; all endpoints are the same backends the www.audiusa.com website (and the other market sites) calls from the browser.

Postman collection — Audi public APIs. All four ingested endpoints are recorded as runnable requests in the live "Public OEM APIs" collection, Audi folder, in the AutoIntel Workspace (reconciled 2026-07-09) — the collection itself is the record of record, not an exported file. The Postman MCP still exposes no folder-creation/delete/transfer tool in this workspace, so the Audi folder mixes the 4 ingested requests with pre-existing non-ingested items (now labeled [LEGACY / UNUSED] in place rather than moved to a subfolder):

  • StockCarSearch — inventory (ingested)
  • CarlineStructure — models (ingested)
  • dealersByMarket — dealers (ingested)
  • CatalogForModel — features (ingested)

Market coverage

All three APIs are market-parameterized and were probed against the full ISO 3166-1 alpha-2 country list on 2026-07-07 (neither GraphQL endpoint allows introspection, so there is no authoritative market list — coverage below reflects what actually returned data). Each market lives in its own defs/<market>/raw/defs.yaml; a market only gets the components its APIs actually serve:

TierAssetsMarkets
Fulldealers, carlines, catalog features, inventoryar, au, az, bh, br, ca, ch, de, es, fr, gb, gr, ie, it, jo, jp, kr, kw, lu, mx, nl, no, om, pl, sa, se, tw, us
No inventorydealers, carlines, catalog featuresbe, dk, fi, in, th, tr
Dealers onlydealersat, bg, cz, hu, my, pt, ro, rs, si, sk

"No inventory" markets return a carline structure but no stockCarSearch results; "dealers only" markets return an empty carlineStructure.carlineGroups (they are not on the OneGraph stack at all). PSS dealersByMarket responds for nearly every country on earth — many with 1–2 import-dealer rows — so dealer counts alone do not indicate a real market. Several more countries (e.g. nz, hk, eg, sg, qa, lb, and most of Central America / the Caribbean) do return carline structures and could be onboarded the same way if ever needed.

The partial tiers are not a language artifact: sweeping the full ISO 639-1 list (the API rejects region variants like de-AT) confirms the dealers-only markets return no OneGraph data in any language, and the no-inventory markets return carlines only in the configured language(s) with no language yielding stock (stockCarsType: USED is equally unknown for them). Every language that has ever returned data is in the country's CLDR territory-language set (or en) — when re-verifying a market, probing those candidates (plus en) is sufficient.

For multi-language markets one site language is ingested: caen, benl, chde, lufr (both languages return identical inventory counts; only display text differs).

API Domains

DomainUsed for
omnigraph.audi.comInventory (StockCarSearch) and model structure (CarlineStructure)
graphql.pss.audi.comDealer locator
web-api.audi.comFeature / option catalog per model

Raw dependency graph

NodeRaw assetUpstreamSource
aaudi/us/raw/onegraph_modelsOmniGraph CarlineStructure
baudi/us/raw/catalog_featuresaWeb-API CatalogForModel per model_id
caudi/us/raw/onegraph_inventoryOmniGraph StockCarSearch
daudi/us/raw/pss_dealersPSS dealersByMarket

OmniGraph GraphQL API

POST https://omnigraph.audi.com/graphql
Endpoint migration — 2026-06-26

The original endpoint https://onegraph.audi.com/graphql began returning 403 on 2026-06-26. The replacement is https://omnigraph.audi.com/graphql. The GraphQL schema and all response shapes are identical; only the hostname changed. See Dagster run f72f5698-d36b-420c-a93a-cee7bb182bba for the first failed production run.

Required headers (copied from live www.audiusa.com browser traffic):

HeaderInventoryCarlineStructure
apollographql-client-namefa-vlp-list-pageaudi-data-platform
apollographql-client-version5.16.01.0.0
content-typeapplication/jsonapplication/json
originhttps://www.audiusa.comhttps://www.audiusa.com
refererhttps://www.audiusa.com/https://www.audiusa.com/

CarlineStructure (node a)

Fetches the full Audi USA model hierarchy — carline groups → carlines → trimlines → models. Drives the catalog_features fan-out (node b).

A single live call (verified 2026-07-09) returns the complete current lineup in one nested tree: 16 carline groups, 32 distinct carline ids / 36 carlines, 36 distinct modelId.code, and 75 model_catalog_id values, spanning model years 2026 (current) and 2027. There is no per-model/-year/-trim fan-out endpoint — the tree carries every model, year, and trim as attributes of this one response. The full current nameplate set is present (Q3/Q5/Q6 e-tron/Q7/Q8, A3/A5/A6/A8, e-tron GT, plus the S/RS variants).

query CarlineStructure($country: String!, $language: String!) {
carlineStructure(identifier: { country: $country, language: $language }) {
carlineGroups { id name carlines { id name vehicleClass trimlines { id name
models { name hidden driveName engineName
modelId { code version extensions year }
prices { financingParameters { modelPrice } }
technicalDataV2 { modelAttributes {
bodyType drive driveTrain engineType engineTechnology fuelType gear gearType
} }
}
} } }
}
}

Variables: {"country": "us", "language": "en"}

Single request; response is a tree of carline groups stored as one raw row.

StockCarSearch (node c)

Fetches all new vehicles nationwide. Paginated with offset; total available from resultNumber on the first page.

query StockCarSearch(
$stockIdentifier: StockIdentifierInput!,
$searchParameter: StockCarSearchParameterInput,
$groupIds: [String!],
$imageIds: [String!]
) {
stockCarSearch(stockIdentifier: $stockIdentifier, searchParameter: $searchParameter) {
resultNumber
results {
sort { id direction }
paging { limit offset }
cars { stockCar {
avpCode businessModelCode commissionNumber doors driveText gearText id
subtitleText titleText vin weblink
carPrices { label price { value } type }
carline { id name }
code { id }
colorInfo {
interiorColor { colorInfo { code text } baseColorInfo { code text } label }
exteriorColor { colorInfo { code text } baseColorInfo { code text } label }
}
dealer { id hid name zip city region position { latitude longitude } }
dynamicAttributes { id value }
engineInfo { fuel { code text } maxPowerKW { unitText value { number formatted } } maxPowerPS { unitText value { number formatted } } }
features { text featureType prNumber { family code class } }
images(groupIds: $groupIds, imageIds: $imageIds) { url type mimeType id { group image } }
model { name salesModelyear id { year code version extensions } }
salesInfo { isBuyOnline saleOrderTypeText orderStatusText physicalOrderStatus availableFromDateInfo { value type } offerDateInfo { value type } }
} }
}
}
}

Variables:

{
"stockIdentifier": {
"marketIdentifier": {"brand": "A", "country": "us", "language": "en"},
"stockCarsType": "NEW"
},
"searchParameter": {
"paging": {"limit": 100, "offset": 0},
"sort": {"id": "DATE_PREDATEEND", "direction": "ASC"},
"criteria": []
},
"groupIds": ["renderImagesPNG"],
"imageIds": []
}

Pagination: offset via searchParameter.paging.offset + .limit. resultNumber from the first response gives the total; termination is a short/empty page. Verified 2026-07-09: paging advances (page 2 ≠ page 1) and terminates naturally on the short final page. Pages are dispatched concurrently (10 workers) via paginated_post_raw_fetch_result, streaming to an IPC-backed LazyFrame. The pipeline sends limit=100.

Page-size ceiling = 200. A limit of 250 or more returns a GRAPHQL subgraph error; limit=100 is safely under the cap.

Coverage: No geo or criteria filters — criteria: [] returns the full US national inventory in one paginated pass. The unfiltered national resultNumber was 52,304 on 2026-07-09.

features.featureType — standard vs. optional equipment

Since OmniGraph disallows introspection, featureType semantics and the fields below were reverse-engineered from the TypeScript source of Audi's Tier-3 dealer VDP apps (fa-vdp-feature-and-specs, fa-vdp-pricing-bar, fa-vdp-pricing-breakdown), which consume this same schema client-side.

featureType distinguishes SERIES = standard equipment from SPECIAL = optional; the dealer frontend renders its standard/optional tabs directly from this flag. It is fetched and retained verbatim in the raw tier, but is not surfaced on the transformed feature_refs entries — those carry only the join keys (pr3_id, parent_package_code), and the consolidation join does not use featureType. Its intended home is a per-(model, feature) standard-vs-optional signal on the consolidated feature entity (planned follow-up), which is where the SERIES/SPECIAL distinction is actually queryable. Kept as a raw string — the full vocabulary is unconfirmed.

manufacturerSpecificItems.cdbCategories — investigated, not ingested

cdbCategories (under manufacturerSpecificItems { ... on StockCarManufacturerAudi }) groups features into a category → subcategory → feature tree with per-feature marketing copy (textInfos { name details benefits }, imageResources). It was evaluated (July 2026) as a signal for detecting "optional but default" trim packages and rejected. Findings from live probes (~3,900 US vehicles):

  • cdb features are a strict subset of stockCar.features (zero violations observed), but membership reflects marketing display content (CDB = content database), not ordering configuration.
  • Trim packages (e.g. WPS) are omitted from cdbCategories universally — for every model, regardless of whether the package is the trim default or a paid second tier. The configuredCar query's feature lists omit them the same way. So cdb absence carries no default-vs-optional signal; only inventory stockCar.features includes package codes at all.
  • ~45% of SERIES features are also absent from cdb — it is a curated display list, not a complete standard-equipment list.
  • US-only: CA and DE return manufacturerSpecificItems with zero cdb feature codes.

Contrast with AccessAudi (private/ordering side), which omits a package code only when the package is the trim default — that asymmetry is the signal that still needs an independent discriminator to reconcile.

carPrices — full price breakdown

The pipeline now persists the full carPrices list (type, label, price.value) instead of only the msrp and final price scalars. The price object also exposes valueAsText/formattedValue (display strings) — schema-valid but not collected. Price-type vocabulary confirmed from the frontend's priority-order constants (not exhaustive — Audi can add types without a schema change):

  • US, new: list, OEMDiscount, dealerMarkup, dealerDocFees, destinationAndHandlingFees, dealerDiscount, dealerPrice, nonConditionalBonus, sale
  • Canada, new: adds levies — freightPDI, acLevy, tireLevy, motoCouncil, adminFee, luxuryTax
  • Used: adds final

Live US sampling (July 2026) observed list, dealerPrice, sale, final, dealerDiscount (negative values), dealerMarkup, and dealerDocFees; label was null on every entry.

Additional fields observed but not currently ingested

Schema-valid on OmniGraph, confirmed either in live www.audiusa.com traffic or in the feature-hub app source; deliberately not collected:

FieldDescription
stockCar.techDataGroups { id label techDataList { id text label } }Full per-car technical specs (displacement, max output/torque, transmission, suspension, brakes, steering, top speed, acceleration, fuel consumption, weights, cargo). Group/item ids differ by market: US uses engine/drivetrain/suspension/brakes/fuelconsumption; international markets use power/driveline/chassis/brake-system/fuel-consumption/performance-data/volumes. Skipped because these are model-level attributes, not per-vehicle.
stockIdentifier.stockCarsType: "USED"Same endpoint serves used stock with mileage, qualityLabel, preUse { code text }. Not ingested — see stockCar.preUse/qualityLabel below for the individual fields.
stockCar.metaData { statImport }Provenance tag (AGC_USA_JDP / AGC_CAN_JDP = JD Power feed). Not ingested.
stockCar.modelInfo.genericModel { code text }Generic model code alongside model
stockCar.modelInfo.modelyearModel year, redundant with model.salesModelyear
stockCar.qualityLabel { label }Quality label (e.g. Certified Pre-Owned)
stockCar.cartypeTextCar type text
stockCar.preUse { code text }Pre-use classification
stockCar.descriptionByDealerFree-text dealer description
stockCar.colorInfo.*.imageUrlSwatch image URLs per color
stockCar.carPrices.disclaimers { id legalEntityKey text }Legal disclaimer text per price line — only observed on the single-vehicle stockCar(...) query, not stockCarSearch
cars.geoDistance { unitText value { formatted number } }Distance from a geo anchor (only populated when geo is passed in searchParameter)
search.criteria[].possibleItems/selectedItemsFacet counts per filter dimension

Single-vehicle query. stockCar(stockCarIdentifier: StockCarIdentifierInput!) also exists and returns the same fragment as stockCarSearch; unnecessary for ingestion since the search query accepts the full fragment for all results in one pass.

Search criteria ids. Confirmed in the wild: stat-import, t_vin (VIN filter — useful for targeted spot-check probes). The pipeline always sends criteria: [].

Frontend brand codes. us=50710 / ca=50720 feed the mediaservice render API (https://mediaservice.audi.com/renderapi/v1/urlsvin) for VIN imagery. Our pipeline already receives image URLs via images(groupIds:["renderImagesPNG"]), so this is unused.

Known data quality issues

dealer_mat_primary_code — same VIN listed under two dealers simultaneously during vehicle transit

Observed: 2026-06-30, e.g. VIN WAUF2BF21RN008391 at USA02F21 (Audi Ann Arbor) and USA03C10 (Audi North Shore).

The StockCarSearch API returns two records for the same VIN when a vehicle is in transit between dealers. One record represents the vehicle as allocated and priced at the receiving dealer (vehicle_order_status: "Dealer Stock", non-null msrp); the other is an open allocation at the originating dealer (sale_order_type: "SHIP - Deliverable Inventory Order", null pricing). Both records are genuine concurrent line items in Audi's order management system — neither is stale or erroneous.

The true current dealer location can be determined by following the weblink field — the URL resolves to the dealer's own inventory page for that VIN, which reflects where the vehicle actually is. No scalar field in the API response reliably identifies the authoritative record without resolving the URL.

The pipeline currently uses dealer_mat_primary_code: min as a secondary tiebreak (after date_offer: max) to produce stable output when date_offer does not discriminate. This tiebreak is deterministic but not semantically meaningful — it picks the alphabetically lowest dealer code, not necessarily the dealer currently holding the vehicle.

PSS GraphQL API — Dealer Locator (node d)

POST https://graphql.pss.audi.com/

Authentication — dynamic client ID

The PSS API requires a clientid header. The value is not static — it is fetched at runtime from the Audi Market Context Service before every dealer request:

GET https://oneaudi-falcon-market-context-service.prod.renderer.one.audi/api/market-context
?path=/content/dam/country/us/configurations/config---market-context
&aemEnvironmentId=p119811-e1162341
&aemEnvironmentService=publish

Response: {"clientId": "<value>", ...}. The clientId field is passed as the clientid request header to the PSS endpoint.

Dealers query

query dealersByMarket($market: Market!) {
dealersByMarket(market: $market) {
dealers { ...FragmentDealerFields }
}
}

Key fields returned: dealerId, matPrimaryCode, kvpsId, name, address, houseNumber, street, city, region, zipCode, latitude, longitude, phone, fax, services, additionalData (display name, location image, additional URL), openingHours (per-department day schedules).

A single A-USA call returns all 315 US dealers (verified 2026-07-09), each with a real, in-range non-zero latitude/longitude. Two dealer identifiers are returned: matPrimaryCode (e.g. USA01A23) and dealerId (e.g. USAA01A17, carrying an extra brand letter). The value that matches the dealer code carried on inventory records (stockCar.dealer.id) is matPrimaryCode, not dealerId.

Market coverage: The market variable is A-<ISO alpha-3>A is the Audi brand and <ISO alpha-3> the market's 3-letter country code (e.g. A-USA). Our market identifiers are ISO alpha-2 (e.g. us), upconverted with a static map (ai_audi.sources.iso_country). One request per market returns all of that market's dealers in a single call. Each ingested market is a separate defs/<market>/ tree — see Market coverage.

Audi Web-API — Feature Catalog (node b)

GET https://web-api.audi.com/vsapi/v1/us/en/CatalogForModel?model={model_id}

No authentication. One request per model ID (e.g. A31SB_2024). Model IDs are derived from the upstream onegraph_models asset (CarlineStructure).

Response shape: featuresData containing named category lists — accessories, bodyColors, extColors, groups, interiorTiles, roofColors, specialGroups, stealthItems — each holding equipment families and individual equipmentList items with id (PR3 code), name, price, type, mbvId (PR7), renderCode, benefits, media, attributes, and optional content (package sub-items).

Retry: 5 attempts with a 15-second pause between rounds. Fetches are sequential per model; failures up to 20 models are logged and skipped rather than hard-failing the run.