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.
What's the general workflow for issuing commands? I'd assume it's:
  1. Login
  2. Get bearer token
  3. Cache token until it expires
  4. Get Vehicle ID
  5. Wake up vehicle - Loop with small delay until status changes to "online"
  6. Get status / issue commands
I've noticed that certain status calls like Driving and Position and commands like HVAC On will fail unless the car is awake. However, those calls will wake the car without having to issue the wake vehicle command. Therefore, is the wake up vehicle command necessary? Is it okay to just loop-with-delay-on-failure those commands that need the vehicle to be awake?
 
I didn't think that the Tim Dorr docs were being updated anymore. Good to know. But the command is supposed to be" https://owner-api.teslamotors.com/api/1/vehicles/vehicle_id/command/trunk_open" with the parameters vehicle_id and which_trunk. But where do you put the which_trunk parameter in the call?

According to the link I posted, it would be:

https://owner-api.teslamotors.com/api/1/vehicles/555555/command/trunk_open?which_trunk=rear

Where the 555555 gets replaced with the real vehicle ID. I've never tried it.
 
Can anybody else confirm this for me?

Sending a POST request to /api/1/users/keys with the following JSON payload:
Code:
{"public_key":"some gibberish"}

Should break the mobile app so that it can't load vehicle anymore and just says "Server Error". Forcing you to sign in/out again.
 
As of V9, the Model 3's are now populating a charge_state attribute called "est_battery_range". Before V9, this field was always empty...I suspect S/X have had these populated already. But now that I'm seeing this new data, I tried (unsuccessfully) to find in the documentation the detailed difference between these 3 attributes:
  • battery_range // rated miles
  • est_battery_range // range estimated from recent driving
  • ideal_battery_range // ideal miles
I'm confused particularly because battery_range and ideal_battery_range are IDENTICAL to two decimal places after 10K miles on my Model 3. Any insight beyond the documented comments above would be welcome!
 
I'm confused particularly because battery_range and ideal_battery_range are IDENTICAL to two decimal places after 10K miles on my Model 3

Does the model 3 (in-car display) allow you to switch between "rated range" (EPA) and "ideal range"? (also known as "typical range" (EPA) and "rated range" (NEDC) in Europe/Australia etc) like the Model S and X do?

They use different efficiency values (200Wh/km and 160Wh/km on my model S) so give different values in the car & via the API.

In this image "Ideal" corresponds to "Typical" in the car.

VTrange.png
 
Does the model 3 (in-car display) allow you to switch between "rated range" (EPA) and "ideal range"? (also known as "typical range" (EPA) and "rated range" (NEDC) in Europe/Australia etc) like the Model S and X do?

They use different efficiency values (200Wh/km and 160Wh/km on my model S) so give different values in the car & via the API.

In this image "Ideal" corresponds to "Typical" in the car.

View attachment 344821
No, I don't think so. The only setting that I am aware of is percent battery vs miles.
 
No pressure!

Last app update I dug into was 3.5.0 and it contained the new message center endpoints. These are important updates/notifications designated for your Tesla account, nothing too fancy.

Looks like 3.6.0 has a few more endpoints here:
  • Media Player
    • Toggle Playback
    • Previous/Next Track
    • Previous/Next Favorite
    • Volume Up/Down
  • Schedule / Cancel Software Update

  • Navigation Request
I can dig into the technical details on these here soon, but they're all pretty straight forward.

Are the new endpoints documented somewhere? I am looking for the format of software updates and nav request specifically.
 
  • Like
Reactions: SG57
Anyway to check for an available update via API? I seem to never be around my phone in the late evenings but rather on tablets and laptops. I would like to automatically send an email to myself if an update is available.
The update is available message the phone gets is via GCM push notification.

If you dont want to register your computer as a device for push notifications the only way I can think to work around this is to compare your cars firmware version to a known higher version from ev-fw.com or something
 
@ACDriveMotor & @dpskipper & @insaneoctane , tagging you three as you've all asked for details on the new APIs, so here ya go.

-

Navigation Request

Endpoint: api/1/vehicles/{id}/command/navigation_request
Type: POST

Request Body:
The request body is expected to have a type, locale, timestamp, and a 'value' containing a small bundle of extras shared to the app.
Code:
{
    "type": "share_ext_content_raw",
    "value": {
        "android.intent.ACTION": "android.intent.action.SEND",
        "android.intent.TYPE": "text\/plain",
        "android.intent.extra.SUBJECT": "Splash Down",
        "android.intent.extra.TEXT": "Splash Down\n11127 E Mission Ave, Spokane Valley, WA 99206\n(509) 464-9541\n\nhttps:\/\/goo.gl\/maps\/YiWSQFd4R9B2"
    },
    "locale": "en-US",
    "timestamp_ms": "1538858755621"
}
The bundle of extras varies depending on the content shared with the app so is hard to explain. Here's psuedo-code of my app's exact replication of the official Android app's logic. This took a bit to reverse engineer fully and accurately but rejoice, it's all there.
Code:
request.value.action = intent.getAction();
request.value.type = intent.getType();
request.value.scheme = intent.getScheme();
request.value.data = intent.getDataString();

if (Intent.ACTION_SEND.equals(request.value.action) && request.value.type != null) {
    request.value.subject = intent.getStringExtra(Intent.EXTRA_SUBJECT);
    request.value.text = intent.getStringExtra(Intent.EXTRA_TEXT);

    if (request.value.type.equals(ContactsContract.Contacts.CONTENT_VCARD_TYPE))
        request.value.stream = {
            first_name = "###",
            last_name = "###",
            org_name = "###",
            phone_numbers = [ { type = "###", phone_number = "###" }, ... ],
            email_addresses = [ { type = "###", email_address = "###"  }, ... ],
            postal_addresses = [ { type = "###", address_string = "###", city = "###", state = "###", country = "###", postal_code = "###"  }, ... ]
        }
}

Response: Typical response for a vehicle command, but you'll get an error "unsupported_input" if Tesla's servers can't determine a location to navigate to from your value in the request body.

-

Software Update Controls

  • Schedule Software Update

    Endpoint:
    api/1/vehicles/{id}/command/schedule_software_update

    Type: POST
    Request Body:
    Code:
    { "offset_sec" : 120 }
    Where offset_sec is how many seconds in the future when to schedule the software update, use 0 to install now.

  • Cancel Software Update

    Endpoint:
    api/1/vehicles/{id}/command/cancel_software_update
    Type: POST

-

Media Controls

All of these have no request body, pretty basic. You will get an error user_not_present if the main display in the car is off and you attempt to use any of these commands.
  • Toggle Playback
    Endpoint:
    api/1/vehicles/{id}/command/media_toggle_playback
    Type: POST

  • Next Track
    Endpoint: api/1/vehicles/{id}/command/media_next_track
    Type: POST

  • Previous Track
    Endpoint: api/1/vehicles/{id}/command/media_prev_track
    Type: POST

  • Next Favorite
    Endpoint: api/1/vehicles/{id}/command/media_next_fav
    Type: POST

  • Previous Favorite
    Endpoint: api/1/vehicles/{id}/command/media_prev_fav
    Type: POST

  • Volume Up
    Endpoint: api/1/vehicles/{id}/command/media_volume_up
    Type: POST

  • Volume Down
    Endpoint:
    api/1/vehicles/{id}/command/media_volume_down
    Type: POST
-

Lastly, forgot to mention there are some new vehicle data properties related to the new APIs as well.

Code:
vehicle_config: {
    ...
  
    can_accept_navigation_requests: true/false,

    ...
}
Code:
vehicle_state: {
    ...
  
    media_state: { remote_control_enabled: true/false },

    software_update: {
        status: "available/scheduled/installing",  // or null,
        scheduled_time_ms: 123421342134, // timestamp in MS, or null
        expected_duration_sec: 2700,  // expected install time in sec, defaults to 2700 sec (45 min)
        warning_time_remaining_ms: 1000000  // time until install, useless seeing as we're given a scheduled time already
    },
}
 
Last edited: