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; the coverage below reflects what actually returned data.

The active pipeline currently ingests full-coverage markets only; those markets live in defs/<oem>/<market>/raw/defs.yaml and include the components their APIs 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

The partial tiers below are retained as discovery records in defs/<oem>/<market>/raw/defs.yaml.disabled; Dagster ignores them until a future onboarding renames the file to defs.yaml and adds the matching template vars / transformed defs:

TierAvailable API dataDisabled markets
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 this: the dealers-only markets return no OneGraph data in any language. 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
Client-header deny-list

The Akamai edge deny-lists specific (apollographql-client-name, apollographql-client-version) pairs on the inventory endpoint, targeting stale versions of Audi's own frontend client. This is independent of egress IP. Verified deterministic (20/20 requests per variant):

client-nameversionResult
fa-vlp-list-page5.16.0 (ours, was)403
fa-vlp-list-page5.28.4 (live site)200
fa-vlp-list-page5.17.0, 5.20.0, 1.0.0403
fa-vlp-list-page5.18.0, 5.19.0, 5.21.05.28.4, 6.0.0, 0.0.1200
audi-data-platform1.0.0200

This is not a minimum-version rule; it is a discrete deny-list.

Required headers:

HeaderInventoryCarlineStructure
apollographql-client-nameaudi-data-platformaudi-data-platform
apollographql-client-version1.0.01.0.0
content-typeapplication/jsonapplication/json

audi-data-platform/1.0.0 is our own identifier, not a value observed in Audi traffic. It is unrecognised by the edge, which is precisely why it is unaffected by the deny-list above. origin/referer are not required; the endpoint is unauthenticated and both were confirmed to have no effect on the 403.

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, spanning model years 2026 (current) and 2027:

  • 16 carline groups
  • 32 distinct carline ids / 36 carlines
  • 36 distinct modelId.code
  • 75 model_catalog_id values

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).

The carlineStructure(identifier: {country, language}) query returns the whole tree in one request — carline groups, carlines, trimlines, and per-model modelId { code version extensions year }, prices and technicalDataV2.modelAttributes.

StockCarSearch (node c)

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

stockCarSearch(stockIdentifier:, searchParameter:) returns resultNumber plus results.cars[].stockCar. stockIdentifier takes a marketIdentifier (brand, country, language) and a stockCarsType; searchParameter takes paging, sort and criteria. The stockCar fragment carries the vehicle (vin, avpCode, commissionNumber, weblink), model, carline, code, colorInfo, dealer, engineInfo, features, carPrices, dynamicAttributes, salesInfo and images.

Images. images(groupIds:, imageIds:) returns one entry per id in imageIdsurl, type, mimeType and id { group image }. An empty imageIds returns an empty list whatever groupIds asks for. Under groupIds: ["renderImagesPNG"], urls are PNGs at https://mediaservice.audi.com/media/fast/...png, built for the vehicle's own color and options. Each id added to imageIds grows the per-vehicle render work of every search page, so responses slow with the size of the set.

Known image ids, verified by inspecting the rendered PNGs. The sc4* set is transparent-background, sc3* is a transparent-background wide crop, sc5c01 is a small 350x196 render, and vtp4x3* carries a background scene:

ViewTransparentTransparent wideWith background
Frontsc4c03sc3c03vtp4x3n3c
3/4 frontsc4c01 (also small: sc5c01)vtp4x3n1c
Zoom 3/4 front hoodsc4c02vtp4x3n2c
Zoom 3/4 front bumpersc3c02
Sidesc4c14sc3c14vtp4x3n8c
3/4 rearsc4c12sc3c12vtp4x3n6c
Rearsc4c11sc3c11vtp4x3n5c
Interior, rear-facing angledsc4n05sc3n05vtp4x3i1n
Interior, front-facing near-straightsc4n06sc3n06vtp4x3i2n

groupIds: ["dealerImages"] serves real dealer photos rather than renders (https://vtpimages.audi.com/carimg2/...jpg, resizable via im=Resize query params). Its image ids are stringified integers counting up from "1", with no fixed ceiling; counts can exceed "12". Population varies per vehicle: on a 200-car page verified 2026-08-25, 166 carried at least one dealer photo, with coverage tapering gradually ("1" on 166 cars, "12" on 156, "20" on 107). Groups combine in one request — each imageIds entry resolves against every group in groupIds, and unmatched (group, id) pairs are simply absent from images.

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.

Page-size ceiling = 200. A limit of 250 or more returns a GRAPHQL subgraph error.

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. 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). 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.

carPrices — full price breakdown

Each carPrices entry carries type, label and price.value. The price object also exposes valueAsText/formattedValue (display strings). 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

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

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. Model-level attributes.
stockIdentifier.stockCarsType: "USED"Same endpoint serves used stock with mileage, qualityLabel, preUse { code text } — see stockCar.preUse/qualityLabel below for the individual fields.
stockCar.metaData { statImport }Provenance tag (AGC_USA_JDP / AGC_CAN_JDP = JD Power feed)
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.

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

Frontend brand codes. us=50710 / ca=50720 feed the mediaservice render API (https://mediaservice.audi.com/renderapi/v1/urlsvin) for VIN imagery.

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.

StockCarSearch — subgraph failures arrive as HTTP 200

OmniGraph is a GraphQL federation gateway. When its stockcar-graphql subgraph returns a non-JSON body, the gateway reports that as HTTP 200 with a 245-byte envelope instead of an error status:

{"data":null,"errors":[{"message":"HTTP fetch failed from 'stockcar-graphql': expected value at line 1 column 1","path":[],"extensions":{"code":"SUBREQUEST_HTTP_ERROR","service":"stockcar-graphql","reason":"expected value at line 1 column 1"}}]}

Measured rate on pl (2026-08-20): ~2% of requests, independent of offset and of concurrency (1.5% over 66 sequential single-request polls, 2.0% over 400 pages fetched at 10 workers). Across a full 50-page market sweep that means most runs hit at least one — 6 of 8 observed sweeps did. Identical request params succeed on an immediate retry (8 of 8 recovered on the first retry), so the failure is transient server-side non-determinism, not a rate limit or a bad request.

These responses also carry cache-control: no-store, where a good response carries public, max-age=3600, s-maxage=3600. The advertised TTL is not honored by anything in the request path — no age header is ever returned and resultNumber drifts between calls seconds apart.

StockCarSearch — per-field errors arrive beside a complete page

An errors list does not by itself mean the response is unusable. The gateway also reports a missing per-vehicle field as a VTP_API_ERROR entry alongside a full page of cars:

{"message":"VTP API system did not deliver a required data field.",
"locations":[{"line":1,"column":1053}],
"path":["stockCarSearch","results","cars",87,"stockCar","model","id","version"],
"extensions":{"code":"VTP_API_ERROR","subCode":2001,"service":"stockcar-graphql",
"id":"b55becda-ced7-4a2b-bf30-b22955e05859",
"exception":{"message":"Exception details removed. Please use the error extension field 'id' to retrieve exception details from the StockCar subgraph log."}}}

The field named by path is non-null in the schema, so the null propagates to the nearest nullable parent — for the path above, the car's entire model block, taking model.id.code, .year, .extensions and model.name with it. Everything else on the page survives: resultNumber is present, all 100 entries are there, and the affected car's own stockCar is non-null with its remaining 21 fields intact.

The gap is fixed per vehicle, not transient.

Rate varies by market, measured 2026-08-21 over 8 requests each across offsets 0-300: es/es 6 of 8 pages, kr/ko 4 of 8, fr/fr 2 of 8, and none on pl/pl, us/en, jp/ja or au/en. A shorter 6-request pass over de/de, gb/en, it/it and ca/en saw none.

StockCarSearch — omitting the named field returns the rest

The field an error names is missing only because the query asked for it. Re-requesting the same window with that field left out of the selection returns the rest of the subtree, and no error at all (measured 2026-08-21):

windowfull querynamed field omitted
fr/fr offset 3001 error, car 87's model nullno errors; model.name, id.code and id.year present, id.extensions still null
au/en offset 100data: null — no page at allno errors; 100 cars, resultNumber 3024

au/en offset 100 fails on every attempt with the full query, over one vehicle's features[].text, at limit 100 and 50 alike — omitting the field is the only way that window reads. The same offsets read cleanly at limit: 1 with the full query, so a lost window is not reducible to a lost 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

dealersByMarket(market: $market) returns dealers. 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), where the site itself is addressed by ISO alpha-2 (e.g. us). One request per market returns all of that market's dealers in a single call — 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; model IDs come from CarlineStructure.

The response names no model: it echoes back neither the requested model id nor any model code or year of its own.

Response structure: 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).