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.
My token renewal started failing a few days ago with an "unsupported grant type" error. It turns out, the auth sequence has been simplified, as discussed here: Auth page goes 401 · Issue #548 · timdorr/tesla-api

You no longer exchange the bearer token for the access token, and instead just use the bearer token. (If following these, skip step 4.)

That also means that you need to renew every 8 hours, rather than every 45 days.
@markb1 - thanks for posting this here. My current token doesn't expire until Apr-11 and would have been scratching my head on what happened.

I'll admit I've read through the Auth page goes 401 · Issue #548 · timdorr/tesla-api discussion on github but am struggling to piece it all together. This is what I think I'm understanding. Does this jive with your knowledge?

My prior refresh token, generated several months ago, is now invalid and I will need to start over first time with the full login from Step 1.
Steps 1 to Step 3 remain unchanged.
I again need to save the refresh token from Step 3 as will use it later for periodic token refresh.
Everything up to this point is same as before.

NEW PART IS:

I now take the access token directly received in Step 3. No longer need to do Step 4 to exchange the access token for the bearer token.
This access token from Step 3 is what's used to initiate the session and for all the subsequent GET/POST calls.

I now need to take action every 8 hours to get new access token. That's opposed to every 45 days previously.
I think I'm tracking OK up to this point??

What's not real clear to me is exactly how the every 8 hour refresh process works versus the prior Step 5 and repeat of Step 4.
Instead, do I understand correct that I simply do:

POST on https://auth.tesla.com/oauth2/v3/token
with the data body
{
"grant_type": "refresh_token",
"client_id": "ownerapi",
"refresh_token": "eyJrefresh", .... //this token is from Step 3 in the documentation
"scope": "openid email offline_access"
}

This returns a new access token, but does not return a new refresh token. Instead the original refresh token from Step 3 remains valid for a yet to be determined time (in perpetuity or someone resets account passwork? Doesn't seem anyone has cleanly confirmed this).

The new access token received form this refresh step is again valid for 8 hour.

So do you agree I've waded through all this correctly? I appreciate your coaching before I go and and redo my base login to remove step 4 and revise my refresh process. I'm always hesitant about potentially invalidating my current token/session, leaving me without a functioning logger, when I start tinkering with the lower level access token portion of my code. I'll admit the whole oauth, resp get/post part of this is a bit of black magic to me; being a guy whose coding knowledge dates to FORTRAN77, I'm much more capable at the application layer/logic level of what I do with the data than I am at the lower API access layer.

Thanks in advance. Paul, aka, PCMc
 
@markb1 - thanks for posting this here. My current token doesn't expire until Apr-11 and would have been scratching my head on what happened.

I'll admit I've read through the Auth page goes 401 · Issue #548 · timdorr/tesla-api discussion on github but am struggling to piece it all together. This is what I think I'm understanding. Does this jive with your knowledge?

My prior refresh token, generated several months ago, is now invalid and I will need to start over first time with the full login from Step 1.

I did not have to start over with step 1. I was still able to use my last refresh token from step 3 to do step 5. The refresh token seem to live for quite a long time, so even if your bearer token has expired, you can still renew.

Steps 1 to Step 3 remain unchanged.
I again need to save the refresh token from Step 3 as will use it later for periodic token refresh.
Everything up to this point is same as before.

NEW PART IS:

I now take the access token directly received in Step 3. No longer need to do Step 4 to exchange the access token for the bearer token.
This access token from Step 3 is what's used to initiate the session and for all the subsequent GET/POST calls.

I now need to take action every 8 hours to get new access token. That's opposed to every 45 days previously.
I think I'm tracking OK up to this point??

Yes, that's correct.

What's not real clear to me is exactly how the every 8 hour refresh process works versus the prior Step 5 and repeat of Step 4.
Instead, do I understand correct that I simply do:

POST on https://auth.tesla.com/oauth2/v3/token
with the data body
{
"grant_type": "refresh_token",
"client_id": "ownerapi",
"refresh_token": "eyJrefresh", .... //this token is from Step 3 in the documentation
"scope": "openid email offline_access"
}

This returns a new access token, but does not return a new refresh token. Instead the original refresh token from Step 3 remains valid for a yet to be determined time (in perpetuity or someone resets account passwork? Doesn't seem anyone has cleanly confirmed this).

The refresh step above returns a refresh token. It's generally the same refresh token as the last refresh, but it could change at some point.

The new access token received form this refresh step is again valid for 8 hour.

So do you agree I've waded through all this correctly? I appreciate your coaching before I go and and redo my base login to remove step 4 and revise my refresh process. I'm always hesitant about potentially invalidating my current token/session, leaving me without a functioning logger, when I start tinkering with the lower level access token portion of my code. I'll admit the whole oauth, resp get/post part of this is a bit of black magic to me; being a guy whose coding knowledge dates to FORTRAN77, I'm much more capable at the application layer/logic level of what I do with the data than I am at the lower API access layer.

Thanks in advance. Paul, aka, PCMc

Yes, you seem to have it correct, except for the two things that I pointed out above. Just hold on to your refresh token, and you should be able to recover if something goes wrong. My script makes backups every time it writes the token to a file, so if it does for some reason overwrite a good token with a bad token, I still have a good backup for recovery.
 
  • Like
Reactions: goRt
Yes, you seem to have it correct, except for the two things that I pointed out above. Just hold on to your refresh token, and you should be able to recover if something goes wrong. My script makes backups every time it writes the token to a file, so if it does for some reason overwrite a good token with a bad token, I still have a good backup for recovery.
@markb1 - Thanks for the confirmation. I did see the comment in the github thread about refresh token does not seems to change, but setting code up as if it's going to change is right approach even though noone appears to see that happening. I also save off the prior token file each time as well as saving the Step3 and Step5 responses each time. Figured between all of those I had most all the combinations covered if anything did go wrong and I had to try and back up a step.

Now I just need to think through how I want to restructure some of my code given the refresh process will be a multi time per day event versus previously every 45 days then start testing.
 
  • Like
Reactions: markb1
OMG thank you for this thread on the change on auth process. I have a program for charging my Model S on spare solar capacity (using standard wall charger) and I couldn't figure out why I was suddenly getting the error invalid_grant_type. Now it's back to working and I should be able to code around the lifecycle changes.
 
  • Like
Reactions: markb1
I've started watching the response status code value a little more closely now that the refresh token process changed about 6 weeks ago. I understand:
200 is OK, GET/POST was successful​
401 code indicates unauthorized and generally an indication of invalid token.​
408 indicates a timeout, typical what I see when my car (MCU2) is asleep​

What's a 503 mean? I know the definition is a service unavailable. I ran into this a couple times yesterday in data a logged over about a 400 mile / 8 hour long trip. One case it immediately proceeded (within ~120 sec) of when my token was set to expire, but my token refresh and new following GET response 150 sec later was successful. The other couple times it was during active driving, generally pulling data at about 10 sec intervals. Is this an indication that server reacting to me pulling too much/too frequent data, or just temporary server unable to respond condition which I shouldn't worry about.

Thanks again for all the help those of you much more savvy on API REST protocol given this novice.
Paul.
 
Anyone run into NotFound issues after changing the Auth process? So I am sending post/get exactly as before, just using the token from step 3 insted of 4. But it now gives me a NotFound error. Did the end points change? URL change? Anyone know?

EDIT: Totally noob error from my side, I was using the wrong car ID. It seems to have changed.
 
Last edited:
Hi everyone ... two questions.

First, is there a way I can trigger a reset of my MCU via API call? I'm pretty certain the answer is no, but just thought I'd ask the many on here that are way smarter on this than I.

Second, I'm trying to figure out how I could pull the charging history as now visible through the Tesla app. I've been looking at the endpoints file posted on Tim Dorr's github page ( Endpoints File - Tesla JSON API (Unofficial) ) but haven't been able to figure out which of the calls might give me this data. I see some for charging history, but these appear to possibly in the powerwall section and when I try using them I'm getting 200 status response but the json response is empty. Anyone have any experience pulling the charging history stats that might be able to point me in the correct direction??

As always, thanks for all the help from this group.
Paul.
 
Hi everyone ... two questions.

First, is there a way I can trigger a reset of my MCU via API call? I'm pretty certain the answer is no, but just thought I'd ask the many on here that are way smarter on this than I.

Second, I'm trying to figure out how I could pull the charging history as now visible through the Tesla app. I've been looking at the endpoints file posted on Tim Dorr's github page ( Endpoints File - Tesla JSON API (Unofficial) ) but haven't been able to figure out which of the calls might give me this data. I see some for charging history, but these appear to possibly in the powerwall section and when I try using them I'm getting 200 status response but the json response is empty. Anyone have any experience pulling the charging history stats that might be able to point me in the correct direction??

As always, thanks for all the help from this group.
Paul.
On #1, it’s definitely not documented so you’d have to reengineer.

For #2, I recommend one of the available data log capturing tools like Teslamate. The data capture is already implemented into a relational database.
 
On #1, it’s definitely not documented so you’d have to reengineer.

For #2, I recommend one of the available data log capturing tools like Teslamate. The data capture is already implemented into a relational database.
I already have a fully functioning data logging program that I've written myself that captures all my driving and charging stats and also automates recharging of my car while I'm oversees on assignment for multiple months at a time. I prefer to keep all my data locally as well as login tokens locally on my own laptop and do not want to use tools which I do not have total control over.
 
  • Like
Reactions: JDOhio
I'm trying to figure out how I could pull the charging history as now visible through the Tesla app.
If you wanna be able to pull the currently displayed charging history from the Tesla App you can just copy the code in the Menu.py or GUI.py examples on Tim's TeslaPy GitHub. The call returns the JSON data and his code shows a couple ways of visualizing it, the GUI one looks very similar to the one the phone app shows.

Screen Shot 2022-07-31 at 11.23.39 AM.png
 
If you wanna be able to pull the currently displayed charging history from the Tesla App you can just copy the code in the Menu.py or GUI.py examples on Tim's TeslaPy GitHub. The call returns the JSON data and his code shows a couple ways of visualizing it, the GUI one looks very similar to the one the phone app shows.

View attachment 835072
@Randy Spencer - Thanks! I'll have to spend more time digesting Tim's code to figure it out.

One of the key things I have spotted is what appears to possibly be an error in the documentation on this endpoints page I was referencing: tesla-api/env_ownerapi_endpoints.json at master · timdorr/tesla-api It shows the charge_history as a POST but the endpoints code in the TeslaPy GitHub link you provided shows it as a GET call. The fact I was seeing it as a POST call was confusing and seemed odd to me, and now when I quickly tried it with a GET call I do get a valid 200 response status.

Now I just need to figure out what the format of the data is that it returns and how to extract what I want. What I found with a quick trial call to my car is what looks like an empty return. Last time I charged was 31 days ago, which I think is all the data it buffers. I'll need to decide if I force my car to charge just to get some data, versus I wait roughly ~2 weeks when my SOC should hig my recharge trigger (my logger automates recharging between SOC endpoints of 51% and 80%; I've chosen to follow that approach so BMS actually gets to see a range of SOC for the roughly 3 months at a time that I'm away from it. It may not matter, but this mirrors better my driving/charging habits when I'm back at home base).
 
  • Like
Reactions: israndy
@Randy Spencer - Thanks! I'll have to spend more time digesting Tim's code to figure it out.

One of the key things I have spotted is what appears to possibly be an error in the documentation on this endpoints page I was referencing: tesla-api/env_ownerapi_endpoints.json at master · timdorr/tesla-api It shows the charge_history as a POST but the endpoints code in the TeslaPy GitHub link you provided shows it as a GET call. The fact I was seeing it as a POST call was confusing and seemed odd to me, and now when I quickly tried it with a GET call I do get a valid 200 response status.

Now I just need to figure out what the format of the data is that it returns and how to extract what I want. What I found with a quick trial call to my car is what looks like an empty return. Last time I charged was 31 days ago, which I think is all the data it buffers. I'll need to decide if I force my car to charge just to get some data, versus I wait roughly ~2 weeks when my SOC should hig my recharge trigger (my logger automates recharging between SOC endpoints of 51% and 80%; I've chosen to follow that approach so BMS actually gets to see a range of SOC for the roughly 3 months at a time that I'm away from it. It may not matter, but this mirrors better my driving/charging habits when I'm back at home base).
If you are using Python’s asyncio then carson may be of interest.
 
Hmmm... It's cute, and I am using AsyncIO, but I am using it with a TPLink Library, all my Tesla interaction are with TeslaPy. I did spawn the whole Tesla part of my app off as a separate task, but I fail to see what advantage Carson has over TeslaPy. At least with the TPLink devices I can send a message to ALL of them and I don't have to wait for the first response to return before sending the second one, it takes a loop talking to 16 devices from 15 seconds to 1 second to have them all run asynchronously. If I had a parking lot full of Teslas (I'd be a happy man) it might be faster...
 
New question ... any way to tell via the API if there's a NAV update in process?

I've just had my car twice in the past 3 weeks decide to stay awake and not sleep. When this happens I see my parasitic energy consumption go up 5 to 10x. First time it happened I was able to get my daughter to go check the car, no signs of HVAC/battery cooling running, but the MCU was locked up, screens would not come alive. Scroll wheel reboot of the car fixed that and it went back to 'normal' behavior for last 13 days.

As of 9 hours ago it again seems to be staying awake all the time, just like the first incident. Unfortunately none of my family are in the area of my car at the moment to go and do a reset of the MCU again.

I've seen some people post about issues of recent NAV updates hanging. Wondering if that might be happening to me. Unfortunately I cannot see anything in the vehicle_data response that gives me any clue why the car would suddenly not be wanting to sleep, but stay awake all the time.
 
My understanding is the https://www.teslaapi.io site was the precursor to and has been superseded by the Introduction - Tesla JSON API (Unofficial) site. If you look at the teslaapi.io site you'll see it's not been updated with revised OAuth2 login process that was rolled out last year.

I've just gone through the https://teslaapi.dev site and it appears to be someone that's put their own API wrapper around Tesla's API. They refer to their system as Smartcar, so what they document is how you can ping their system for certain items. They turn around and then ping Tesla directly to return to you the few pieces of data that their calls are to provide. Some of this appears to be set up so someone using their system could write an application to work with multiple types of vehicles and not have to worry about the differences in the API for each unique manufacturer. Some of their calls, like read_engine_oil, clearly have nothing to do with a Tesla. While they document the calls to their API, I find nothing in their document which actually shows the Tesla native API calls. That's understandable as what they are trying to do is get you to buy their manufacture/platform agnostic developer kit.

Appreciate the suggestions, but don't see anything in these that give me anything more than the timdorr site which I've always viewed as the official 'unofficial' reference doc for Tesla's API.
Thanks for pointing in the right direction to the latest Tesla API documentation. Does anyone know if the data for the Virtual Power Plant Beta in CA that launched at the end of June is exposed? I'm not seeing it in any documentation. I've been tracking the program manually, but I need an automated solution long term: Tesla's Virtual Power Plant Tracker — Lastbulb
 
Another question. Anyone using the set_charge_limit endpoint? If so, have you started having problems with it over the past month?

I implemented an automated charging function in my logger that uses this command to reset the charge limit to trigger my car to recharge. That's been working great for the past year, but suddenly around first of the month my code quite working. I've been trying to troubleshoot and am seeing I consistently get a 406 status code response to the set_charge_limit command

I've looked at Tim Dorr's github site and do not see any updates to his endpoints file to suggest that the API call may have changed, but have not come up with any good reason why this is not working. Anyone else using this end point, found they've recently needed to make any changes to their code, and could help point me in the right direction????

Thanks as always.
Paul.
 
My streaming client seems to have started rejecting my token. Can anyone provide any tips?

The message I'm sending is:

Code:
{
    msg_type: 'data:subscribe_oauth',
    token: 'eyJh...',
    value: 'speed,odometer,soc,elevation,est_heading,est_lat,est_lng,power,shift_state,range,est_range,heading',
    tag: 'yyyyy'
}

("eyJh..." is the same token I'm sending to the REST API, and that works fine.)

Response is:
Code:
{
    msg_type: 'data:error',
    tag: 'yyyy',
    value: 'Can\'t validate token. ',
    error_type: 'client_error'
}

This used to work!
 
My streaming client seems to have started rejecting my token. Can anyone provide any tips?

The message I'm sending is:

Code:
{
    msg_type: 'data:subscribe_oauth',
    token: 'eyJh...',
    value: 'speed,odometer,soc,elevation,est_heading,est_lat,est_lng,power,shift_state,range,est_range,heading',
    tag: 'yyyyy'
}

("eyJh..." is the same token I'm sending to the REST API, and that works fine.)

Response is:
Code:
{
    msg_type: 'data:error',
    tag: 'yyyy',
    value: 'Can\'t validate token. ',
    error_type: 'client_error'
}

This used to work!

It started working again with no changes. Go figure!
 
  • Like
Reactions: zoomer0056
Delete if this is in a bad place.

Trying to get the charging data from the tesla site. Is there any workflow for api that would work well (we have multiple cars). I was doing this through browser automation but recently it seems that after you login to Tesla you just get a blank page.
 
Delete if this is in a bad place.

Trying to get the charging data from the tesla site. Is there any workflow for api that would work well (we have multiple cars). I was doing this through browser automation but recently it seems that after you login to Tesla you just get a blank page.
I would recommend taking a look at one of the existing solutions like TeslaMate. You can either use it to see how they are pulling the data (we have two Teslas and it pulls both of them just fine) or even just use it to pull the data and source it from there. TeslaMate uses a Postgres SQL database so it‘s easy to access the data from there once it is pulled.
 
  • Like
Reactions: KArnold