
Security News
AGENTS.md Gains Traction as an Open Format for AI Coding Agents
AGENTS.md is a fast-growing open format giving AI coding agents a shared, predictable way to understand project setup, style, and workflows.
node-tesla-api
Advanced tools
A modern NodeJS implementation of the (unofficial) Tesla API.
Under development: features outlined below may not be final.
npm i node-tesla-api
I'm only focussing on the oauth
, vehicles
, and logs
parts of the Tesla API for now.
The API follows the commands outlined in the (unofficial) Tesla API, but uses camelCase instead of underscores.
You'll need to have access to a Tesla, and have a valid Tesla username and password to make use of this API.
Please feel free to use my Tesla referral code if you buy a Tesla - we both get some free charging that way.
My code is: david60377
const { oauth, vehicles } = require('node-tesla-api')
const sleep = async delay => new Promise(resolve => setTimeout(resolve, delay))
const wakeCar = async ({ id, token, retry = 0, maxRetries = 3 }) => {
if (retry === maxRetries) return
const {
response: { state }
} = await vehicles.vehicle({ id, token })
if (state === 'online') return
await vehicles.wake({ id, token })
await sleep(DELAY)
// try again
await wakeCar({ id, token, retry: retry + 1, maxRetries })
}
const start = async (email, password) => {
const { accessToken: token } = await oauth.token({
email,
password,
// These values are an open secret.
// See https://tesla-api.timdorr.com for the latest values.
clientSecret: 'get-me-from-pastebin',
clientId: 'also-get-me-from-pastebin'
})
console.log('token', token)
const { response: cars } = await vehicles.list({ token })
console.log('cars', cars)
const { idS: id } = cars.find(car => car.displayName === 'Terry')
await wakeCar({ id, token })
const { response: state } = await vehicles.vehicleState({ id, token })
console.log('state', JSON.stringify(state, null, 2))
}
start('your-tesla@account.email', 'Y0uRP@55w0rd').catch(err => {
console.error(err)
})
The API is broken down into
oauth
— you provide your username and password and get back a token
.vehicles
- using the token
you interact with your vehicleslogs
- using the token
you can perform various diagnostics, but only if the token has the correct embedded permissions.oauth
Controls how you obtain, refresh and revoke tokens.
const { oauth } = require('node-tesla-api')
token
Returns the accessToken
you will need to invoke the other api functions.
const { accessToken, refreshToken, tokenType, createdAt, expiresIn } = await oauth.token({
email: 'your-tesla@account.email',
password: 'your-password',
clientSecret: 'get-me-from-pastebin',
clientId: 'also-get-me-from-pastebin'
})
timdorr
: post-oauth-token-grant_type-password
teslaapi
: get-access-token
refresh
Returns a refreshed accessToken
. Use this if your original token has expired.
const { accessToken, refreshToken, tokenType, createdAt, expiresIn } = await oauth.refresh({
refreshToken: 'the refresh token you got back from the `token` function',
clientSecret: 'get-me-from-pastebin',
clientId: 'also-get-me-from-pastebin'
})
timdorr
: post-oauth-token-grant_type-refresh_token
teslaapi
: get-access-token
revoke
Revokes an accessToken
. Use this to log the user out.
await oauth.revoke({ token: 'the access token you got back from the `token` function' })
timdorr
: Not mentionedteslaapi
: revoke-access-token
vehicles
Using the accessToken issued above you use the vehicles
functions to interact with your car.
const { vehicles } = require('node-tesla-api')
list
Get a list of your vehicles.
const { response: cars } = await vehicles.list({ token })
const {
id, // don't use this integer version as the number overflows
vehicleId, // a number, unsure what it's used for
vin, // a string
displayName, // a string
optionCodes, // a string of comma separated codes
color, // not sure - usually null
accessType, // e.g. 'OWNER'
tokens, // an array of tokens
state, // "online" if the car is online
inService, // boolean
idS, // use this string version of the id instead of id
calendarEnabled, // boolean
apiVersion, // a number, e.g. 10 right now.
backseatToken, // unsure what this is
backseatTokenUpdatedAt // timestamp or null
vehicleConfig, // e.g. null
} = cars[0]
timdorr
: get-api-1-vehicles
teslaapi
: vehicles
vehicle
Get the basic details of a specific vehicle.
// using the `idS` field returned from `vehicles.list`, not the `id`, or `vehicleId`.
// and the token from `oauth.token`
const {
id, // don't use this integer version as the number overflows
vehicleId, // a number, unsure what it's used for
vin, // a string
displayName, // a string
optionCodes, // a string of comma separated codes
color, // not sure - usually null
accessType, // e.g. 'OWNER'
tokens, // an array of two tokens
state, // "online" if the car is online
inService, // boolean
idS, // use this string version of the id instead of id
calendarEnabled, // boolean
apiVersion, // a number, e.g. 10 right now.
backseatToken, // unsure what this is
backseatTokenUpdatedAt // timestamp or null
vehicleConfig, // e.g. null
} = await vehicles.vehicle({ id, token })
timdorr
: get-api-1-vehicles-id
teslaapi
: vehicle
The keen observer will note that this is the same data as returned in the vehicle list response.
wake
When you first get the details of your car, you need to check the state
to see if it's 'online'
or not.
If the car's state
is 'asleep'
or otherwise not 'online'
then you need to wake it up before you can do anything with it.
Note You might also want to check to see if the car is inService
(true
or false
) if you are going to do something like move it, or start it.
To wake up the car you send it a wake
command as follows:
await vehicles.wake({ id, token })
Now just because you told the car to wake, doesn't mean that the car will actually wake up. Sometimes your car can go into a deep-sleep mode, or it might even be off, or disconnected from the network.
You need to keep checking the state
and reissuing the wake
command until either the car really wakes up, or decide to stop trying.
// Check the `state` of the car recursively, trying three times to wake it up.
const wakeCar = async ({ id, token, retry = 0, maxRetries = 3 }) => {
if (retry === maxRetries) return
const {
response: { state }
} = await vehicles.vehicle({ id, token })
if (state === 'online') return
await vehicles.wake({ id, token })
await sleep(DELAY)
// try again
await wakeCar({ id, token, retry: retry + 1, maxRetries })
}
Then you can just call
await wakeCar({ id, token })
ToDo: Compose a high-level API that simplifies the use of this low-level API wrapper. (See issues/28)
timdorr
: post-api-1-vehicles-id-wake_up
teslaapi
: wake-up
vehicleData
Now you know how to wake your car, let's take a look at the full set of car data.
const {
response: {
id, // don't use this.
userId,
vehicleId, // or this
vin,
displayName, // TODO: Is this ever different to `vehicleName`?
optionCodes,
color,
accessType, // e.g. "OWNER" TODO: find out these values.
tokens, // array of two small strings
state, // should be "online",
inService, // boolean,
idS, // use this instead of `id`
calendarEnabled, // boolean
apiVersion, // e.g. 10
backseatToken, // TODO: find out what this is for
backseatTokenUpdatedAt, // TODO: find out what this is for
vehicleConfig: {
canAcceptNavigationRequests, // boolean
canActuateTrunks, // boolean
carSpecialType, // e.g. "base" TODO: find out these values.
carType, // mine is a "model3" TODO: find out these values.
chargePortType, // mine is "CCS" TODO: find out these values.
eceRestrictions, // boolean
euVehicle, // boolean (e.g. true but I am in AU)
exteriorColor, // mine is "MidnightSilver" TODO: find out these values.
hasAirSuspension, // boolean
hasLudicrousMode, // boolean
keyVersion, // e.g. 2
motorizedChargePort, // boolean
plg, // boolean (e.g. false)
rearSeatHeaters, // e.g. 1 - I have rear seat heaters
rearSeatType, // e.g. null
rhd, // right hand drive? (e.g. true)
roofColor, // e.g. "Glass" TODO: find out these values.
seatType, // e.g. null
spoilerType, // e.g. "None"
sunRoofInstalled, // e.g. null,
thirdRowSeats, // e.g. "<invalid>", TODO: find out these values.
timestamp: vcTimestamp, // unix epoch timestamp
useRangeBadging, // e.g. true,
wheelType, // e.g. "Pinwheel18" TODO: find out these values.
},
chargeState: {
batteryHeaterOn, // boolean
batteryLevel, // integer percentage
batteryRange, // floating point value using imperial units (miles)
chargeCurrentRequest, // how many amps the car wants (e.g. 8)
chargeCurrentRequestMax, // how many amps the car can have (e.g. 8)
chargeEnableRequest, // boolean
chargeEnergyAdded, // floating point number (e.g 10.15)
chargeLimitSoc, // integer percentage (e.g 94)
chargeLimitSocMax, // integer percentage (e.g 100)
chargeLimitSocMin, // integer percentage (e.g 50)
chargeLimitSocStd, // integer percentage (e.g 90)
chargeMilesAddedIdeal, // floating point number (e.g 41.5)
chargeMilesAddedRated, // floating point number (e.g 41.5)
chargePortColdWeatherMode, // boolean
chargePortDoorOpen, // boolean
chargePortLatch, // e.g "Engaged" TODO: find out these values.
chargeRate, // a number TODO: check these values when charging the car
chargeToMaxRange, // boolean
chargerActualCurrent, // a number e.g 0 TODO: check these values when charging the car
chargerPhases, // 1 = single, 3 = three TODO: is there such a thing as 2 phase power?
chargerPilotCurrent, // something else measured in amps (e.g. 8)
chargerPower, // a number (TODO: check these values when charging the car)
chargerVoltage, // an integer (e.g 2)
chargingState, // e.g. "Stopped" TODO: find out these values.
connChargeCable, // e.g. "IEC" TODO: find out these values.
estBatteryRange, // floating point value using imperial units (miles) (e.g. 273.36)
fastChargerBrand, // e.g. "<invalid>"
fastChargerPresent, // boolean
fastChargerType, // e.g. "MCSingleWireCAN" TODO: find out these values.
idealBatteryRange,// floating point value using imperial units (miles) (e.g. 281.16)
managedChargingActive, // boolean
managedChargingStartTime, // a timestamp or null
managedChargingUserCanceled, // boolean
maxRangeChargeCounter, // TODO: maybe how the car knows to warn you about overcharging.
minutesToFullCharge, // integer count (e.g 0)
notEnoughPowerToHeat: null, // e.g. null TODO: find out these values.
scheduledChargingPending, // boolean
scheduledChargingStartTime, // unix epoch timestamp
timeToFullCharge, // integer count (e.g 0)
timestamp: chsTimestamp,// unix epoch timestamp
tripCharging, // boolean
usableBatteryLevel, // integer percentage (e.g 93)
userChargeEnableRequest // e.g. null TODO: find out these values.
},
climateState: {
batteryHeater, // boolean
batteryHeaterNoPower, // e.g. null TODO: find out these values.
climateKeeperMode, // e.g "off" TODO: find out these values.
defrostMode, // e.g. 0. TODO: find out these values.
driverTempSetting, // e.g. 22 (uses GUI setting `guiTemperatureUnits`)
fanStatus, // e.g. 0. TODO: find out these values.
insideTemp, // e.g. 16.2 (uses GUI setting `guiTemperatureUnits`)
isAutoConditioningOn, // boolean
isClimateOn, // boolean
isFrontDefrosterOn, // boolean
isPreconditioning, // boolean
isRearDefrosterOn, // boolean
leftTempDirection, // e.g. 326 - range is 0 to 360 presumably.
maxAvailTemp, // e.g. 28 (uses GUI setting `guiTemperatureUnits`)
minAvailTemp, // e.g. 15 (uses GUI setting `guiTemperatureUnits`)
outsideTemp, // e.g. 15.5 (uses GUI setting `guiTemperatureUnits`)
passengerTempSetting, // e.g. 22 (uses GUI setting `guiTemperatureUnits`)
remoteHeaterControlEnabled, // boolean
rightTempDirection // e.g. 326 - range is 0 to 360 presumably.
seatHeaterLeft, // 0 = off, else 1, 2, or 3
seatHeaterRearCenter, // 0 = off, else 1, 2, or 3
seatHeaterRearLeft, // 0 = off, else 1, 2, or 3
seatHeaterRearRight, // 0 = off, else 1, 2, or 3
seatHeaterRight, // 0 = off, else 1, 2, or 3
sideMirrorHeaters, // boolean
timestamp: clsTimestamp, // unix epoch timestamp again
wiperBladeHeater: false
},
driveState: {
gpsAsOf, // unix epoch timestamp
heading, // e.g. 340 0 to 360 integer degrees
latitude, // e.g. -30.336537
longitude, // e.g. 141.145116,
nativeLatitude, // e.g. -30.336537 TODO: what's this all about?
nativeLocationSupported, // e.g. 1 TODO: what's this all about?
nativeLongitude, // e.g. 141.145116 TODO: what's this all about?
nativeType, // e.g. "wgs" TODO: get acceptable values for this
power, // e.g. 0 TODO: get acceptable values for this
shiftState, // e.g. null TODO: get acceptable values for this
speed, // e.g. null TODO: find out the units for this but my guess is imperial units (mph)
timestamp: dsTimestamp, // e.g. 1600552117638
},
guiSettings: {
gui24HourTime, // boolean
guiChargeRateUnits, // e.g. "kW" TODO: get acceptable values for this
guiDistanceUnits, // e.g. "km/hr" TODO: get acceptable values for this
guiRangeDisplay, // e.g. "Rated" TODO: get acceptable values for this
guiTemperatureUnits, // e.g. "C" TODO: get acceptable values for this
showRangeUnits, // boolean
timestamp: gsTimestamp, // unix epoch timestamp
},
vehicleState: {
apiVersion, // e.g. 10,
autoparkStateV2, // e.g. "standby" TODO: get acceptable values for this
autoparkStyle, // e.g. "standard", "dead_man" TODO: get acceptable values for this
calendarSupported, // boolean
carVersion, // e.g. "2020.36.10 010e3e5a2863",
centerDisplayState, // e.g. 0 = off, 2 = on, 3 = charging screen, 7 = sentry mode, 8 = dog mode
df, // e.g. 0 (driver-side front tyre/someone sitting?) TODO: get acceptable values
dr, // e.g. 0 (driver-side rear tyre/someone sitting?) TODO: get acceptable values
fdWindow, // e.g. 0 (front driver-side window) TODO: get acceptable values
fpWindow, // e.g. 0 (front passenger-side window) TODO: get acceptable values
ft, // e.g. 0 (front trunk) TODO get acceptable values
isUserPresent, // boolean
lastAutoparkError, // e.g. "no_error",
locked, // boolean
mediaState: {
remoteControlEnabled // boolean
},
notificationsSupported, // boolean
odometer, // e.g 16686.68661 always in imperial units (miles)
parsedCalendarSupported, // boolean
pf, // e.g. 0 (passenger-side front tyre/someone sitting?) TODO: get acceptable values
pr, // e.g. 0 (passenger-side rear tyre/someone sitting?) TODO: get acceptable values
rdWindow, // e.g. 0 (rear driver-side window) TODO: get acceptable values
remoteStart, // boolean
remoteStartEnabled, // boolean
remoteStartSupported, // boolean
rpWindow, // e.g. 0 TODO no idea what this is (driver-side front)
rt, // e.g. 0 (rear trunk) TODO get acceptable values
sentryMode, // boolean
sentryModeAvailable, // boolean
smartSummonAvailable, // boolean
softwareUpdate: {
downloadPerc, // 0 if not downloading
expectedDurationSec, // e.g. 2700 but no update downloading
installPerc, // 1 if not installing
status, // e.g. ''
version, // e.g. ''
},
speedLimitMode: {
active, // boolean
currentLimitMph, // always in imperial units
maxLimitMph, // always in imperial units
minLimitMph, // always in imperial units
pinCodeSet, // boolean
},
summonStandbyModeEnabled, // boolean
timestamp, // numeric unix epoch time
valetMode, // boolean
valetPinNeeded, // boolean
vehicleName // TODO: is this different to the displayName of the vehicle?
}
} = await vehicles.vehicleState({ id, token })
timdorr
: get-api-1-vehicles-id-vehicle_data
teslaapi
: vehicle-data
vehicleState
The car's current state (This is the same as the vehicleState
field in the response to vehicles.vehicleData()
)
const {
response: {
apiVersion, // e.g. 10
autoparkStateV2, // 'standby' or ? (also seeing `autoparkStateV3` in docs)
autoparkStyle, // e.g. 'standard', 'dead_man'
calendarSupported, // boolean
carVersion, // e.g. '2020.36.10 010e3e5a2863'
centreDisplayState, // e.g. 0 = off, 2 = on, 3 = charging screen, 7 = sentry mode, 8 = dog mode
df, // driver-side front door 0 = closed, non-zero is open.
dr, // driver-side rear door 0 = closed, non-zero is open.
fdWindow, // e.g. 0 = closed, non-zero is open (front driver-side window) TODO is it a %?
fpWindow, // e.g. 0 = closed, non-zero is open (front passenger-side window) TODO is it a %?
ft, // front trunk (aka frunk) 0 = closed, non-zero is open.
isUserPresent, // boolean
lastAutoparkError, // 'no_error'
locked, // boolean
mediaState: { // see also the `mediaState` command
remoteControlEnabled, // e.g. true. boolean
},
notificationsSupported, // boolean
odometer, // NOTE always in miles not metric
parsedCalendarSupported, // boolean
pf, // passenger-side front door 0 = closed, non-zero is open.
pr, // passenger-side rear door 0 = closed, non-zero is open.
rdWindow, // e.g. 0 (rear driver-side window)
remoteStart, // boolean
remoteStartEnabled, // boolean
remoteStartSupported, // boolean
rpWindow, // e.g. 0 (rear passenger-side window)
rt, // rear trunk (aka boot) 0 = closed, non-zero is open.
sentryMode, // boolean
sentryModeAvailable, // boolean
smartSummonAvailable, // boolean
softwareUpdate: {
downloadPerc, // 0 if not downloading
expectedDurationSec, // e.g. 2700 but no update downloading
installPerc, // 1 if not installing
status, // e.g. ''
version, // e.g. ''
},
speedLimitMode; {
active, // boolean
currentLimitMph, // always in imperial units
maxLimitMph, // always in imperial units
minLimitMph, // always in imperial units
pinCodeSet, // boolean
},
summonStandbyModeEnabled, // boolean
timestamp, // numeric unix epoch time
valetMode, // boolean
valetPinNeeded, // boolean
vehicleName // TODO: is this different to the displayName of the vehicle?
}
} = await vehicles.vehicleState({ id, token })
timdorr
: get-api-1-vehicles-id-data_request-vehicle_state
teslaapi
: not listedvehicleConfig
The car's configuration (This is the same as the vehicleConfig
field in the response to vehicles.vehicleData()
)
const {
response: {
canAcceptNavigationRequests, // boolean
canActuateTrunks, // boolean
carSpecialType, // e.g. "base" TODO: find out these values.
carType, // mine is a "model3" TODO: find out these values.
chargePortType, // mine is "CCS" TODO: find out these values.
eceRestrictions, // boolean
euVehicle, // boolean (e.g. true but I am in AU)
exteriorColor, // mine is "MidnightSilver" TODO: find out these values.
hasAirSuspension, // boolean
hasLudicrousMode, // boolean
keyVersion, // e.g. 2
motorizedChargePort, // boolean
plg, // boolean (e.g. false)
rearSeatHeaters, // e.g. 1 - I have rear seat heaters
rearSeatType, // e.g. null
rhd, // right hand drive? (e.g. true)
roofColor, // e.g. "Glass" TODO: find out these values.
seatType, // e.g. null
spoilerType, // e.g. "None"
sunRoofInstalled, // e.g. null,
thirdRowSeats, // e.g. "<invalid>", TODO: find out these values.
timestamp, // unix epoch timestamp
useRangeBadging, // e.g. true,
wheelType // e.g. "Pinwheel18" TODO: find out these values.
}
} = await vehicles.vehicleConfig({ id, token })
timdorr
: get-api-1-vehicles-id-data_request-vehicle_config
teslaapi
: not listedchargeState
The car's current charge state. (This is the same as the chargeState
field in the response to vehicles.vehicleData()
)
const {
response: {
batteryHeaterOn, // boolean
batteryLevel, // integer percentage
batteryRange, // floating point value using imperial units (miles)
chargeCurrentRequest, // how many amps the car wants (e.g. 8)
chargeCurrentRequestMax, // how many amps the car can have (e.g. 8)
chargeEnableRequest, // boolean
chargeEnergyAdded, // floating point number (e.g 10.15)
chargeLimitSoc, // integer percentage (e.g 94)
chargeLimitSocMax, // integer percentage (e.g 100)
chargeLimitSocMin, // integer percentage (e.g 50)
chargeLimitSocStd, // integer percentage (e.g 90)
chargeMilesAddedIdeal, // floating point number (e.g 41.5)
chargeMilesAddedRated, // floating point number (e.g 41.5)
chargePortColdWeatherMode, // boolean
chargePortDoorOpen, // boolean
chargePortLatch, // e.g "Engaged" TODO: find out these values.
chargeRate, // a number (TODO: check these values when charging the car)
chargeToMaxRange, // boolean
chargerActualCurrent, // a number (TODO: check these values when charging the car)
chargerPhases, // 1 = single, 3 = three TODO: is there such a thing as 2 phase power?
chargerPilotCurrent, // something else measured in amps (e.g. 8)
chargerPower, // a number (TODO: check these values when charging the car)
chargerVoltage, // an integer (e.g 2)
chargingState, // e.g. "Stopped" TODO: find out these values.
connChargeCable, // e.g. "IEC" TODO: find out these values.
estBatteryRange, // floating point value using imperial units (miles) (e.g. 273.36)
fastChargerBrand, // e.g. "<invalid>"
fastChargerPresent, // boolean
fastChargerType, // e.g. "MCSingleWireCAN" TODO: find out these values.
idealBatteryRange, // floating point value using imperial units (miles) (e.g. 281.16)
managedChargingActive, // boolean
managedChargingStartTime, // a timestamp or null
managedChargingUserCanceled, // boolean
maxRangeChargeCounter, // TODO: maybe how the car knows to warn you about overcharging.
minutesToFullCharge, // integer count (e.g 0)
notEnoughPowerToHeat: null, // e.g. null TODO: find out these values.
scheduledChargingPending, // boolean
scheduledChargingStartTime, // unix epoch timestamp
timeToFullCharge, // integer count (e.g 0)
timestamp, // unix epoch timestamp
tripCharging, // boolean
usableBatteryLevel, // integer percentage (e.g 93)
userChargeEnableRequest // e.g. null TODO: find out these values.
}
} = await vehicles.chargeState({ id, token })
timdorr
: get-api-1-vehicles-id-data_request-charge_state
teslaapi
: 'charge-state'climateState
The car's current climate state. (This is the same as the climateState
field in the response to vehicles.vehicleData()
)
const {
response: {
batteryHeater, // boolean
batteryHeaterNoPower, // e.g. null TODO: find out these values.
climateKeeperMode, // e.g "off" TODO: find out these values.
defrostMode, // e.g. 0. TODO: find out these values.
driverTempSetting, // e.g. 22 (uses GUI setting `guiTemperatureUnits`)
fanStatus, // e.g. 0. TODO: find out these values.
insideTemp, // e.g. 16.2 (uses GUI setting `guiTemperatureUnits`)
isAutoConditioningOn, // boolean
isClimateOn, // boolean
isFrontDefrosterOn, // boolean
isPreconditioning, // boolean
isRearDefrosterOn, // boolean
leftTempDirection, // e.g. 326 - range is 0 to 360 presumably.
maxAvailTemp, // e.g. 28 (uses GUI setting `guiTemperatureUnits`)
minAvailTemp, // e.g. 15 (uses GUI setting `guiTemperatureUnits`)
outsideTemp, // e.g. 15.5 (uses GUI setting `guiTemperatureUnits`)
passengerTempSetting, // e.g. 22 (uses GUI setting `guiTemperatureUnits`)
remoteHeaterControlEnabled, // boolean
rightTempDirection // e.g. 326 - range is 0 to 360 presumably.
seatHeaterLeft, // 0 = off, else 1, 2, or 3
seatHeaterRearCenter, // 0 = off, else 1, 2, or 3
seatHeaterRearLeft, // 0 = off, else 1, 2, or 3
seatHeaterRearRight, // 0 = off, else 1, 2, or 3
seatHeaterRight, // 0 = off, else 1, 2, or 3
sideMirrorHeaters, // boolean
timestamp, // unix epoch timestamp again
wiperBladeHeater: false
}
} = await vehicles.climateState({ id, token })
timdorr
: get-api-1-vehicles-id-data_request-climate_state
teslaapi
: 'climate-state'driveState
The car's current location and driving state. (This is the same as the driveState
field in the response to vehicles.vehicleData()
)
const {
response: {
gpsAsOf, // unix epoch timestamp
heading, // e.g. 340 0 to 360 integer degrees
latitude, // e.g. -30.336537
longitude, // e.g. 141.145116,
nativeLatitude, // e.g. -30.336537 TODO: what's this all about?
nativeLocationSupported, // e.g. 1 TODO: what's this all about?
nativeLongitude, // e.g. 141.145116 TODO: what's this all about?
nativeType, // e.g. "wgs" TODO: get acceptable values for this
power, // e.g. 0 TODO: get acceptable values for this
shiftState, // e.g. null TODO: get acceptable values for this
speed, // e.g. null TODO: find out the units for this but my guess is imperial units (mph)
timestamp // e.g. 1600552117638
}
} = await vehicles.driveState({ id, token })
timdorr
: get-api-1-vehicles-id-data_request-drive_state
teslaapi
: 'drive-state'guiSettings
Localisation settings including units for distances, temperatures, and charge, as well as the clock type. (This is the same as the guiSettings
field in the response to vehicles.vehicleData()
)
const {
response: {
gui24HourTime, // boolean
guiChargeRateUnits, // e.g. "kW" TODO: get acceptable values for this
guiDistanceUnits, // e.g. "km/hr" TODO: get acceptable values for this
guiRangeDisplay, // e.g. "Rated" TODO: get acceptable values for this
guiTemperatureUnits, // e.g. "C" TODO: get acceptable values for this
showRangeUnits, // boolean
timestamp: gsTimestamp // unix epoch timestamp
}
} = await vehicles.guiSettings({ id, token })
timdorr
: get-api-1-vehicles-id-data_request-gui_settings
teslaapi
: 'gui-settings'mobileEnabled
Is mobile access enabled?
const { response: mobileEnabled } = await vehicles.mobileEnabled({ id, token })
timdorr
: get-api-1-vehicles-id-mobile_enabled
teslaapi
: 'mobile-enabled'serviceData
Current servicing data.
const {
response: {
// unknown fields - maybe only of use when the car is booked in for service.
...serviceData
}
} = await vehicles.serviceData({ id, token })
timdorr
: not mentionedteslaapi
: 'vehicle-service-data'nearbyChargingSites
Lists Tesla-operated charging stations near to the car.
const {
response: {
congestionSyncTimeUtcSecs, // integer number of seconds
destinationCharging: [
{
location: {
lat: dcLat, // e.g. -35.312247
long: dcLong, // e.g. 149.133236
},
name: dcName, // e.g. "Hotel Realm Canberra"
type: dcType, // e.g. "destination"
distanceMiles: dcDist // e.g. 11.807002
}
],
superchargers: [
{
location: {
lat: scLat, // e.g. -35.294304,
long: scLong, // e.g. 149.190322
},
name: scName, // e.g. "Canberra, ACT"
type: scType, // e.g. "supercharger"
distanceMiles: scDist, // e.g. 11.87435
availableStalls, // e.g. 5
totalStalls, // e.g. 6
siteClosed // boolean
}
],
"timestamp" // unix epoch timestamp
}
} = await vehicles.nearbyChargingSites({ id, token })
timdorr
: get-api-1-vehicles-id-nearby_charging_sites
teslaapi
: not mentionedupcomingCalendarEntries
If you have allowed your car to share your calendar then this will list your upcoming calendar entries.
const {
response: { result, reason }
} = await vehicles.upcomingCalendarEntries({ id, token })
timdorr
: calendar
teslaapi
: upcoming-calendar-entries
It's great to be able to get data from your car, but what about making it do things? We already saw the wake
command above.
Commands all return a response with a result
(boolean) and, if the result
is false
, a reason
string.
honkHorn
Beeps the car's horn. toot!
const {
response: { result, reason }
} = await vehicles.honkHorn({ id, token })
timdorr
: post-api-1-vehicles-id-command-honk_horn
teslaapi
: honk-horn
flashLights
Flashes the car's headlights.
const {
response: { result, reason }
} = await vehicles.flashLights({ id, token })
timdorr
: post-api-1-vehicles-id-command-flash_lights
teslaapi
: flash-lights
autoConditioningStart
Start the car's climate control system. It will use the temperature and set-warming options you've previously set. Repeated calls to this will not cause an error, though obviously if the car's climate control system is on it's not going to turn on again.
const {
response: { result, reason }
} = await vehicles.autoConditioningStart({ id, token })
timdorr
: post-api-1-vehicles-id-command-auto_conditioning_start
teslaapi
: start-hvac-system
autoConditioningStop
Stop the car's climate control system.
Note: If you call this when the car's climate control system is already off you will get a ECONNABORTED
error rather than a response of { result: false, reason: 'some reason' }
.
const {
response: { result, reason }
} = await vehicles.autoConditioningStop({ id, token })
timdorr
: post-api-1-vehicles-id-command-auto_conditioning_stop
teslaapi
: stop-hvac-system
setTemps
Sets the temperature for the car's climate control system.
The request requires the parameter driverTemp
. It also accepts a passengerTemp
but only the driverTemp
is actually used right now. This may change in the future.
driverTemp
and passengerTemp
are always in Metric (°C
) no matter what you have set in guiSettings
.const driverTemp = 23.4 // degrees celsius.
const {
response: { result, reason }
} = await vehicles.setTemps({ id, token, driverTemp })
timdorr
: post-api-1-vehicles-id-command-auto_conditioning_stop
teslaapi
: stop-hvac-system
the api claims that the params get passed in as query params but this is not actually true.setPreconditoningMax
Toggles the climate controls between Max Defrost and the previous setting.
You can pass on: true
, or 'on: false' to this multiple times, without error.
const {
response: { result, reason }
} = await vehicles.setPreconditioningMax({ id, token, on: true })
timdorr
: post-api-1-vehicles-id-command-set_preconditioning_max
teslaapi
: not listedsetSeatHeater
Sets the seat heater level for the nominated seat.
Note You must have already turned the car's climate system on first with autoConditioningStart
for this to work. If you don't you'll get an error. Also in testing I found this API call quite prone to timeout errors.
Value | Seat |
---|---|
0 | front left |
1 | front right |
2 | rear left |
3 | rear center |
4 | rear right |
const {
response: { result, reason }
} = await vehicles.setSeatHeater({ id, token, heater: 0, level: 1 })
timdorr
: post-api-1-vehicles-id-command-remote_seat_heater_request
teslaapi
: not listedsetSteeringWheelHeater
Turns the steering wheel heater on or off.
Note You must have already turned the car's climate system on first with autoConditioningStart
for this to work. If you don't you'll get an error.
Also Note I am not sure that my Model 3 even has a steering wheel heater so all I get from this is a timeout error.
const {
response: { result, reason }
} = await vehicles.setSteeringWheelHeater({ id, token, on: true }) // or on: false
timdorr
: post-api-1-vehicles-id-command-remote_steering_wheel_heater_request
teslaapi
: not listedmediaTogglePlayback
Either toggles the media between playing
and paused
, or if the car is tuned to a radio station, this mutes or un-mutes the audio.
Note You, or someone, must have turned the car on and be sitting in it for this to work. If you don't you'll get a 'user_not_present' error.
const {
response: { result, reason }
} = await vehicles.mediaTogglePlayback({ id, token })
timdorr
: post-api-1-vehicles-id-command-media_toggle_playback
teslaapi
: not listedmediaNextTrack
Skips the media to the next track, unless the car is tuned to a radio station.
Note You, or someone, must have turned the car on and be sitting in it for this to work. If you don't you'll get a 'user_not_present' error.
const {
response: { result, reason }
} = await vehicles.mediaNextTrack({ id, token })
timdorr
: post-api-1-vehicles-id-command-media_next_track
teslaapi
: not listedmediaPrevTrack
Skips the media to the previous track, unless the car is tuned to a radio station.
Note You, or someone, must have turned the car on and be sitting in it for this to work. If you don't you'll get a 'user_not_present' error.
const {
response: { result, reason }
} = await vehicles.mediaPrevTrack({ id, token })
timdorr
: post-api-1-vehicles-id-command-media_prev_track
teslaapi
: not listedmediaNextFav
Skips the media to the next 'favourite', however that is defined, e.g if the car is tuned to a radio station, it switches to the next radio station in your favourites.
Note You, or someone, must have turned the car on and be sitting in it for this to work. If you don't you'll get a 'user_not_present' error.
const {
response: { result, reason }
} = await vehicles.mediaNextFav({ id, token })
timdorr
: post-api-1-vehicles-id-command-media_next_track
teslaapi
: not listedmediaPrevFav
Skips the media to the previous 'favourite', however that is defined, e.g if the car is tuned to a radio station, it switches to the previous radio station in your favourites.
Note You, or someone, must have turned the car on and be sitting in it for this to work. If you don't you'll get a 'user_not_present' error.
const {
response: { result, reason }
} = await vehicles.mediaPrevFav({ id, token })
timdorr
: post-api-1-vehicles-id-command-media_prev_track
teslaapi
: not listedmediaVolumeUp
Turns the volume up.
Note You, or someone, must have turned the car on and be sitting in it for this to work. If you don't you'll get a 'user_not_present' error.
const {
response: { result, reason }
} = await vehicles.mediaVolumeUp({ id, token })
timdorr
: post-api-1-vehicles-id-command-media_volume_up
teslaapi
: not listedmediaVolumeDown
Turns the volume down.
Note You, or someone, must have turned the car on and be sitting in it for this to work. If you don't you'll get a 'user_not_present' error.
const {
response: { result, reason }
} = await vehicles.mediaVolumeDown({ id, token })
timdorr
: post-api-1-vehicles-id-command-media_volume_down
teslaapi
: not listedshare
Share a video url, or navigation destination. If the car is in 'theatre mode' the url will launch the appropriate player. If the value
you send is a street address, then it will set the navigation system to navigate to that address.
If the car can't understand the value you send it will return an error.
const value = '1 Commonwealth Avenue, Yarralumla ACT 2600, Australia'
const {
response: { result, reason }
} = await vehicles.share({ id, token, value, locale: 'en-AU' }) // locale is optional, it will default to your OS's system locale.
timdorr
: post-api-1-vehicles-id-command-share
teslaapi
: not listedsetSentryMode
Turn sentry mode on or off.
const {
response: { result, reason }
} = await vehicles.setSentryMode({ id, token, on: true }) // or `on: false` for off.
timdorr
: post-api-1-vehicles-id-command-set_sentry_mode
teslaapi
: not listedactuateTrunk
Opens (or 'pops' depending on your hardware) the 'frunk' or boot.
const {
response: { result, reason }
} = await vehicles.actuateTrunk({ id, token, which: 'front' }) // for the 'frunk', or `which: 'rear'` for the boot.
timdorr
: post-api-1-vehicles-id-command-actuate_trunk
teslaapi
: not listedwindowControl
Lets you 'vent' or 'close' the car's windows.
Note to 'close' the windows you must also provide a gps location that's close to the car. You can get the car's current gps location from vehicles.driveState
. Alternatively you could issue a lock
command which will also close the windows if the car was not locked.
const {
response: { result, reason }
} = await vehicles.windowControl({ id, token, command: 'vent' })
or
const {
response: { result, reason }
} = await vehicles.windowControl({ id, token, command: 'close', lat: -35.297476, lon: 149.12579 })
timdorr
: post-api-1-vehicles-id-command-window_control
teslaapi
: not listedsunRoofControl
Lets you 'vent' or 'close' the car's sun roof if it has a sun roof.
const {
response: { result, reason }
} = await vehicles.sunRoofControl({ id, token, state: 'vent' })
timdorr
: post-api-1-vehicles-id-command-sun_roof_control
teslaapi
: not listedtriggerHomelink
Lets you trigger the HomeLink controller if it is connected.
Note You must also provide a gps location that's close to the homelink device.
const {
response: { result, reason }
} = await vehicles.triggerHomelink({ id, token, lat: -35.297476, lon: 149.12579 })
timdorr
: post-api-1-vehicles-id-command-trigger_homelink
teslaapi
: not listedscheduleSoftwareUpdate
If you have a pending software update, this command lets you schedule a time for the install to happen. If you do not provide an offset then it will attempt to install immediately.
If there is no software update available you'll get a result: false
and reason: update_not_available
.
const {
response: { result, reason }
} = await vehicles.scheduleSoftwareUpdate({ id, token })
or, to install in an hour:
const {
response: { result, reason }
} = await vehicles.scheduleSoftwareUpdate({ id, token, offset: 3600 }) // offset is in seconds
timdorr
: post-api-1-vehicles-id-command-schedule_software_update
teslaapi
: not listedcancelSoftwareUpdate
If you have a pending software update, and you've scheduled an installation time, then this lets you cancel that installation.
If there is no software update scheduled you'll get a result: false
and reason: no_update_scheduled
.
const {
response: { result, reason }
} = await vehicles.cancelSoftwareUpdate({ id, token })
timdorr
: post-api-1-vehicles-id-command-cancel_software_update
teslaapi
: not listedsetValetMode
Valet Mode limits the car's top speed to 110 Kilometres per hour and 80kW of acceleration power. It also disables Homelink, Bluetooth, and Wifi settings, as well as the ability to disable mobile access to the car.
It also hides your favourites, as well as your home, and work locations in navigation.
If you provide a password then anyone with that password, (a numeric PIN) can disable Valet Mode from the screen in the car. You can always disable Valet Mode from the API without a password however. It only applies to the person driving your car.
const {
response: { result, reason }
} = await vehicles.setValetMode({ id, token, on: true, password: 1234 })
timdorr
: post-api-1-vehicles-id-command-set_valet_mode
teslaapi
: set-valet-mode
resetValetPin
Clears the Valet Mode PIN
, meaning that once Valet Mode is disabled, you can enable it with or without a new PIN
.
const {
response: { result, reason }
} = await vehicles.resetValetPin({ id, token })
timdorr
: post-api-1-vehicles-id-command-reset_valet_pin
teslaapi
: reset-valet-pin
logs
Using the accessToken
issued above, if you have the appropriate 'entitlements' (defined by Tesla and embedded into the token Tesla give you) you can you use the logs
functions to perform diagnostics on your account. Use logs.getEntitlements
to check if you have the right permissions.
const { logs } = require('node-tesla-api')
getEntitlements
Does your token
allow you to perform diagnostics?
const {
response: { eligible } // eligible will be true or false
} = await logs.getEntitlements({ token })
timdorr
: not listedteslaapi
: logs/diagnostics#entitlements
getLogs
If you are eligible for logs you can get the account logs associated with your token. hint you probably are not eligible.
const {
response: { result, reason }
} = await logs.getLogs({ token })
timdorr
: not listedteslaapi
: logs/logs
sendEntitlements
It's hard to know what this does.
const {
response: { result, reason }
} = await logs.sendEntitlements({ token })
timdorr
: not listedteslaapi
: logs/diagnostics#send
branch | status | coverage | audit | notes |
---|---|---|---|---|
develop | work in progress | |||
main | latest stable release |
npm install
npm run lint
Note this will also run whenever you commit file changes.
npm run prettier
Note: this will also run whenever you commit file changes.
npm test
or with code coverage
npm run test:unit:cov
Please see the contributing notes.
FAQs
A modern NodeJS implementation of the (unofficial) Tesla API
The npm package node-tesla-api receives a total of 5 weekly downloads. As such, node-tesla-api popularity was classified as not popular.
We found that node-tesla-api demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
AGENTS.md is a fast-growing open format giving AI coding agents a shared, predictable way to understand project setup, style, and workflows.
Security News
/Research
Malicious npm package impersonates Nodemailer and drains wallets by hijacking crypto transactions across multiple blockchains.
Security News
This episode explores the hard problem of reachability analysis, from static analysis limits to handling dynamic languages and massive dependency trees.