Welcome to Tesla Motors Club
Discuss Tesla's Model S, Model 3, Model X, Model Y, Cybertruck, Roadster and More.
Register

Model S REST API

This site may earn commission on affiliate links.
Value of "expires in" for the "bearer".

I first thought it was milliseconds, as their other timestamps are given in ms, and that the bearer would expire in 7776 seconds - about 2 hours. However I have now successfully used the same bearer for more than 12 hours so I decided to do a few more calculations. It seems like the value of "expires in" is actually given in seconds - and 7776000 seconds is exactly 90 days so the value makes sense.

That agrees with the OAuth 2.0 spec. (Though calling OAuth 2.0 a spec is a bit generous, IMO, given that it leaves so many things unspecified.)
 
I'd like the communities' thoughts on the appropriate level of protection that should be afforded to the embedded information required to use Tesla's OAuth api.

There are a couple of options I can see:

  1. Don't use the new api. Use the old API as long as it is still supported and after that we're out of luck. Hope that Tesla creates a program in which they will grant developers keys.
  2. Start using the information, but don't store it in the clear. Use some key hiding technique that requires the same level of effort to circumvent as Tesla required (very little). Tesla didn't even require running a debugger, the info is present in clear text in the code. It would be easy to at least require a debugger to get at the data, but let's not kid ourselves, it's still very little work.
  3. Store the keys in the clear. I'm not comfortable with this even though, from a practical perspective, it's not very different from #2.

Are there other, better options?
 
I'd like the communities' thoughts on the appropriate level of protection that should be afforded to the embedded information required to use Tesla's OAuth api.

There are a couple of options I can see:

  1. Don't use the new api. Use the old API as long as it is still supported and after that we're out of luck. Hope that Tesla creates a program in which they will grant developers keys.
  2. Start using the information, but don't store it in the clear. Use some key hiding technique that requires the same level of effort to circumvent as Tesla required (very little). Tesla didn't even require running a debugger, the info is present in clear text in the code. It would be easy to at least require a debugger to get at the data, but let's not kid ourselves, it's still very little work.
  3. Store the keys in the clear. I'm not comfortable with this even though, from a practical perspective, it's not very different from #2.

Are there other, better options?

I am leaning toward #2 but going the extra mile beyond what Tesla did and storing the keys in ROT13 format ;-)
 
To be even safer, you should do that twice. ;-)

Back in the days of third-party disk compression, I once had a co-worker ask me if they could run "Stacker" twice, to get double the compression. I told them, why stop there? Keep running it until you get down to 2 bytes, you won't need a hard disk at all! I think they then realized why that wouldn't work... but I still explained to them the real reason.

In terms of the REST API, has anyone just asked Tesla for a developer API key and secret?
 
That's a can of worms that I wouldn't want to open. Could easily lead to us getting less access rather than more.

Tesla is just not ready to support third party developers. They know where to find us when the time comes.

Agreed.

I encrypted the data with AES, put the resulting bytes in the code, and then decrypt it at runtime. It's trivial to get the plaintext by putting a debugger on the code, but at least the values aren't sitting in the open as they are in the Tesla code. I'm using AES only because it's a convenient built-in cipher.
 
I haven't released anything yet, but if/when I do, I guess I'll just remove the keys from the code. As I write PHP there is no easy way to obscure them. Ofcourse I could encrypt them, but then the encryption key would need to be in plain text in the code instead, and that would not really help.
I could use some kind of php-obfuscator, to hide the decrypt-function but that just seems stupid, and anyone could just copy the obfuscated code and use it as is anyway.
 
Has anyone got a web service running that maps Tesla firmware version numbers into release numbers? For example, the service would say that v1.65.15 of the firmware corresponds to the 6.0 release. I know that I can get this information in human readable form from pages like this, but I'd like to be able to query this information programatically.
 
Last edited:
In the Android app there are both "prod" and "dev" client-id/client-secret.
None of these start with 8c or 81 so they probably used different ids and secrets for the two platforms. This is both a good sign - they obviously have code in place to handle multiple client ids, but it could also mean that they can revoke the keys we now use if they want to.
 
I haven't released anything yet, but if/when I do, I guess I'll just remove the keys from the code. As I write PHP there is no easy way to obscure them.

Which functions are supported by your app? I released a PHP/MySQL web client that's up on the wiki and github. Maybe we can join forces and you can incorporate my features into your code.

I decrypted and checked the iOS app and there are two id/secret combo's in there, could that be of any use? (one id starting with 8c , the second with 81)
Wonder if those are the same as in the Android app?

Ah, so on iOS it seems it is not as trivial to obtain these keys (no wonder I couldn't find them just poking around in iFile). I've downloaded the Android app as apparently it's in plain text.
 
Some more info copied from the iOS app:

.%@/api/1/vehicles/%@/command/charge_start
.%@/api/1/vehicles/%@/command/charge_stop
.%@/api/1/vehicles/%@/command/charge_port_door_open
.%@/api/1/vehicles/%@/command/charge_port_door_close
.%@/api/1/vehicles/%@/command/auto_conditioning_start
.%@/api/1/vehicles/%@/command/auto_conditioning_stop
.%@/api/1/vehicles/%@/command/door_lock
.%@/api/1/vehicles/%@/command/door_unlock
.%@/api/1/vehicles/%@/command/trunk_open
.%@/api/1/vehicles%@/command/sun_roof_control
.%@/api/1/vehicles/%@/command/sun_roof_control
.%@/api/1/vehicles/%@/wake_up
.%@/api/1/vehicles/%@/command/honk_horn
.%@/api/1/vehicles/%@/command/flash_lights
.%@/api/1/vehicles/%@/command/charge_standard
.%@/api/1/vehicles/%@/command/charge_max_range
.%@/api/1/vehicles/%@/command/front_defrost_on
.%@/api/1/vehicles/%@/command/front_defrost_off
.%@/api/1/vehicles/%@/command/rear_defrost_on
.%@/api/1/vehicles/%@/command/rear_defrost_off
.%@/api/1/vehicles/%@/subscription_preferences
.%@/api/1/vehicles/%@/command/remote_start_drive
.%@/api/1/vehicles/%@/data_request/drive_state
.%@/api/1/vehicles/%@/data_request/charge_state
.%@/api/1/vehicles/%@/mobile_enabled
.%@/api/1/vehicles/%@/data_request/gui_settings
.%@/stream/%@/?values=speed,odometer,soc,elevation,est_heading,est_lat,est_lng,power,shift_state
.%@/api/1/vehicles/%@/data_request/climate_state
.%@/api/1/vehicles/%@/data_request/vehicle_state
.%@/api/1/vehicles/%@
.%@/api/1/notification_preferences
.%@/api/1/vehicle_subscriptions.ios-production.waking.online.state.close.vent.open
.%@/api/1/vehicles/%@/command/set_temps.driver_temp.passenger_temp
.%@/api/1/vehicles/%@/command/set_charge_limit.percent
.%ld
.https://owner-api.teslamotors.com
.https://streaming.vn.teslamotors.com
.https://owner-api.dev.teslamotors.com
.CommandReply:%@.result.%@/oauth/token.%@/oauth/revoke
.%@/api/1/vehicles
.%@/users/change_password
.%@/api/1/vehicles/%@/command/upcoming_calendar_entries
.%@/api/1/notification_confirmations
.%@/api/1/log_uploads.displayName

Some things like rear_defrost are not known yet I think?
 
Some more info copied from the iOS app:
[omitted for brevity]​

Some things like rear_defrost are not known yet I think?

Yes, the defrost related commands are new. However, they do not appear in the Android app and when I issue a defrost related command, I get an invalid_command error. It's possible that I'm getting that error because my car is not yet on version 6, but it's the same error that is returned if I issue a nonsense command like xyzzy.

We'll need someone with version 6 on their car to give it a try to see if they are really valid or not. Perhaps they are a precursor of things to come.
 
Which functions are supported by your app? I released a PHP/MySQL web client that's up on the wiki and github. Maybe we can join forces and you can incorporate my features into your code.

I have divided my code in pieces. One is a kind of deamon - really just a php-cli-script - that constantly polls the rest and streaming APIs, and adds the data into a SQLite-database.
Then a couple of other scripts and webapps shows the data from the database in different ways.
That way I only have one active session to Teslas servers, but I can still display the info on several devices.
 
Just tested the defroster-commands, and I get "unknown command" even with a 6.0 car. But I use the Android app-id and secrets, so it _might_ be a possibility that they have rigged the API to allow different commands from different apps. It would make sense to disable IE. remote start from a web app, or filter out other commands to only certain apps.