Connect Your First Vehicle
Learn how to connect your first vehicle to DIMO and access real-time vehicle data.
⏱️ Time to complete: 10 minutes 💰 Cost: Free (Hobbyist tier) 📚 Prerequisites: Basic JavaScript/TypeScript knowledge, Node.js installed 🎯 Difficulty: Beginner
What You'll Build
By the end of this tutorial, you'll have:
- ✅ A DIMO Developer License with credentials
- ✅ The DIMO Data SDK installed and configured
- ✅ Authentication working (Developer JWT)
- ✅ A vehicle connected via DIMO Connect
- ✅ Real-time telemetry data flowing to your application
Step 1: Create Your Developer License
Time: 2 minutes
- Visit console.dimo.org
- Sign up for a free account (or sign in if you already have one)
- Create a Developer License - this acts like an access card for the DIMO platform
- Give your license a descriptive name (e.g., "My First DIMO App")
A Developer License is your application's identity on the DIMO platform. It allows you to request data from vehicle owners and access DIMO APIs.
Expected Result: You should see your new Developer License in the console.
Step 2: Get Your Credentials
Time: 1 minute
From your Developer License in the console, you'll need three things:
- Client ID - Your application's public identifier
- Redirect URI - Where users return after granting permissions (e.g.,
http://localhost:3000/callback) - API Key - Your private key for authentication
Keep your API Key secure! Never commit it to Git or share it publicly. Store it in environment variables.
Store credentials safely:
Create a .env file in your project:
DIMO_CLIENT_ID="your_client_id_here"
DIMO_REDIRECT_URI="http://localhost:3000/callback"
DIMO_API_KEY="your_api_key_here"
Add .env to your .gitignore:
.env
Step 3: Install the DIMO Data SDK
Time: 30 seconds
The DIMO Data SDK provides methods for authentication and querying vehicle data.
- npm
- Yarn
- pnpm
npm install @dimo-network/data-sdk
yarn add @dimo-network/data-sdk
pnpm add @dimo-network/data-sdk
Verify installation:
npm list @dimo-network/data-sdk
Step 4: Authenticate (Get Developer JWT)
Time: 2 minutes
Create a file to initialize the DIMO SDK and get your Developer JWT:
- TypeScript
- JavaScript
import { DIMO } from '@dimo-network/data-sdk';
import * as dotenv from 'dotenv';
// Load environment variables
dotenv.config();
// Initialize DIMO SDK
const dimo = new DIMO('Production'); // or 'Staging' for testing
async function authenticateWithDIMO() {
try {
// Get Developer JWT
const auth = await dimo.auth.getDeveloperJwt({
client_id: process.env.DIMO_CLIENT_ID!,
domain: process.env.DIMO_REDIRECT_URI!,
private_key: process.env.DIMO_API_KEY!,
});
console.log('✅ Authentication successful!');
console.log('Developer JWT:', auth.access_token.substring(0, 20) + '...');
return auth;
} catch (error) {
console.error('❌ Authentication failed:', error);
throw error;
}
}
// Export for use in other files
export { dimo, authenticateWithDIMO };
// Run if called directly
if (require.main === module) {
authenticateWithDIMO();
}
const { DIMO } = require('@dimo-network/data-sdk');
const dotenv = require('dotenv');
// Load environment variables
dotenv.config();
// Initialize DIMO SDK
const dimo = new DIMO('Production'); // or 'Staging' for testing
async function authenticateWithDIMO() {
try {
// Get Developer JWT
const auth = await dimo.auth.getDeveloperJwt({
client_id: process.env.DIMO_CLIENT_ID,
domain: process.env.DIMO_REDIRECT_URI,
private_key: process.env.DIMO_API_KEY,
});
console.log('✅ Authentication successful!');
console.log('Developer JWT:', auth.access_token.substring(0, 20) + '...');
return auth;
} catch (error) {
console.error('❌ Authentication failed:', error);
throw error;
}
}
// Export for use in other files
module.exports = { dimo, authenticateWithDIMO };
// Run if called directly
if (require.main === module) {
authenticateWithDIMO();
}
Test your authentication:
node src/dimo-auth.js
Expected Output:
✅ Authentication successful!
Developer JWT: eyJhbGciOiJSUzI1NiIs...
Step 5: Connect a Vehicle with DIMO Connect
Time: 3 minutes
To access vehicle data, users must grant your application permission. DIMO Connect is the flow where users authenticate and share their vehicles with your app.
Create Your DIMO Connect URL
Build a URL that users will visit to grant permissions:
const clientId = process.env.DIMO_CLIENT_ID;
const redirectUri = encodeURIComponent(process.env.DIMO_REDIRECT_URI!);
// Build DIMO Connect URL
const dimoConnectUrl = `https://login.dimo.org?client_id=${clientId}&redirect_uri=${redirectUri}`;
console.log('Share this URL with users to connect their vehicles:');
console.log(dimoConnectUrl);
What Happens Next
- User visits your DIMO Connect URL
- User logs in with their DIMO account (or creates one)
- User selects which vehicle(s) to share with your app
- User is redirected back to your
redirect_uriwith authorization - You receive a
tokenIdfor each vehicle they shared
Users can also connect vehicles through the DIMO Mobile app and then grant permissions to your app through the "Connected Apps" settings.
Step 6: Get Vehicle JWT and Fetch Data
Time: 2 minutes
Once a user has shared a vehicle with you, you'll receive a tokenId. Use this to get a Vehicle JWT and query telemetry data:
import { dimo, authenticateWithDIMO } from './dimo-auth';
async function getVehicleData(vehicleTokenId: number) {
try {
// 1. Get Developer JWT
const developerAuth = await authenticateWithDIMO();
// 2. Exchange for Vehicle JWT
const vehicleAuth = await dimo.tokenexchange.getVehicleJwt({
...developerAuth,
tokenId: vehicleTokenId,
privileges: [1, 3], // Request: all-time non-location data + current location
});
console.log('✅ Vehicle JWT obtained!\n');
// 3. Query Telemetry API for real-time data
const telemetryData = await dimo.telemetry.query({
...vehicleAuth,
query: `
query GetLatestSignals($tokenId: Int!) {
signalsLatest(tokenId: $tokenId) {
speed {
value
timestamp
}
powertrainRange {
value
timestamp
}
chargeLevel: batterySoc {
value
timestamp
}
latitude {
value
timestamp
}
longitude {
value
timestamp
}
}
}
`,
variables: {
tokenId: vehicleTokenId
}
});
console.log('📊 Latest Vehicle Data:');
console.log(JSON.stringify(telemetryData, null, 2));
return telemetryData;
} catch (error) {
console.error('❌ Error fetching vehicle data:', error);
throw error;
}
}
// Example usage (replace with actual tokenId from DIMO Connect)
// getVehicleData(12345);
export { getVehicleData };
Run your code (replace 12345 with your actual vehicle tokenId):
node -r dotenv/config src/get-vehicle-data.js
Expected Output:
✅ Vehicle JWT obtained!
📊 Latest Vehicle Data:
{
"data": {
"signalsLatest": {
"speed": {
"value": 45.5,
"timestamp": "2025-01-22T15:30:00Z"
},
"powertrainRange": {
"value": 245,
"timestamp": "2025-01-22T15:30:00Z"
},
"chargeLevel": {
"value": 82,
"timestamp": "2025-01-22T15:30:00Z"
},
"latitude": {
"value": 37.7749,
"timestamp": "2025-01-22T15:30:00Z"
},
"longitude": {
"value": -122.4194,
"timestamp": "2025-01-22T15:30:00Z"
}
}
}
}
Troubleshooting
Issue: "Invalid credentials"
Cause: Client ID, Redirect URI, or API Key is incorrect.
Solution:
- Verify credentials in the DIMO Console
- Check environment variables are loading:
console.log('Client ID:', process.env.DIMO_CLIENT_ID);
console.log('Has API Key:', !!process.env.DIMO_API_KEY); - Regenerate API Key if needed
Issue: "No vehicles found" / "Missing tokenId"
Cause: No vehicles have been shared with your Developer License yet.
Solution:
- Share the DIMO Connect URL with a user (or use it yourself)
- Complete the vehicle sharing flow
- Check shared vehicles in the Developer Console under "Vehicles"
Issue: "Token exchange failed"
Cause: Invalid tokenId or insufficient permissions.
Solution:
- Verify the tokenId is correct
- Check that the vehicle owner granted the specific permissions you're requesting (privileges array)
Issue: "Rate limit exceeded"
Cause: Too many API requests in a short time.
Solution:
- Hobbyist tier: 10 requests/second limit
- Add delays between requests:
await new Promise(r => setTimeout(r, 100)); - Upgrade to Core plan for higher limits
Next Steps
🎉 Congratulations! You've successfully connected your first vehicle to DIMO.
Continue learning:
-
Explore Telemetry API Discover all available vehicle signals and data points
-
Chat with Your Vehicle Using AI Build conversational AI agents powered by vehicle data
-
Set Up Webhooks Get real-time notifications when vehicle events occur
-
Build with React SDK Use
@dimo-network/login-with-dimofor seamless user authentication -
Deploy to Production Best practices for production deployments
Complete Working Example
Here's a complete example that ties everything together:
import { DIMO } from '@dimo-network/data-sdk';
import * as dotenv from 'dotenv';
dotenv.config();
const dimo = new DIMO('Production');
interface VehicleSnapshot {
tokenId: number;
speed: number | null;
range: number | null;
battery: number | null;
location: { lat: number; lng: number } | null;
timestamp: string;
}
async function getVehicleDashboard(vehicleTokenId: number): Promise<VehicleSnapshot> {
// 1. Authenticate
const devAuth = await dimo.auth.getDeveloperJwt({
client_id: process.env.DIMO_CLIENT_ID!,
domain: process.env.DIMO_REDIRECT_URI!,
private_key: process.env.DIMO_API_KEY!,
});
// 2. Get Vehicle JWT
const vehicleAuth = await dimo.tokenexchange.getVehicleJwt({
...devAuth,
tokenId: vehicleTokenId,
privileges: [1, 3], // Non-location data + current location
});
// 3. Query latest telemetry
const result = await dimo.telemetry.query({
...vehicleAuth,
query: `
query GetVehicleSnapshot($tokenId: Int!) {
signalsLatest(tokenId: $tokenId) {
speed { value timestamp }
powertrainRange { value }
batterySoc { value }
latitude { value }
longitude { value }
}
}
`,
variables: { tokenId: vehicleTokenId }
});
const signals = result.data.signalsLatest;
return {
tokenId: vehicleTokenId,
speed: signals.speed?.value || null,
range: signals.powertrainRange?.value || null,
battery: signals.batterySoc?.value || null,
location: signals.latitude && signals.longitude
? { lat: signals.latitude.value, lng: signals.longitude.value }
: null,
timestamp: signals.speed?.timestamp || new Date().toISOString()
};
}
// Usage
if (require.main === module) {
const tokenId = parseInt(process.argv[2] || '0');
if (!tokenId) {
console.error('Usage: node vehicle-dashboard.js <tokenId>');
process.exit(1);
}
getVehicleDashboard(tokenId)
.then(dashboard => {
console.log('\n🚗 Vehicle Dashboard:\n');
console.log(JSON.stringify(dashboard, null, 2));
})
.catch(error => {
console.error('Error:', error.message);
process.exit(1);
});
}
export { getVehicleDashboard };
Run it:
node -r dotenv/config examples/vehicle-dashboard.js 12345
Additional Resources
- 📚 DIMO Data SDK Documentation
- 📚 Authentication Guide
- 🔌 DIMO Connect (Client SDK)
- 🎮 API References
- 💬 Discord Community - Get help from developers
- 📧 [email protected]
Questions? Join our Discord and ask in the #developers channel!