Skip to main content

Does my login work for Geotab API?

AGibs-2017
Original Poster
Join the conversation

You need to be logged in to reply to this post and participate in the Geotab Community discussions.

Top Answers

Hey @AGibs-2017​,

 

Just to add on to @EishiFUN​'s answer, you should use a service account if you want to follow best practices. Here are the guidelines. Hope that helps!

9 Replies

EishiFUN
Geotabber

Hello @AGibs-2017​ ,

 

Thank you for asking our question in our community. Yes you will use the same credentials you use for MyGeotab in the API.

 

If you have any other questions feel free to reach out. We are here to help.

 

Have a great day!

Eishi FUN

Hey @AGibs-2017​,

 

Just to add on to @EishiFUN​'s answer, you should use a service account if you want to follow best practices. Here are the guidelines. Hope that helps!

AGibs-2017
Original Poster

Hello Tucker first off thank you for your help. I did follow the instructions and received this message after attempting:

Authentication failed: {"error":{"message":"Incorrect login credentials","code":-32000,"data":{"id":"af5ff242-d5a4-46ad-93fb-3bcad09027f0","type":"InvalidUserException","requestIndex":0},"name":"JSONRPCError","errors":[{"message":"Incorrect login credentials","name":"InvalidUserException"}]},"jsonrpc":"2.0","id":1,"requestIndex":0}

Any idea why?

EishiFUN
Geotabber

Thanks Tucker!

Can you send me the API request you're making? It's probably just a formatting issue.

 

Thanks,

Tucker

AGibs-2017
Original Poster

Hello Tucker, I have been trying different methods and all come back with the login error. Here is the latest one I have tried.

 

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Geotab Vehicle Fetcher</title></head><body><input type="text" id="vinInput" placeholder="Enter VIN"><button onclick="fetchGeotabData()">Fetch Vehicle Details</button><div id="output"></div>

<script> async function fetchGeotabData() { console.log("Button clicked."); const vin = document.getElementById('vinInput').value.trim(); console.log("VIN entered: " + vin);

if (!vin) { alert("Please enter a VIN."); return; }

const url = "https://my.geotab.com/apiv1"; // Geotab API endpoint const database = "****"; // Your actual database here const username = "****"; // Your username here const password = "****"; // Your password here

// Step 1: Authenticate payload const authPayload = { method: "Authenticate", params: { database, username, password }, id: 1, jsonrpc: "2.0" };

try { // Step 2: Authenticate const authResponse = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(authPayload) });

console.log("Auth Response Status: ", authResponse.status);

if (!authResponse.ok) { const errorText = await authResponse.text(); throw new Error(`Network error: ${authResponse.status} ${errorText}`); }

const authJsonResponse = await authResponse.json(); console.log("Authentication Response: ", authJsonResponse);

if (authJsonResponse.error) { throw new Error("Auth Error: " + authJsonResponse.error.message); }

const sessionToken = authJsonResponse.result.credentials.sessionId;

// Step 3: Fetch Vehicles using the Session ID const vehiclesPayload = { method: "Get", params: { type: "Vehicle", search: { vin: vin }, credentials: { database, username, sessionId: sessionToken } }, id: 2, jsonrpc: "2.0" };

const vehiclesResponse = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(vehiclesPayload) });

console.log("Vehicles Response Status: ", vehiclesResponse.status);

if (!vehiclesResponse.ok) { const errorText = await vehiclesResponse.text(); throw new Error(`Network error: ${vehiclesResponse.status} ${errorText}`); }

const vehiclesJson = await vehiclesResponse.json(); console.log("Vehicles Response: ", vehiclesJson);

if (vehiclesJson.error) { throw new Error("Error fetching vehicles: " + vehiclesJson.error.message); }

const vehicle = vehiclesJson.result[0]; if (vehicle && vehicle.id) { document.getElementById('output').innerHTML = `Vehicle Name: ${vehicle.name}, VIN: ${vehicle.vin}`; } else { alert("No vehicle found with VIN: " + vin); }

} catch (error) { console.error("Error: ", error); alert("An error occurred: " + error.message); } } </script></body></html>

Hey @AGibs-2017​,

 

This should work:

 

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Geotab Vehicle Fetcher</title></head><body><input type="text" id="vinInput" placeholder="Enter VIN"><button onclick="fetchGeotabData()">Fetch Vehicle Details</button><div id="output"></div>

 

<script> 

async function fetchGeotabData() {

console.log("Button clicked."); const vin = document.getElementById('vinInput').value.trim(); console.log("VIN entered: " + vin);

 

async function authenticate() {

 try {

  

const url = "https://my.geotab.com/apiv1"; // Geotab API endpoint 

 

const database = "***"; // Your actual database here 

const username = "***"; // Your username here 

const password = "***"; // Your password here

 

// Step 1: Authenticate payload 

 

const authPayload = { method: "Authenticate", params: { "database": database, "userName": username, "password": password }};

 

const authResponse = await fetch(url, {

 method: 'POST',

 headers: { 'Content-Type': 'application/json' },

 body: JSON.stringify(authPayload)

});

const data = await authResponse.json(); // Parse as JSON

console.log("Response JSON:", data);

 } catch (error) {

console.error("Error:", error);

 }

}

 

if (!vin) { alert("Please enter a VIN."); return; }

 

authenticate();

}

 

</script></body></html>

AGibs-2017
Original Poster

First off thanks for all the help. I did finally get it to work and made some modifications. I do need to know if there is a way to add odometer and location to this.

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Geotab Pull</title> <style> body { font-family: Arial, sans-serif; margin: 20px; background-color: #CDDCAF; /* New background color */ } #output { margin-top: 20px; background-color: #f4f4f4; padding: 10px; border: 1px solid #ccc; border-radius: 5px; overflow-x: auto; /* Allow horizontal scrolling */ } table { width: 100%; border-collapse: collapse; margin-top: 10px; } th, td { border: 1px solid #ddd; padding: 8px; text-align: left; } th { background-color: #f2f2f2; } h2 { color: #333; } ul { margin: 0; padding-left: 20px; } pre { display: none; /* Hide raw JSON */ } </style> </head> <body>   <h1>Geotab Data</h1> <label for="vinInput">Enter VIN:</label> <input type="text" id="vinInput" placeholder="Enter VIN" /> <button onclick="fetchGeotabData()">Click Here</button>   <div id="output"></div>   <script> async function authenticate() { const url = "https://my.geotab.com/apiv1"; // Geotab API endpoint const database = "******"; const username = "******"; const password = "******";   const authPayload = { method: "Authenticate", params: { database: database, userName: username, password: password } };   try { console.log("Authenticating..."); const authResponse = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept-Version': '1' }, body: JSON.stringify(authPayload) });   const data = await authResponse.json(); // Parse as JSON console.log("Authentication Response:", data); if (data.error) { alert("Authentication failed: " + data.error.message); return null; // Authentication failure }   return data.result.credentials; // Return the credentials object } catch (error) { console.error("Error during authentication:", error); return null; // Error during fetch } }   async function fetchGeotabData() { console.log("Button clicked."); const vehicleIdentificationNumber = document.getElementById('vinInput').value.trim(); console.log("Vehicle Identification Number entered: " + vehicleIdentificationNumber);   if (!vehicleIdentificationNumber) { alert("Please enter VIN."); return; }   const credentials = await authenticate(); // Get credentials from the authenticate function if (!credentials) { alert("Authentication failed."); return; // Exit if no credentials }   // Log the credentials for debugging console.log("Using credentials:", credentials);   // Fetch vehicle details using the credentials and Vehicle Identification Number try { const vehiclePayload = { method: "Get", params: { typeName: "Device", // Specifies that we want to retrieve Device information search: { vehicleIdentificationNumber: vehicleIdentificationNumber // Using the correct field name }, credentials: credentials // Include the credentials object here } };   console.log("Fetching vehicle data with payload:", JSON.stringify(vehiclePayload, null, 2));   const vehicleResponse = await fetch("https://my.geotab.com/apiv1", { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept-Version': '1' }, body: JSON.stringify(vehiclePayload) });   const vehicleData = await vehicleResponse.json(); // Parse as JSON // Log the full response for debugging console.log("Vehicle Response JSON:", JSON.stringify(vehicleData, null, 2));   if (vehicleData.error) { alert("Failed to fetch vehicle details: " + vehicleData.error.message); return; // Exit if there's an error in response }   // Check if a specific vehicle is returned if (!vehicleData.result || vehicleData.result.length === 0) { alert("No vehicle found with the specified Vehicle Identification Number."); } else { displayVehicleData(vehicleData.result[0]); // Display the first vehicle's data } } catch (error) { console.error("Error fetching vehicle details:", error); alert("Error fetching vehicle details. Please check console for more information."); } }   function displayVehicleData(vehicleInfo) { let outputHTML = '<h2>Vehicle Details</h2><table>';   // Define the preferred and deferred key order const preferredKeys = [ 'vehicleIdentificationNumber', 'serialNumber', 'comment', 'name', 'engineType' ];   const deferredKeys = [ 'accelerationWarningThreshold', 'accelerometerThresholdWarningFactor', 'brakingWarningThreshold', 'corneringWarningThreshold', 'enableBeepOnDangerousDriving', 'enableBeepOnRpm', 'engineHourOffset', 'isActiveTrackingEnabled', 'forceActiveTracking', 'isDriverSeatbeltWarningOn', 'isPassengerSeatbeltWarningOn', 'isReverseDetectOn', 'isIoxConnectionEnabled', 'odometerFactor', 'odometerOffset', 'rpmValue', 'seatbeltWarningSpeed', 'activeFrom', 'activeTo', 'disableBuzzer', 'enableBeepOnIdle', 'enableSpeedWarning', 'idleMinutes', 'isSpeedIndicator', 'minAccidentSpeed', 'speedingOff', 'speedingOn', 'goTalkLanguage', 'fuelTankCapacity', 'wifiHotspotLimits', 'autoGroups', 'customParameters', 'enableMustReprogram', 'engineVehicleIdentificationNumber', 'ensureHotStart', 'gpsOffDelay', 'licensePlate', 'licenseState', 'major', 'minor', 'parameterVersion', 'pinDevice', 'groups', 'timeZoneId', 'deviceFlags', 'deviceType', 'id', 'ignoreDownloadsUntil', 'maxSecondsBetweenLogs', 'productId', 'timeToDownload', 'workTime', 'devicePlans', 'devicePlanBillingInfo', 'customProperties', 'mediaFiles', 'isContinuousConnectEnabled', 'obdAlertEnabled', 'auxWarningSpeed', 'enableAuxWarning', 'enableControlExternalRelay', 'externalDeviceShutDownDelay', 'immobilizeArming', 'immobilizeUnit', 'isAuxIgnTrigger', 'isAuxInverted' ];   // Iterate through preferred keys first for (const key of preferredKeys) { if (vehicleInfo.hasOwnProperty(key)) { outputHTML += `<tr><td><strong>${key}</strong></td><td>${formatValue(vehicleInfo[key])}</td></tr>`; } }   // Then iterate through the deferred keys for (const key of deferredKeys) { if (vehicleInfo.hasOwnProperty(key)) { outputHTML += `<tr><td><strong>${key}</strong></td><td>${formatValue(vehicleInfo[key])}</td></tr>`; } }   outputHTML += '</table>'; document.getElementById('output').innerHTML = outputHTML; }   function formatValue(value) { if (Array.isArray(value)) { return value.length > 0 ? `<ul>${value.map(item => `<li>${JSON.stringify(item)}</li>`).join('')}</ul>` : '[]'; } else if (typeof value === 'object' && value !== null) { return `<pre>${JSON.stringify(value, null, 2)}</pre>`; } else { return value !== null && value !== undefined ? value.toString() : 'N/A'; } } </script>   </body> </html>

 

Hey @AGibs-2017​,

 

I won't have time to look through that whole script, but I think I can point you in the right direction. Immediate location can be gotten through DeviceStatusInfo (including speed, direction, ect) and for Odometer, you need to do a Get for StatusData and specify a Diagnostic by doing a DiagnosticSearch and the Diagnostic ID is DiagnosticOdometerId. Hope that helps!

Still have questions?