Volkswagen US — Public API Source Reference
Postman collection — Volkswagen public APIs. Postman MCP was unavailable during discovery, so the collection (every endpoint below — cache key, MOFA models, OneAPI configurator features, GSL inventory, DCC dealers) is exported for manual import at
postman/volkswagen-us.postman_collection.json. Import under Public OEM APIs / Volkswagen / US.
Overview
The VW US pipeline pulls from four separate public backends that together cover the full raw → transformed → consolidated tier:
| Backend | Purpose | Base URL |
|---|---|---|
| MOFA (Model Overview Feature App) | Current US builder carlines, trims, model years, MSRP | https://v1-548-2.mofa.feature-app.io |
| VW OneAPI | Configurator cache key and full feature catalogue | https://oneapi.volkswagen.com |
| GSL (Group Showroom Layer) | Inventory search (VIN-level, brand-level, paginated) | resolved from en.global-config.json |
| DCC (Dealer Config Center) | Dealer directory (national, single call) | https://v3-81-1.ds-us.dcc.feature-app.io |
All four are unauthenticated from a browser perspective — no OAuth or user
sessions required. Authentication is via API key query params or x-api-key
headers embedded in the requests.
Authentication
MOFA (oneapiKey query param)
The current VW US model/trim enumerator is the MOFA model-overview BFF used by
https://www.vw.com/en/builder.html. Build its request from
https://www.vw.com/en.global-config.json:
oneapiKey=1AvAgztRZs6LdqjOULN1u7WTskbc5AnSserviceConfigEndpointTokenis the JSON value atspaAsyncConfig.serviceConfigEndpointdataVersionismodelCacheBuster-serviceConfigsVersion-modelStructureVersion-mofaCarDataVersion
The old US OneAPI /viso/catalogue/* tenant still returns HTTP 200, but the US
product data is stale. Do not use it as the current model source.
OneAPI (x-api-key header)
Two distinct API keys are used depending on the endpoint group:
| Key | Used for |
|---|---|
1AvAgztRZs6LdqjOULN1u7WTskbc5AnS | Cache key (/cks/*) |
Ox5AegtsLDecFmKHxYdf599VKBCpHsX4 | Configurator features (/vcso/*) |
Pass as x-api-key: <value> request header. No rotation mechanism has been
observed — these are static embedded keys.
GSL and DCC (oneapiKey / lufthansaApiKey query params)
| Param | Value | API |
|---|---|---|
oneapiKey | nOqkwPxxu8ViK9aaHvTkglzVZAlX4yIx | GSL inventory |
lufthansaApiKey | h0CQWvPYSBvp5KYXUpRU4FpZrnl0tZx1 | DCC dealers |
These are passed as URL query parameters. No Authorization header is needed.
Resolve the versioned feature-app base URLs and API keys from
spaAsyncConfig.featureHubModel.featureAppsForFeatureAppService in
https://www.vw.com/en.global-config.json; do not pin feature-app subdomains in code.
Cache Key Refresh
The cache key must be refreshed at the start of every pipeline run.
The cache key is a SHA1 hash of the current catalog publish state. All
OneAPI /vcso/* calls require a valid cacheKey query param — stale keys
return empty or error responses.
Fetch the current key before any other OneAPI calls:
GET https://oneapi.volkswagen.com/cks/cachekey/ihdcc-vw-us-en
x-api-key: 1AvAgztRZs6LdqjOULN1u7WTskbc5AnS
Response: JSON with a key value, e.g.
{"key":"89b5b19699de0fc7981a6d270c6bd4795202b0b7"}.
dataVersion
GSL inventory requests also require a dataVersion query parameter. Use
spaAsyncConfig.dataVersions.serviceConfigsVersion from en.global-config.json. Do
not hardcode this value; it changes when the public site publishes new service config.
Endpoints
| Entity | Method | URL Pattern | Auth |
|---|---|---|---|
| Cache key | GET | /cks/cachekey/ihdcc-vw-us-en | x-api-key (catalog key) |
| Current model overview | GET | https://v1-548-2.mofa.feature-app.io/bff/model-overview?dataVersion=&serviceConfigEndpointToken=&... | oneapiKey query param |
| Features | GET | /vcso/configStart?modelKey=&modelYear=&carlineKey=&salesgroupKey=&trimName=&tenant=&cacheKey= | x-api-key (configurator key) |
| Inventory | GET | <gsl_base_url>/bff/car/search?t_cartype=N&page=&... | oneapiKey query param |
| Dealers | GET | https://v3-81-1.ds-us.dcc.feature-app.io/bff-search/dealers?lufthansaApiKey=&serviceConfigEndpoint=&query= | lufthansaApiKey query param |
Endpoint Details
Cache Key (/cks/cachekey/ihdcc-vw-us-en)
- Single call, no params beyond the header.
- Returns a JSON object with a
keyfield. - Must be stored and passed to all subsequent OneAPI requests in the same run.
- No pagination.
Current Model Overview (/bff/model-overview)
- Single call returns current US carlines, trims, engine-level model keys, model years, MSRP, and highlight features.
- The response is wrapped as
{payload: {models: [...]}}. - Each trim engine has
key.modelId(e.g.CA33PZ),key.modelYear(currently2026),key.carlineId,key.salesgroupId, andkey.trimId. - No pagination.
- FK join target:
payload.models[].children[].data.engines[].key.modelId←inventory.cars[].salesModelCode.carlineIdis one level higher than the model code and is not precise enough for inventory→models joins — see Cross-Source FK Joins.
Features (/vcso/configStart)
- One call per distinct trim model code.
- Params:
modelKey,carlineKey,salesgroupKey(trim-level, from models response),trimName,modelYear,tenant=ihdcc-vw-us-en,cacheKey. - Use all model identifiers from MOFA model overview, including
modelYear. - Returns
vehicleCatalogue.featuresarray (280 features for Atlas SE CA33PZ MY2026). - Feature fields:
code,name,prices,packages,isExterior,isInterior,isStandard,isSelectable. - FK:
vehicleConfiguration.modelKey(e.g.CA33PZ) matches MOFA trim enginekey.modelId, andvehicleConfiguration.carlineKey(e.g.31691) matches MOFAkey.carlineId. Features reach inventory throughsalesModelCode/model_codeplus feature extension codes or exterior color name bridging. - Previous endpoint
/viso/catalogue/models/{code}/vehicleCatalogue/featureshas been removed. Use/vcso/configStartonly. - No pagination.
Inventory (/bff/car/search)
- One brand-level call per page. Params:
t_cartype=N— new inventory onlysort=PRICE_SALE&sortdirection=ASC— stable sort for paginationpageitems=12page— 1-based page number; iterate tometa.pageMaxcountry=US&language=en&market=passengeroneapiKey,dataVersion,endpoint— resolved fromen.global-config.json
pageitemsis hard-capped at 12 by the API — requests for 100/500 still returnmeta.pageItems=12. Iteratepage(1-based) until a short/empty page orpage >= meta.pageMax.- No model fan-out: omit
t_model. A live filter-ablation probe (2026-06-24) proved the unfiltered brand-level request returns all new VW US inventory:meta.resultNumber=68,672,meta.pageItems=12,meta.pageMax=5,723. Page 2 is disjoint from page 1 (0 overlap →pagehonored); page 5,723 returned exactly68,672 − (5,723 − 1) × 12 = 8cars, confirming paging reaches the reported total with no silent cap. Full-pagination completeness was certified on a low-volume slice (t_model=BQAM): 1,839/1,839 unique VINs across 154 pages, natural end reached. (An earlier 2026-06-17 probe read 68,885 / 5,741; totals drift as stock turns over, confirming a live, non-cached source.) - Response:
{cars: [...], meta: {resultNumber, pageItems, pageMax, page, ...}}. - Key fields on each car:
vin,salesModelCode(FK to models),carline(carlineId, useful context but not the model FK),dealer.key,configurationPrice.
The frontend uses /bff/setup and /bff/criteria/possible to populate filter dropdowns,
but those are not needed for raw inventory collection because the broader search endpoint
already returns the complete brand-level population.
Dealers (/bff-search/dealers)
- Single call returns the full US VW dealer list (626 dealers, live 2026-06-24;
625 on 2026-06-17) — no pagination, no enumeration. There is no
totalfield; coverage islen(dealers). - Params:
lufthansaApiKey,serviceConfigEndpoint(JSON blob, URL-encoded),query(JSON blob, URL-encoded). - The
queryJSON specifiescountryCode=US,type=DEALER, andname=" "(space) to match all dealers. - Response:
{dealers: [...]}. Key fields:id,coordinates([lat, lon]). - FK join:
dealers[].id(e.g.03002) is joined from inventory viacars[].dealer.keywith theUSAprefix stripped:dealer_id = cars[].dealer.key.lstrip("USA"). Confirmed:USA25152→25152,USA25085→25085,USA07439→07439,USA06457→06457.
Cross-Source FK Joins
| Join | Left field | Right entity | Right field | Transform |
|---|---|---|---|---|
| inventory → dealers | cars[].dealer.key | dealers | dealers[].id | Strip USA prefix from inventory side (USA06457 → 06457) |
| inventory → models | cars[].salesModelCode | models | MOFA engine key.modelId | Direct match when present in current MOFA; stock-only/older codes are backfilled by inventory-derived models |
| inventory → features (extensions) | model.mbv.extension tokens, paired with salesModelCode | features | configurator feature.code, paired with model_code | Convert tokens such as P16 to GP16P16 |
| inventory → features (color) | color.out.value, paired with salesModelCode | features | configurator feature.name, paired with model_code | Exact color-name bridge, e.g. Opal White |
| features → models | vehicleConfiguration.modelKey / carlineKey | models | MOFA engine key.modelId / key.carlineId | Direct match |
FK correction (verified live 2026-06-24).
cars[].salesModelCodeis the precise inventory→models key: it matches MOFAkey.modelIdwhen the stocked model code is present in the current builder. Some stock-only or older codes (BU42RS,BU51RS,DA16UZ) do not appear in MOFA; this is accepted partial model resolution rather than a transformed backfill, because GSL inventory carries too little model detail to create useful model records.cars[].carline/MOFAkey.carlineIdwas rejected as the model FK because it is one level higher in the hierarchy: one carline maps to many model codes.
endpoint / serviceConfigEndpoint JSON Blob
Both GSL and DCC require a structured JSON blob identifying the content environment. This is URL-encoded in actual requests:
{
"endpoint": {
"type": "publish",
"country": "us",
"language": "en",
"content": "onehub_pkw",
"envName": "prod",
"testScenarioId": null
},
"signature": "VehBWLTr2hxx8TJ85NJrpgRXoPfAyNcz2K8KuyXQTNI="
}
Treat this as a static config value per environment. The signature field is
opaque — do not attempt to derive it programmatically.
Subdomain Versioning
Feature-app.io endpoints use versioned subdomains (v1-548-2.mofa, v3-116-1.gsl,
v3-81-1.ds-us.dcc). These versions change with deployments — MOFA went from
v1-544-1 to v1-548-2 in a single week.
Version Lifespan
GSL subdomain versions remain DNS-resolvable for approximately 3–4 months after replacement, then return ENOTFOUND. API keys are stable across 2+ years of observed deployments (confirmed via Internet Archive captures Sep 2024 – Jun 2026).
DCC -us Suffix
The DCC URL has a country-specific subdomain suffix not present in the config JSONs.
Config carries v3-81-1.ds.dcc.feature-app.io; the frontend JS transforms it for
US market:
// dealer-search-standalone-umd.js, module 6603
const COUNTRY_SUFFIX_LIST = ["US"];
// ...
if (countryCode && COUNTRY_SUFFIX_LIST.includes(countryCode)) {
const segment = baseUrl.split(".")[1]; // "ds"
baseUrl = baseUrl.replace(`.${segment}.`, `.${segment}-${countryCode.toLowerCase()}.`);
// ".ds." → ".ds-us."
}
Only "US" is in the suffix list. Other markets (e.g. Canada) use the base domain
without modification. If implementing dynamic URL resolution from config, replicate
this transform for the US DCC endpoint.
Dynamic Resolution
Current en.global-config.json carries feature-app versions, API keys, the service
config endpoint token, and service data versions. Resolve GSL, MOFA, and DCC from
that file at runtime. The only endpoint-specific transform is the DCC US host suffix
described above (.ds. → .ds-us.).
VW Group Siblings
VW Group brands each run separate API stacks:
| Brand | Status |
|---|---|
| Audi | Confirmed separate stack (different OneAPI tenant, different GSL instance) |
| Porsche | Confirmed separate stack |
| Volkswagen | This document |
Do not share API keys, endpoints, or tenant identifiers across brands. The ihdcc-vw-us-en
tenant token is VW-specific.
Pipeline Run Order
1. GET /en.global-config.json → MOFA dataVersion + serviceConfigEndpoint
2. GET MOFA /bff/model-overview → current models/trims/model years
3. GET /cks/cachekey → Victor cacheKey for configStart
4. GET /vcso/configStart (per trim) → features
5. GET /bff/car/search (brand-level, paginated) → inventory
6. GET /bff-search/dealers → dealers (single call, any order)
Steps 5–6 can run after global config is available. Step 4 depends on the MOFA model identifiers and cache key.
Postman Collection
The Postman collection covering all five endpoint groups above is exported at:
docs/content/oems/volkswagen/postman/volkswagen-us.postman_collection.json
Import this into the team's Postman workspace under Public OEM APIs / Volkswagen / US.
The collection uses collection-level variables for all configurable values (cacheKey,
page, GSL base URL, API keys, etc.) so environment switching requires only variable
updates.