2024.8 Tesla Fleet Integration (still) only one way

Im trying to add it manually (Tesla Fleet - Home Assistant), but I’m stuck here

Run this CURL request, replacing the variable values as specified in the notes below:

Replace LONG_GIBBERISH_ACCESS_TOKEN_STRING with the access token that you copied in the previous step.

I dont see anything like that in the second CURL request. Where do I put the access token I got in previous step?

curl --location 'https://fleet-api.prd.na.vn.cloud.tesla.com/api/1/partner_accounts' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer JSON_WEB_TOKEN' \
--data '{
    "domain": "my.domain.com"
}'```

Ok, done.

The instructions should change the

Replace LONG_GIBBERISH_ACCESS_TOKEN_STRING with the access token that you copied in the previous step.

for

Replace JSON_WEB_TOKEN with the access token that you copied in the previous step.

Thanks for this integration

Sure.

I assume you were able to create a key pair and created a developer application. Just follow “Hosting a Public/Private Key Pair” and “Setting up the Developer Application” from Tesla Fleet - Home Assistant

I also assume you’ve added the OAuth application credentials details to Home Assistant described in “Linking the Developer Application with Home Assistant”


Basic stuff first

Copy the private key to your Home Assistant, placing it at:

config/tesla_fleet.key


Unraid Containers

Install linuxserver’s nginx container (binhex-nginx dosnt work for reasons) and mgutt’s Nginx-Proxy-Manager-Official, NPM for short.

Both Contains need their own IP by setting Network Type to Custom br0 - in my case NPM got xx.5 and nginx xx.6


Router

On you’re Router you forward Port 443 for HTTPS and 80 for HTTP to the NPM Container. Also, make sure your domain points to you via DynDNS or something similar.
This means when you access your domain, everything is forwarded to NPM, which handles SSL encryption and routes traffic to the correct application based on the subdomain used.


Nginx-Proxy-Manager

Open NPM and add a Proxy Host.
To keep things scalable, I used a subdomain for the key - just in case I want to host more keys later.

  1. Add the domain name (e.g., sub.mydomain.com).
  2. Set the Scheme to http.
  3. Enter the IP of the nginx container.
  4. Keep the port as 80.

Next, go to the SSL Tab, select “Request a new SSL Certificate”, agree to the ToS, and save.

Switch to Advaanced Tab and add the following:

# Serve the Tesla public key file
location = /.well-known/appspecific/com.tesla.3p.public-key.pem {
    proxy_pass http://192.168.167.6:80;
}

# Reject everything else with a 403 (Forbidden)
location / {
    deny all;
}

This tells NPM to forward requests for the key to your nginx server and block everything else. Replace the IP with your nginx container’s actual IP.


Setup nginx

Now, we need to actually host the key itself.

  1. Go to the nginx config folder and create the required directories. Copy the key to this location:

appdata\nginx\www.well-known\appspecific\com.tesla.3p.public-key.pem

  1. Open the site configuration file:

\appdata\nginx\nginx\site-confs\default.conf

  1. Add the following block right after the existing / location:
    # Serve files from your app-specific directory
    location /.well-known/appspecific/ {
        root /config/www;
        autoindex off;
    }

Visiting: sub.mydomain.com/.well-known/appspecific/com.tesla.3p.public-key.pem should just downlaod the key. This means we are good here.


Scripts

Now to the script’s I posted. In order to link the keypair to your account and prove you’re the owner of the domain you have to first get a Partner Token and then use this Partner Token to register your domain where tesla validates the key is accessible.

Copy the first “GetPartnerToken” to a text Editor, add your Client-ID and Client Secret from the Tesla developer website and make sure you use the correct API based on your region. You may need to swap out fleet-api.ord.eu with fleet-api.ord.na or something based on https://developer.tesla.com/docs/fleet-api/getting-started/base-urls

I made this to run on Windows Powershell. Go to some folder as the scripts save the responses as .json (like the Partner Token) to the current folder. Open a Terminal/Powershell.

Paste in the GetPatnerToken you’ve edited and wait for stuff to happen. You maybe have to press enter once so the last line where it saves to the .json gets executed.
Do the same with the RegisterDomain. Edit in your domain, make sure the Region is correct and send it. It uses the Token from the saved .json.


Link key to Car

Go to https://www.tesla.com/_ak/sub.mydomain.com (replace with your domain of cause).
Scan the QR code. The Tesla App should open and ask whether you’d like to add the key. Add it, and that’s it.


Everything works?

Reload Tesla Fleet in Home Assistant. It should work


Hope its at least like 73% clear what to do.

3 Likes

Hello @Brett_Adams Thanks for your service, but I got some issues registering it n the Tesla dev-portal. It seems all fleetkey.cc-domains are somehow blocked for me? I’ve tried setting it up a couple of times with different instances. My public key is available directly, but the Tesla developer portal does not accept it as origin.

Thanks a lot for this extensive explenation. Love it!! Got everything up and running!

I’ve raised a support request with Tesla because they have moved the goal posts again.

3 Likes

does the number of entities exposed vary depending if the logged in user is the owner of the vehicle (main user) or other user?

First of all, thanks for the awesome work put into this extension!

I’ve followed the installation path on my setup, but I have an NGINX Proxy Manager in front of my HA (2025.1.2). My key is reachable through internet, as so is my HA.

The installation completed successfully (latest as I installed yesterday), but I am only able to view information, not send. Viewing is accurate and updates timely. The errors are:

  • Command failed: Unknown Key ID - when attempting to change charge to on/off
  • Failed to perform the action cover/close_cover. data must not be an empty byte string - when attempting to open/close charge port
    Other commands also generate similar issues.

Any hints on where I should explore to address this issue?

1 Like

to add to the above. i actually managed to get commands to start working and has worked for a few days but today it has stopped and shows the following error:


what does this mean?

The instructions on the integration installation page don’t explicitly state this but did you rename the created private key tesla-fleet.key and copy it to your HA config folder?

Yes, I did similarly. Instead of creating as public-key.pem, I set the output directly to the requested filename. This means instead of this:

openssl ecparam -name prime256v1 -genkey -noout -out private-key.pem
openssl ec -in private-key.pem -pubout -out public-key.pem
mv public-key.pem com.tesla.3p.public-key.pem

I did this:

openssl ecparam -name prime256v1 -genkey -noout -out com.tesla.3p.private-key.pem
openssl ec -in com.tesla.3p.private-key.pem -pubout -out com.tesla.3p.public-key.pem

Aside from that, everything was copy-pasted. I’m serving the public file via Nginx Proxy Manager in front of HA.

actually it seems this response only seems to come from the unlock charge cable button

I’m running HAOS and accessing my installation via the cloudflared add-on. I still have not yet figured out a simple way to serve https://my.domain.com/.well-known/appspecific/com.tesla.3p.public-key.pem behind cloudflare.

I’ve messed around with both the NGINX Home Assistant SSL proxy and the Nginx Proxy Manager and I haven’t yet figured out the correct configuration.

Looks like some people may have had some success with Tesla HTTP Proxy add-on, however that add-on is no longer maintained.

If anyone has any tips, they would be highly appreciated. Otherwise once I figure out how to get it working I will come back with the update.

I resisted for a while because of the cost, but I finally got Tessie and I have no regrets. It fits all my Tesla automation needs.

if you have a cloudflare account you can create a free page. create the folders .wellknown/appspecific on your pc and copy the public key to that folder. create a zip of the .wellknown folder and upload that to the free cloudfare page

Is the Tesla integration working on newer releases now? I am currently still on the 2024.12.5 version where is is working fine. After upgrading to a 2025 version I got the authentication error, and hade some problems getting it back up, so reverted back to 2024.12.5. Worked again, so I will leave it there for now.

Good I have the integration working again…
Created my app at Tesla, created my private/public keys… registered my domain via the app to my Tesla…
Added my private key on my HA /config folter, add the key on my domains webserver…

Reading from the Tesla works.
Sending commands like ‘Open charge Port’ or ‘Unlock port’ fails with " data must not be an empty byte string"…
Any idea?

Error details:

"File “/usr/local/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/ec.py”, line 178, in from_encoded_point
raise ValueError(“data must not be an empty byte string”)
ValueError: data must not be an empty byte string

OK: I hit the same issue ;-).
I cannot help…

I was facing a similar issue, so maybe my solution will help as well.
Documentation says to put the key in /config. I’m using the File editor add-on with HAOS and had to put the key directly in the parent directory, labeled homeassistant/ for it to work. Also reloaded the extension after making the change.

I ended up writing my own custom_component integration to serve the API key. It was actually very straight-forward to do and I didn’t have to mess around with nginx or cloudflared. Just put your API key in /config/www/.well-known/appspecific/com.tesla.3p.public-key.pem and this code will do the job:

from homeassistant.components.http import StaticPathConfig

async def async_setup(hass, config):
    static_dir = hass.config.path("www/.well-known")

    await hass.http.async_register_static_paths([
        StaticPathConfig(
            url_path="/.well-known",
            path=static_dir,
            cache_headers=True
        )
    ])

    return True

But now that I see the costs that I’m racking up using the Tesla API, I can see that maybe the Tessie account is better value, and then setup I can use the Tesse integration to get the data back to HA.

1 Like