Skip to main content

Quickstart

Get your first API call working in under 5 minutes.

Prerequisites

  • Node.js 18+ installed
  • Your client ID and secret from the JLR Developer Portal
  • The jose and uuid npm packages
npm install jose uuid

Step 1: Generate a DPoP key pair

const { generateKeyPair, exportJWK } = require('jose');

async function setup() {
const { publicKey, privateKey } = await generateKeyPair('ES256');
const publicJwk = await exportJWK(publicKey);

// Store these securely — you'll reuse the same key pair
return { publicKey, privateKey, publicJwk };
}

Step 2: Create a DPoP proof helper

const { SignJWT } = require('jose');
const { v4: uuidv4 } = require('uuid');

async function createDPoPProof(privateKey, publicJwk, method, url) {
return await new SignJWT({
jti: uuidv4(),
htm: method,
htu: url,
iat: Math.floor(Date.now() / 1000),
})
.setProtectedHeader({
alg: 'ES256',
typ: 'dpop+jwt',
jwk: publicJwk,
})
.sign(privateKey);
}

Step 3: Obtain an access token

async function getToken(privateKey, publicJwk, clientId, clientSecret) {
const tokenUrl = 'https://api.data.jlr-vcdp.com/auth/token';
const dpopProof = await createDPoPProof(privateKey, publicJwk, 'POST', tokenUrl);

const response = await fetch(tokenUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'DPoP': dpopProof,
},
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: clientId,
client_secret: clientSecret,
scope: 'vehicle:read',
}),
});

return await response.json();
}

Step 4: Make an API call

async function getVehicle(privateKey, publicJwk, accessToken, vin) {
const url = `https://api.data.jlr-vcdp.com/v1/vehicles/${vin}`;
const dpopProof = await createDPoPProof(privateKey, publicJwk, 'GET', url);

const response = await fetch(url, {
headers: {
'Authorization': `DPoP ${accessToken}`,
'DPoP': dpopProof,
},
});

return await response.json();
}

Step 5: Put it all together

async function main() {
const { privateKey, publicJwk } = await setup();

// Get access token
const tokenResponse = await getToken(
privateKey, publicJwk,
'YOUR_CLIENT_ID', 'YOUR_CLIENT_SECRET'
);

console.log('Token type:', tokenResponse.token_type); // "DPoP"

// Fetch vehicle data
const vehicle = await getVehicle(
privateKey, publicJwk,
tokenResponse.access_token,
'SALGA2BN6PH123456'
);

console.log('Vehicle:', vehicle.Vehicle.VehicleIdentification.Model);
}

main().catch(console.error);

What's next