Developer Documentation
Request and receive connected-vehicle data directly from our APIs — under the EU Data Act, with owner consent at the core.
What Programmatic Access is
Programmatic Access lets your application request and receive vehicle data — historical, last-known, and real-time — directly from our APIs under the EU Data Act (EUDA). You register an integration once, receive credentials, and then call the data-request APIs to create requests, track their status, and retrieve delivered data.
Three things are true of every integration, and they shape everything else in this guide:
- Access is read-only. The B2B integration realm is a zero-trust, read-only environment. You can request data about a vehicle; you cannot send commands to a vehicle (no door unlock, no engine start). Those capabilities live in a separate fleet realm and are not exposed here.
- The vehicle owner is always in control. Data only flows after the owner has explicitly consented to the specific data you asked for, for the specific purpose you stated. You initiate; the owner approves. There is no path that bypasses owner consent.
- The platform meters and bills automatically. Pricing, payment, and invoicing are enforced by the platform before any backend service runs. Your backend never handles pricing logic — you register a payment method and the platform does the rest.
If you have integrated with OAuth providers or other consent-gated data APIs before, the overall shape will feel familiar. The one concept that is easy to under-estimate — and the one that causes the most integration bugs — is consent as a first-class, owner-controlled lifecycle that is independent of your access tokens. The Consent section is the most important in this guide; read it before you write code.
How a data request works (the mental model)
There are three actors:
| Actor | Who | Role |
|---|---|---|
| You (the integrator) | A B2B organization: insurer, leasing co., energy aggregator, repairer, mobility operator, data intermediary | Initiates data requests on behalf of, or with the permission of, a vehicle owner |
| The vehicle owner (B2C) | The natural person linked to the VIN | Grants, denies, or revokes consent in their own secure portal |
| The platform | Nissan Connected Data Platform (NiCoDaP), the EUDA data-access platform on top of the connected-vehicle infrastructure | Validates, gates, meters, bills, and delivers |
Every request follows the same arc, regardless of integration model or data family:
The request does not return data synchronously at creation time. Creating a request returns a requestId and a status. You then either poll the status or subscribe to a webhook to learn when consent is granted and data is ready. Only when the request reaches APPROVED with consent GRANTED does data become retrievable.
Consent: the rule that governs everything
Consent is owner-granted, scope-specific, time-bounded, revocable, and independent of your tokens. Internalize these five properties and most lifecycle questions answer themselves.
You initiate; the owner approves
For security and EUDA/GDPR compliance, the act of granting consent always happens in the owner's own secure portal session — never through your credentials. A B2B partner can initiate a consent request via API, but cannot grant it. How the owner is brought into the loop differs by integration model:
- M2M (server-to-server): When you create a request, the platform emails the owner a secure deep-link. They follow it, authenticate, review exactly what you asked for (data, purpose, time range), and approve or deny.
- App (Authorization Code + PKCE):The owner is redirected to the Nissan login + consent screen inline during your app's authorization flow, approves there, and is redirected back to your app.
Either way, the owner sees a plain-language description of your request — for example, "Allow [App Name] to access your driving-style data to provide a personalized insurance quote."
Scope-specific and additive-only
Consent is granted at the package level (see Data families). A grant covers exactly the packages and purpose you requested — nothing more. You cannot silently widen scope. If you later need data attributes that were not in the original grant, you must create a new request for the additional scope, which the owner approves separately. This enforces data minimization.
Time-bounded
Every grant carries a duration. Historical requests are bounded by a date range; subscriptions run for an agreed term. When the term ends, consent reaches a terminal "expired" state and data stops automatically.
Revocable at any time
The owner can revoke an active consent from their portal at any moment. Revocation is immediate: real-time streams associated with that grant are terminated and no further data flows. Your integration must treat revocation as a normal, expected event — not an error — and stop relying on that data.
Independent of your access tokens
This is the property most likely to bite you. Your OAuth/M2M token lifecycle and the consent lifecycle are two separate things.
- A valid, unexpired access token does not mean you are entitled to data. Entitlement is gated by stored consent, evaluated fresh on every data access.
- Conversely, refreshing or re-minting a token does not re-grant or extend consent.
So: a real-time read can return 403/no-data even with a perfectly valid token, because the owner revoked consent or the term expired. Always check the request/consent status, not just your token, before assuming data is available.
Consent request expiry
If the owner never acts on a pending request, the request expires after a configurable window (commonly ~7 days, with reminders) and the secure link becomes invalid. The opportunity is closed and you must initiate a fresh request. You are notified of expiry via webhook/polling like any other status change.
The three authorization gates
Before any data is read, every request passes through a centralized compliance engine — three sequential gates. If any gate fails, the request is terminated immediately. You don't call these gates; they run for you. Knowing they exist explains why a request can be rejected even when your call is well-formed.
| Gate | Question it answers | What it checks |
|---|---|---|
| 1 — Governance | Is this B2B entity legally allowed to receive data? | Global sanctions lists and the EUDA "gatekeeper" blocklist. Restricted entities are blocked. |
| 2 — Policy (consent) | Has the owner granted this specific scope? | The requested package/scope against the active consent ledger for that VIN. Enforces data minimization. |
| 3 — Dynamic (entitlement) | Did this owner own this vehicle during the requested window? | The temporal intersection of your request window and the owner's vehicle-ownership window, plus privacy-mode filters. Prevents leakage across previous/subsequent owners. |
Gate 3 is why a historical request can succeed but return less data than the full date range you asked for: only the portion of the window during which the consenting owner actually owned the vehicle is eligible.
Data families: what you can request
Every service package belongs to one of three families. The family determines the delivery mechanism, the request endpoint, and the billing model. List the packages available to your account before creating a request (see the service-package catalog); use the returned package id values in your request body.
| Family | What it provides | How it's delivered | Billing |
|---|---|---|---|
| Historical | Time-series history over a date range — one-off or recurring (periodic) | Async file: zipped CSVs via a time-limited pre-signed download URL | Prepaid per request (one-off); subscription (periodic) |
| Last Known Value | The most recent known value(s); no date range | Synchronous JSON, last-known value | Prepaid per call |
| Real-Time | Live telematics for an approved vehicle | Pull: read a resource snapshot on demand. Push: webhook events on state change | Subscription (aggregated monthly) |
Notes that matter in practice:
- Data availability is vehicle-dependent. For retrieving recorded values, a given vehicle supports either the Historical (time-series over a date range) option or the Last Known Value option — not necessarily both. Some vehicle models expose only the last-known-value service. Always rely on the service-package catalog and the package
typeto see what is actually available for your account and the vehicles you query, rather than assuming a vehicle supports historical. - Real-time delivery is event-driven, not a raw firehose. Subscriptions surface meaningful events — e.g., journey completed, charge-state changed, safety fault — rather than continuous raw pings. This protects your receiving infrastructure. Pull reads give you the latest known state on demand.
- A resource can legitimately return no dataif the vehicle doesn't support it. For example, the
chargingresource returns404for non-EV (ICE) vehicles. - Very high-volume continuous telemetry is out of scope here. Webhook-based delivery is designed for self-serve SME-to-mid scale. If your run-rate or frequency needs grow past the threshold for managed streaming, that is a managed high-throughput streaming tier conversation — contact your account team rather than working around webhook limits.
Billing: how and when you are charged
Billing is enforced by the platform, not your backend. The model depends entirely on the data family / request type — not on whether the call came from an M2M backend or an app.
The prerequisite: a valid payment method
Your API credentials remain suspended until your B2B account has a complete billing profile and a valid default payment method (a credit or debit card). Until then, data-request calls are blocked. Add a payment method in account settings to activate.
Pricing tier
Pricing is rendered dynamically by account type:
- SME — EUDA margin-free rate.
- Large Enterprise — commercial rate.
You don't pass a price; the platform computes it from your account type and the requested package.
Workflow A — One-off historical & last-known (strict prepaid)
A pre-authorization hold is placed for the exact price when the request is created. Payment is captured only at the moment consent is granted; if the owner never consents, the hold is released and nothing is charged.
Workflow B — Recurring subscriptions (periodic & real-time, postpaid aggregated)
Because consented VINs can be added or revoked organically throughout the month, individual VINs are not charged per transaction. Instead, on the 1st of each month, an aggregated billing job sums all active, consented VINs for your account over the prior month and raises a single consolidated charge.
Invoices & retention
Invoices are generated at capture (Workflow A) or at the monthly aggregation (Workflow B) and are available in the portal. Financial records are retained for tax-compliance purposes independently of account deletion.
Choose your integration model: M2M vs. App (PKCE)
You pick the authorization model when you create the integration, and it cannot be changed afterwards. If you need both, create two integrations.
| Server-to-Server (M2M) | Authorization Code + PKCE (App) | |
|---|---|---|
| Best for | Backend services acting on behalf of your organization | Apps acting on behalf of an individual vehicle owner |
| Grant | client_credentials | authorization_code |
| Credentials | client_id + client_secret | client_id only (public client + PKCE; no secret) |
| User login | Not required | Required (owner consents via browser redirect) |
| Redirect URLs | Not used | Required at registration; exact-match enforced |
| How consent is captured | Owner approves via emailed secure deep-link | Owner approves inline on the Nissan login/consent screen |
| Tokens used on reads | access_token only | access_token + X-Id-Token (dual-token) |
| API base path | /cms/m2m/... | /cms/oauth/... |
Rule of thumb: if a human owner is present in your UX and you want them to authenticate and consent in the moment, use App (PKCE). If you're running unattended backend jobs against VINs your organization is permitted to act for, use M2M and rely on email-link consent capture. Both share the same package catalog, the same data-request lifecycle, and the same billing model.
Before you begin
Make sure the following are in place for your B2B account. Data requests are blocked until every gate below passes.
- An active B2B account (not suspended), and your organization is not on a sanctions/gatekeeper blocklist (Gate 1).
- A complete billing profile with a valid default payment method (a credit or debit card). Until this exists, your API credentials are suspended.
- Accepted platform terms and Data Terms & Conditions.
Development vs. production: a development account is sandboxed and vehicle-count-limited for PoC and pre-prod validation; a primary account runs live, contracted services. Build and validate against development first.
Create an integration & get credentials
From the Programmatic Access tab, choose Create Integration and complete the form:
- Application name (3–50 characters).
- Authorization model — M2M or Authorization Code. Immutable after creation.
- Redirect URLs — required for Authorization Code. These are the only URLs the authorize step will redirect back to (exact match).
- Purpose of the integration (shown to owners in the consent prompt).
- Service packages you intend to request.
- Accept the Data Terms & Conditions.
Submit to register. You can later update most fields, but the authorization model stays fixed.
Your credentials
After creation, credentials are shown once in a popup. Store them securely before closing it (you can also download a PDF summary).
- M2M: a
client_idand aclient_secret(the secret is shown only once). - Authorization Code: a
client_idonly (no secret — security comes from PKCE).
Browse the service-package catalog
A service package defines the data a request can access, and which family/billing it falls under. List what's available to your account before creating a request:
M2M
GET {API_BASE}/cms/m2m/accounts/{account_id}/service-packages?dataType=HISTORICAL|REAL_TIMEApp (PKCE) — same shape, OAuth path + dual-token headers:
GET {API_BASE}/cms/oauth/accounts/{account_id}/service-packages?dataType=HISTORICAL|REAL_TIMEEach package returns at least an id, name, description, and type. Use the package id values in the packages array when you create a data request. The catalog is the source of truth for what a given vehicle/account supports — including whether historical time-series or only last-known-value reads are available (see Data families).
Quickstart A — Server-to-Server (M2M)
Backend service, no interactive login. Consent is captured via an emailed secure link to the owner.
- Your backend → Platform API:
POST /cms/m2m/token(client credentials) - Platform API → Your backend:
access_token - Your backend → Platform API: POST data-request (VIN, package, owner email)
- Platform API → Vehicle owner: Email secure consent link
- Platform API → Your backend:
requestId, status =PENDING - Vehicle owner → Platform API: Approve in secure portal
- Platform API → Your backend: Webhook
CONSENT_GRANTED(or poll status) - Your backend → Platform API: GET data (deliveries / resource)
- Platform API → Your backend: Pre-signed download URL or JSON
Step 1 — Get an access token
Exchange your account ID and client credentials for a bearer token:
curl -X POST "{API_BASE}/cms/m2m/token" \
-H "Content-Type: application/json" \
-d '{
"account_id": "YOUR_ACCOUNT_ID",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET"
}'The response contains an access_token and its expires_in lifetime. Send it on every subsequent call:
Authorization: Bearer <access_token>Step 2 — Create a data request
Use the endpoint that matches the package family:
/cms/m2m/accounts/{account_id}/realtime/data-requests/cms/m2m/accounts/{account_id}/historical/data-requestsA request identifies a vehicle (17-character vin), the vehicle user's email (used to notify the owner for consent), and one or more package id values. Historical requests also take requestType (ONE_OFF or PERIODIC), a date range, and — for periodic — a frequency. The exact field names and validation rules are in the API reference.
What happens behind the scenes: the platform runs synchronous validations (valid VIN, resolvable user, active ownership pairing, EUDA temporal limits — see Compliance constraints), creates a PENDING record, sets up the billing hold (Workflow A) or validates the payment method (Workflow B), and emails the owner a secure approval link. The call returns a requestId and status — no data yet.
Step 3 — Monitor the request
Poll the list endpoints (filter by vin, requestStatus, consentStatus, with paging), or subscribe to a webhook to be pushed status changes:
/cms/m2m/accounts/{account_id}/realtime/data-requests/cms/m2m/accounts/{account_id}/historical/data-requestsWait for requestStatus = APPROVED and consentStatus = GRANTED. See Data-request lifecycle & statuses.
Step 4 — Retrieve data
Historical — list deliveries, then fetch a time-limited download URL:
/cms/m2m/accounts/{account_id}/historical/data-requests/{requestId}/data-deliveries/cms/m2m/accounts/{account_id}/historical/.../data-deliveries/{dataDeliveryId}/downloadReal-time — once approved, read a telematics resource directly:
/cms/m2m/accounts/{account_id}/realtime/vehicles/{vin}/{resource}See the real-time telematics catalog for valid {resource} values.
Quickstart B — Authorization Code + PKCE (App)
Use this when an individual owner authorizes your app. PKCE means no client secret.
- Your app: Generate PKCE verifier + challenge
- Your app → Platform API: Redirect owner to
/authorize(challenge) - Platform API → Nissan IdP: Redirect for login
- Vehicle owner → Nissan IdP: Authenticate
- Nissan IdP → Vehicle owner: Consent prompt
- Vehicle owner → Nissan IdP: Approve
- Platform API → Your app: Redirect to callback (auth code)
- Your app → Platform API:
POST /cms/oauth/token(code + verifier) - Platform API → Your app: access_token + id_token + refresh_token
- Your app → Platform API: GET data (Authorization + X-Id-Token)
- Platform API → Your app: Data
Step 1 — Generate a PKCE verifier and challenge (per authorization attempt)
// Keep the verifier private; send only the challenge to /authorize.
const verifier = base64url(crypto.getRandomValues(new Uint8Array(32)));
const digest = await crypto.subtle.digest(
"SHA-256",
new TextEncoder().encode(verifier)
);
const codeChallenge = base64url(new Uint8Array(digest));Step 2 — Redirect the owner to the authorize endpoint
/cms/oauth/authorize{API_BASE}/cms/oauth/authorize
?account_id=YOUR_ACCOUNT_ID
&client_id=YOUR_CLIENT_ID
&redirectUri=https://your-app.example.com/callback
&codeChallenge=BASE64URL_SHA256_OF_VERIFIER
&codeChallengeMethod=S256The owner logs in via the Nissan IdP, sees the plain-language consent prompt for the scopes you requested, approves, and is redirected back to your redirectUri with an auth code.
redirectUri must exactly match one of the redirect URLs registered for the integration, or the request is rejected.Step 3 — Exchange the code for tokens (on your callback, using the original verifier)
/cms/oauth/tokencurl -X POST "{API_BASE}/cms/oauth/token" \
-H "Content-Type: application/json" \
-d '{
"grant_type": "authorization_code",
"code": "AUTH_CODE_FROM_CALLBACK",
"redirect_uri": "https://your-app.example.com/callback",
"client_id": "YOUR_CLIENT_ID",
"code_verifier": "ORIGINAL_VERIFIER"
}'You receive an access_token, an id_token, and a refresh_token.
Step 4 — Call owner-scoped APIs with dual tokens
Every /cms/oauth/accounts/... call requires both headers:
Authorization: Bearer <access_token>
X-Id-Token: <id_token>The owner-scoped endpoints mirror the M2M ones:
/cms/oauth/accounts/{account_id}/realtime/data-requests/cms/oauth/accounts/{account_id}/historical/data-requests/cms/oauth/accounts/{account_id}/realtime/data-requests/cms/oauth/accounts/{account_id}/historical/data-requests/cms/oauth/accounts/{account_id}/realtime/vehicles/{vin}/{resource}Step 5 — Refresh tokens before they expire
The refresh token rotates on each use — store the new one each time:
/cms/oauth/token/refreshcurl -X POST "{API_BASE}/cms/oauth/token/refresh" \
-H "Content-Type: application/json" \
-d '{
"clientId": "YOUR_CLIENT_ID",
"refreshToken": "YOUR_REFRESH_TOKEN"
}'Data-request lifecycle & statuses
A request moves through several states as the owner consents and data is delivered. Poll the list endpoints or use webhooks to track it. These are the authoritative enums returned by the API:
| Field | Values |
|---|---|
requestStatus | PENDING, ACTIVE, APPROVED, DECLINED, COMPLETED, REVOKED, CANCELLED, INVALID, EXPIRED |
consentStatus | PENDING, GRANTED, REVOKED, EXPIRED, DENIED, SUPERSEDED |
package status | PENDING, GRANTED, DENIED, EXPIRED, REVOKED |
requestType | HISTORICAL, REAL_TIME, ONE_OFF, PERIODIC |
frequency | MONTHLY, WEEKLY (periodic only) |
The consent lifecycle, in brief:
| Transition | When |
|---|---|
PENDING → APPROVED | Owner grants |
PENDING → DECLINED | Owner denies |
PENDING → EXPIRED | No action in window |
APPROVED → COMPLETED | One-off delivered |
APPROVED → REVOKED | Owner revokes |
APPROVED → EXPIRED | Term ends |
How to read the statuses together:
PENDING/consentStatus = PENDING— created, owner notified, awaiting action. No data.APPROVED+GRANTED— the only state in which data is retrievable. Real-time reads and historical deliveries are available here.DECLINED/consentStatus = DENIED— owner rejected. Terminal; initiate a new request if still needed.EXPIRED(request) /consentStatus = EXPIRED— either the request lapsed before the owner acted, or the consent term ended. Terminal; create a fresh request.REVOKED— owner revoked an active grant; data stops immediately. Terminal for that grant.SUPERSEDED(consent) — a newer consent grant has replaced this one (e.g., re-scoped request).COMPLETED— a one-off request whose delivery has been fulfilled.INVALID/CANCELLED— failed validation (bad VIN, no ownership link, etc.) or was cancelled.
requestStatus = APPROVED and consentStatus = GRANTED.Retrieving data
Historical (file delivery)
Historical results are prepared asynchronously and delivered as zipped CSVs via a time-limited pre-signed download URL (session/IP- restricted). The flow:
- Request reaches
APPROVED+GRANTEDand (Workflow A) payment is captured. - List deliveries:
GET .../historical/data-requests/{requestId}/data-deliveries. - Fetch the download URL:
GET .../data-deliveries/{dataDeliveryId}/download. - Download promptly — the URL expires.
If you created the request via API and subscribed to webhooks, you'll receive a delivery-ready event instead of needing to poll.
Last-known value
Last-known packages return the most recent known value(s) synchronously as JSON — no date range, no async file. Availability is vehicle-dependent (see Data families); expect a single response per call.
Real-time (pull)
Once APPROVED + GRANTED, read the latest known state of a resource on demand:
GET {API_BASE}/cms/{m2m|oauth}/accounts/{account_id}/realtime/vehicles/{vin}/{resource}Real-time (push)
Subscribe a webhook to receive events on state change instead of polling. Real-time push is event-driven (e.g., journey completed, charge-state changed, safety fault).
Real-time telematics catalog
Real-time resources are read per vehicle via .../realtime/vehicles/{vin}/{resource}. Available {resource} values:
| Resource | Description |
|---|---|
location | Current GPS position |
cockpit | Odometer, fuel/energy and cockpit readouts |
charging | EV charging state (EV only; 404 for ICE vehicles) |
hvac | Climate / HVAC state |
tirepressure | Tire pressure readings |
occupancy | Seat occupancy / belt status |
visibility | Lights and visibility-related state |
adas | Advanced driver-assistance state |
behavior | Driving-behavior signals |
security | Doors, locks and alarm state |
healthstatus | Vehicle health / diagnostic status |
charging returns 404 for non-EV (ICE) vehicles. This is expected, not an error in your integration.Webhooks
Subscribe a webhook to receive push notifications instead of polling — for consent status changes, historical delivery readiness, and real-time events.
- Platform → Your endpoint: Challenge value
- Your endpoint → Platform: Echo challenge
- Platform: Save subscription (active)
- Platform → Your endpoint: POST event +
X-NiCoDap-Sig(HMAC-SHA256) - Your endpoint: Verify signature, then process
What you provide
- A publicly reachable HTTPS callback URL.
- An HMAC key (up to 32 characters) used to sign payloads so you can verify authenticity.
Manage subscriptions from the portal (or the webhook API, where available).
Registration handshake (ownership challenge)
When you register a callback URL, the platform verifies you own it before it will send events:
- The platform sends a challenge to your URL.
- Your endpoint must echo the challenge back in the response.
- On a match, the subscription is saved and set active.
Runtime delivery & signature verification
At runtime, the platform POSTs each event to your URL with an HMAC-SHA256 signature computed over the body using your shared HMAC key, carried in the X-NiCoDap-Sig header.
HMAC-SHA256(body, your_hmac_key) and compare to the header; reject on mismatch.Events to expect
- Consent lifecycle changes — e.g., consent granted, denied, revoked, expired (carrying the
requestId). - Historical delivery ready — file download is available.
- Real-time telemetry push — e.g., the
telemetry-pushevent and event-driven topics such as journey completed, charge-state changed, and safety fault, depending on the subscribed package.
Compliance constraints you must design for
These are EUDA/GDPR constraints enforced by the platform. Designing for them up front avoids confusing rejections and partial results.
Temporal limits on historical requests
- Earliest requestable date: 12 September 2025 (EUDA effective date). You cannot request data older than this.
- Maximum 90 days per historical request. Split longer ranges into multiple requests.
- Lookback limited to ~3 years. Older history is not available.
Ownership / entitlement (Gate 3)
- Data is only eligible for the portion of your requested window during which the consenting owner actually owned the vehicle. A valid request can therefore return a shorter window than asked.
- Entitlement resolution differs by vehicle generation: for older generations an active ownership link suffices; newer generations additionally verify the active driver against the linked owner. The net effect for you: don't assume every request yields the full range — handle partial results.
Data minimization (Gate 2)
- You receive exactly the packages/scopes the owner approved. Need more? Initiate a new request.
Governance (Gate 1)
- Sanctioned or gatekeeper-designated entities are blocked at login and at request time.
Retention & deletion
- Delivered files and decisions are retained as audit records under the platform's retention policy. Financial records persist for tax compliance even after account deletion.
Errors & troubleshooting
| Symptom | Likely cause / fix |
|---|---|
401 | On /cms/oauth/accounts/... calls: missing or invalid X-Id-Token. Owner-scoped calls need both the access token and the id token. |
| 401 token expired | Refresh with /cms/oauth/token/refresh (App) or request a new token (M2M). |
| Real-time read returns 4xx / no data | No APPROVED request with GRANTED consent exists for that VIN/package yet — or consent was revoked/expired. Check requestStatus + consentStatus, not your token. |
| charging returns 404 | The vehicle is ICE (non-EV); charging is EV-only. Expected. |
| Historical result smaller than requested range | Gate 3 trimmed the window to the consenting owner's ownership period. Expected under EUDA. |
| Authorize rejects the redirect | redirectUri does not exactly match a registered redirect URL. |
| Request blocked at creation | An onboarding gate failed: suspended account, incomplete billing / no valid payment method, unaccepted Data T&C, or a gatekeeper/sanctions block. Fix in settings; retrying without fixing will fail again. |
| Request goes INVALID immediately | Validation failed — invalid VIN, unresolvable user email, or no active owner–VIN pairing. |
| Consent never granted, request EXPIRED | Owner didn't act within the consent window. The link is dead; initiate a new request. |
| Download link doesn't work | Pre-signed URLs are time- and session/IP-limited. Re-fetch a fresh URL from the deliveries endpoint. |
| Webhook events not arriving | Registration challenge wasn't echoed correctly, or your URL isn't reachable over HTTPS. Re-verify the subscription. |
| Charged differently than expected | One-off/historical is prepaid (hold→capture on consent); subscriptions are billed via a single aggregated charge on the 1st. SME vs. Large rates differ. |
Rate limits & operational notes
- The API Gateway applies rate-limiting policies. Build in retry-with-backoff and treat
429as transient. - Validate against a development account (sandboxed, vehicle-count-limited) before going to production.
- Real-time/webhook delivery suits self-serve SME-to-mid volumes. If sustained run-rate or frequency grows beyond the platform's managed-streaming threshold, that's a managed high-throughput streaming tier conversation — contact your account team rather than working around webhook limits.
- Token hygiene: store the rotating refresh token after every refresh (App); never ship the client secret to a client device (M2M).
Glossary
| Term | Meaning |
|---|---|
| Account ID | Your B2B account identifier, used in API paths and the M2M token request. |
| Client ID / Secret | Integration credentials. The secret applies to M2M only. |
| VIN | 17-character Vehicle Identification Number. |
| Package | A catalog entry defining the data a request can access; consent and billing are granted at the package level. |
| Data family | Historical, Last Known Value, or Real-Time — determines delivery and billing. |
| Consent | The vehicle owner's explicit, scope-specific, time-bounded, revocable approval for a data request. |
| Consent vs. token | Two independent lifecycles. Tokens authenticate your client; consent authorizes data. Both must be valid. |
| 3-Gate engine | The sequential governance → consent-scope → ownership-time authorization run on every data access. |
| Entitlement | Whether the consenting owner owned the vehicle during the requested window (Gate 3). |
| Gatekeeper / blocklist | EUDA-designated restricted entities blocked from receiving data (Gate 1). |
| PKCE | Proof Key for Code Exchange — secures the Authorization Code flow without a client secret. |
| Dual-token | Sending both Authorization: Bearer and X-Id-Token on owner-scoped (/cms/oauth/...) calls. |
| Pre-auth hold / capture | A hold is placed at request time and captured when the owner consents (one-off/historical). |
| Aggregated billing | A single monthly charge on the 1st covering all active, consented VINs (subscriptions). |
| SME / Large Enterprise | Account tiers; SME gets the EUDA margin-free rate, Large the commercial rate. |
| Pre-signed URL | A time- and session-limited download link for historical file deliveries. |
API reference (Swagger)
The reference below is generated from the live OpenAPI specification. Use it for exact request/response schemas and to try endpoints interactively.
In the portal, the interactive Swagger UI is embedded below. The OpenAPI document is served (per environment) from:
{API_BASE}/cms/openapi-by-tag.json?tags=b2b-developer-data-requests,realtime-data