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.
I managed to get the vehicle list. I'm not going to post Tesla's OAuth secrets, so don't ask. But here's everything else.

First, you need to get the bearer token. To do this, you need to post a JSON object to https://owner-api.teslamotors.com/oauth/token

(You will need to fill in the empty strings below.)

Code:
{
   "grant_type" : "password",
   "client_id" : "",
   "client_secret" : "",
   "email" : "",
   "password" : ""
}

That will return a JSON object containing the bearer token. That must be put in an HTTP header like this:

Code:
Authorization: Bearer 1234abcd

(1234abcd is the bearer token, but in practice, this will be a much longer hexadecimal number.)

Simply get https://owner-api.teslamotors.com/api/1/vehicles using the above header, and a JSON object will be returned with the vehicle list.

Works for me too. Agreed, that they didn't obfuscate this at all.
 
To be pedantic, I think they did do *something* to obfuscate them. You need to know how to unpack and decompile the file, which is not even made obvious to Android developers (although any developer other than a "script kiddie" knows how to do it). If they wanted us to have it and use it, they would document how to do so. It's clear they don't want us to use it, because they are not issuing us our own private keys. The only way to get it to work is to use the key that is meant for the mobile app. It is a terrible practice to use someone else's key.

My opinion remains that they may want to eventually allow other apps to have access, but it will be a long time.

Of course I am more interested in access to the center screen because I have many ideas about applications to run on there.
 
There were several instances of correspondence between TM and the programmers here. IIRC, @hans got temporarily blocked for spamming the API. Tesla contacted him and asked him to check his program but did not ask him to stop. Nor did they imply he was abusing his privileges.
 
There were several instances of correspondence between TM and the programmers here. IIRC, @hans got temporarily blocked for spamming the API. Tesla contacted him and asked him to check his program but did not ask him to stop. Nor did they imply he was abusing his privileges.

I did get blocked and I made attempts to contact TM about it but I did not correspond with anyone at Tesla. Several times I have made efforts to contact Tesla specifically about the telemetry systems but each time I get nothing but crickets.
 
Quick searched turned up this post in the VT thread. Perhaps this is what I was thinking of but I got the wrong user.

I use VT pretty continuously and have not had that problem. I did get turned off temporarily earlier in the development process when a bug caused a large number of requests to the Tesla servers before I shut it off. I was contacted by Tesla about it via email the same day.
 
Yup, I was turned off when I accidentally pounded their servers. I got an email from Tesla IT. I apologized profusely and took steps to ensure it wouldn't happen again (rate limiter on the rest API). I have had no official contact from Tesla asking me to stop using their service, nor have I been given any indication that they officially condone it.
 
This is great. Works like a charm. The only thing that confused me was "To do this, you need to post a JSON object".
Afer a bit of trial and error, I realized that it is a regular http post with the fields set, not really a json object. Now all I need is my own set of client ids and secrets.

The fact that they have actually included a "DEV" id, secret and url in the code that they MUST know we will read might suggests that they plan to do at least some kind of opening of the API.
 
Strange. I could not get it to work as a json-object. I am using php and curl, and need to submit them as standard httppost query fields.
Did you name the json-object anything in the post request?

Here's my curl command line:

Code:
curl -v -H "Content-Type: application/json" -d '{"grant_type" : "password", "client_id" : "xxxxxx", "client_secret" : "xxxxxx", "email" : "xxxxxx", "password" : "xxxxxx"}' https://owner-api.teslamotors.com/oauth/token
 
Are you sure you're not using the old (portal) site, as opposed to the new (owner-api) site?

Pretty certain.

Just for reference, here is (part) of my PHP-code:

PHP:
define('PROD_OAUTH_CLIENT_ID', "XXXXXXXXXXXXXXXXXXXXXXX");
define('PROD_OAUTH_CLIENT_SECRET', "XXXXXXXXXXXXXXXXXXXXXXXX");
define('HOST_PROD_API', "owner-api.teslamotors.com");

$request = array(
                'grant_type' => 'password',
                'client_id' => PROD_OAUTH_CLIENT_ID,
                'client_secret' => PROD_OAUTH_CLIENT_SECRET,
                'email' => em@il,
                'password' => password,
);
$postdata = http_build_query($request);
$url =  'https://' . HOST_PROD_API . "/oauth/token";

$rest_ch = curl_init();
curl_setopt($rest_ch, CURLOPT_URL, $url);
curl_setopt($rest_ch, CURLOPT_POSTFIELDS, $postdata);
curl_exec($rest_ch);
 
Pretty certain.

Just for reference, here is (part) of my PHP-code:

PHP:
define('PROD_OAUTH_CLIENT_ID', "XXXXXXXXXXXXXXXXXXXXXXX");
define('PROD_OAUTH_CLIENT_SECRET', "XXXXXXXXXXXXXXXXXXXXXXXX");
define('HOST_PROD_API', "owner-api.teslamotors.com");

$request = array(
                'grant_type' => 'password',
                'client_id' => PROD_OAUTH_CLIENT_ID,
                'client_secret' => PROD_OAUTH_CLIENT_SECRET,
                'email' => em@il,
                'password' => password,
);
$postdata = http_build_query($request);
$url =  'https://' . HOST_PROD_API . "/oauth/token";

$rest_ch = curl_init();
curl_setopt($rest_ch, CURLOPT_URL, $url);
curl_setopt($rest_ch, CURLOPT_POSTFIELDS, $postdata);
curl_exec($rest_ch);

I'm not a PHP guy, but I don't think you're code is achieving what you want. You need to post a body of mime type application/json whose value is literally a string of the form: {"grant_type" : "password", "client_id" : "xxxxxx", "client_secret" : "xxxxxx", "email" : "xxxxxx", "password" : "xxxxxx"}. It should not be encoded as a query string.

 
Oh, the PHP-code I posted works fine, so it's not really a problem now.

But it might be the content-type that was the problem when I first tested with a json-object.

It looks like you can then do either a regular http-post with a query string, OR a http-post with content-type application/json and the json-encoded object.
 
Any particular reason you are defining constants here instead of using variables?

I have not really given it that much thought, but I use them in more than one function, so they would either need to be global, or defined multiple places or passed around as arguments to various functions, and they are pretty constant :wink: (no need to change them throughout the application), so I just think it makes sense to define them once and for all in the top of the file.

- - - Updated - - -

Has anyone found out how the notification for new software updates work yet?
Is the info available in the REST api?
My car is still on 5.12, so I obviously don't have it. My best guess is that it is part of "vehicle_state"?
 
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.
 
Last edited: