BMW CenterNet CRM Source
The centernet source fetches per-dealer CRM-vendor metadata from BMW's
CenterNet WCF service. It is specific to the us market of projects/ai_bmw
and feeds the dealers entity alongside dealer_locator (see
Dealer Locator Source).
Endpoint
GET https://aws-p-app1.bmwcenternet.com/center_services/api/CrmVendorApi?access_key=<KEY>&line_make=BMW
Private API — auth is a static access_key query parameter, no OAuth, no
rotation. One request returns the full BMW CRM-vendor roster; there is no
pagination.
Content negotiation
CenterNet is a WCF service that serves XML to a browser-like Accept header.
The client pins Accept: application/json explicitly to get JSON back.
Response shape
A JSON array, one object per dealer outlet:
| Field | Type | Notes |
|---|---|---|
center_code | string | 5-char dealer id + 2-char location id concatenated (e.g. "6577501" → dealer 65775 / location 01). Split into dealer_code + location_id so the entity joins against BmwUsaDealerEntity. |
crm_tool | string | |
nextgen_crm | "Y" / "N" | Coerced to bool. |
data_sharing | string | |
marketing_optin | "Y" / "N" | Coerced to bool. |
date_updated | MM/DD/YYYY or null | Parsed to a date; an unparseable value is coerced to null rather than raising. |
Assets
| Tier | Asset key | Notes |
|---|---|---|
| Raw | bmw/us/raw/centernet_crm | source=centernet, resource=crm. |
| Transformed | bmw/us/transformed/centernet_crm_dealers | Keyed on center_code. |
Security — access key redaction
The access_key is sent on the wire but must never be persisted. It is added
only to the live request's query params, never to the params dict passed
through to the raw-row writer — the persisted raw row's _request_url /
_request_params carry only line_make, never the key. See
ai_bmw/sources/centernet.py::fetch_crm_raw.
Secret
| Secrets Manager name | dagster/bmw/crm-vendor-api-key |
| Declared in | deployments/aws/terraform/solutions/secrets/secrets.tf (aws_secretsmanager_secret.bmw_crm_vendor_api_key) — shell only; the value is filled manually after the secrets solution applies |
| Value source | Copied manually from GCP Secret Manager crm-vendor-api-key in project bmw-prod-309117 |
| ECS env var | BMW_CRM_VENDOR_API_KEY, resolved from the secret via BMW_CRM_VENDOR_API_KEY_SECRET_ID (set in projects/ai_bmw/container_context.yaml) |
| Local development | export BMW_CRM_VENDOR_API_KEY=... directly — no secret-manager lookup locally |
Backfill
Partitions from 2025-07-16 onward materialize live. Partitions before that
are backfilled from the legacy BQ table via reshape functions in
ai_bmw.backfill, with asset-backfill defs under defs/us/. The legacy
table's history is weekly from July 2024 through December 2025, then daily —
a partition without a legacy snapshot stays unmaterialized.
Backfilled partitions lack fields the legacy table never stored:
nextgen_crm, data_sharing, marketing_optin, and date_updated are all
null on any pre-2025-07-16 partition.
Cadence
Daily at 10:00 UTC — matches the bmwusa private inventory cadence.