Tesla Fleet API × Home Assistant
Deploying the official Tesla Fleet API into Home Assistant: key generation, public-key hosting on a Cloudflare Worker, application registration, vehicle pairing, and integration setup.
- Tesla Model Y
- Tesla Fleet API
- Cloudflare Worker
- Home Assistant

Overview
This document records the configuration used to integrate a Tesla Model Y with Home Assistant through the Tesla Fleet API, Tesla’s official third-party interface. It covers key generation, hosting the application’s public key, registering the application with Tesla, pairing the vehicle, and installing the Home Assistant integration. Each step cites the corresponding section of the official Tesla Fleet API documentation; see References.
Status
- Vehicle data and commands: in production.
- Fleet Telemetry (push streaming): not yet deployed. Design notes are in Fleet Telemetry (planned).
Scope — a single vehicle, a single Home Assistant instance, and one Cloudflare-hosted subdomain. Multi-vehicle and multi-tenant deployments are out of scope.
Background — why the Fleet API
Most Home Assistant integrations for Tesla vehicles use Tesla’s private owner API, the interface behind the official mobile app. That interface is unversioned and unsupported for third-party use: Tesla rate-limits and throttles it without notice, and poll-based integrations wake the vehicle on every request, drawing down the battery.
The Fleet API is the supported alternative. It requires more initial setup and provides:
- Scoped OAuth — the application receives only the permissions explicitly granted.
- Signed commands — vehicle commands are signed with the application’s private key and delivered through Tesla’s command endpoint.
- Fleet Telemetry — a push stream in which the vehicle sends data to a server, removing the need to poll.
Architecture
| Component | Role | Hosting |
|---|---|---|
| ECDSA P-256 key pair | Private key signs Vehicle Command requests; public key proves domain ownership | Private key on the Home Assistant host; public key embedded in the Worker |
| Cloudflare Worker | Serves the public key at the required well-known path; returns 404 elsewhere |
Cloudflare, free tier, dedicated subdomain |
| Fleet API application | Scoped OAuth client; source of the partner and user tokens | Tesla developer portal |
tesla_fleet integration |
OAuth, state retrieval, signed command delivery | Home Assistant (HACS custom component) |
| Fleet Telemetry endpoint | Push stream of vehicle fields over WebSocket | Not yet provisioned |
The private key is held on exactly one host — the Home Assistant instance — and is not committed to any repository. Everything else in the table is either public by construction or reproducible from configuration.
Prerequisites
- A Tesla account with multi-factor authentication enabled. MFA is required before an application can be registered.
- A vehicle associated with that account and controllable from the Tesla app. This deployment uses a Model Y.
- A domain managed by Cloudflare. Any subdomain is sufficient, e.g.
fleet.example.com. - Home Assistant with HACS installed; the integration is distributed as a custom component.
opensslon the host used for key generation.
Procedure
Step 1 — Generate the key pair
The Fleet API uses an ECDSA key pair on the NIST P-256 curve
(prime256v1 / secp256r1).
- The private key signs Vehicle Command requests. It must remain secret.
- The public key is published on the application’s domain so Tesla can verify domain control.
Generate both on one host:
openssl ecparam -name prime256v1 -genkey -noout -out private-key.pem
openssl ec -in private-key.pem -pubout -out public-key.pem
Placement:
private-key.pem— on the host that will sign requests. In this deployment that is the Home Assistant instance, which stores it as an integration secret. It is not committed to any repository, private or otherwise.public-key.pem— embedded in the Cloudflare Worker in Step 2. It is public by design.
The openssl invocations above are taken from [1], “Step 3 — Generate a
Public/Private Key Pair.”
Step 2 — Publish the public key
Tesla requires the public key to be served at a fixed path on the application’s domain:
https://<your-domain>/.well-known/appspecific/com.tesla.3p.public-key.pem
This endpoint is a continuous requirement, not a one-time registration check. Tesla treats control of the HTTPS endpoint as proof of domain ownership and re-validates it: the register endpoint reference states that the key “must be and remain hosted” at this path [3], and Tesla’s troubleshooting guidance lists an unreachable key here as a cause of pairing failure.
Two hosting approaches are unsuitable:
- A home server — residential connections are typically behind CGNAT, and the endpoint that anchors the application’s identity should not depend on household uptime.
- A static site — serving the key as a committed file turns an availability requirement into a source-control change on every key rotation.
This deployment uses a Cloudflare Worker bound to a dedicated subdomain (free tier, no persistent infrastructure).
Setup:
- In the Cloudflare dashboard, create a Worker, e.g.
tesla-key. - Bind the subdomain (
fleet.example.com) to the Worker as a custom domain. All requests to the subdomain are then routed to the Worker; the code below returns the key only on the exact path and404on everything else. - Replace the default Worker source with the code below, inserting the public key between the backticks.
- Deploy, then verify:
curl https://<your-domain>/.well-known/appspecific/com.tesla.3p.public-key.pemreturns200with the PEM body.curl https://<your-domain>/returns404.
const TESLA_PUBLIC_KEY = `<YOUR PUBLIC KEY>`;
export default {
async fetch(request) {
const url = new URL(request.url);
if (url.pathname === "/.well-known/appspecific/com.tesla.3p.public-key.pem") {
return new Response(TESLA_PUBLIC_KEY, {
headers: {
"Content-Type": "application/x-pem-file",
"Cache-Control": "public, max-age=86400"
}
});
}
return new Response("Not found", { status: 404 });
}
};
Behaviour is intentionally minimal: 200 with the application/x-pem-file
content type on the key path, 404 on every other path, no redirects. Key
rotation is a new key pair plus a redeploy, with no other moving parts.
The requirement text is in [3], the register endpoint reference, which also documents the check used to confirm the registered key.
Step 3 — Register the application
- From the Fleet API getting-started page, select Create Application and Access Dashboard.
- On the registration form, provide:
- the application name and a short description of its function;
- the required scopes. This deployment requests
offline_access,vehicle_device_data,vehicle_location, andvehicle_cmdsonly. Scopes are granted individually; request the minimum set.
- Complete the flow. Tesla issues a partner authentication token for the application.
- Call the register endpoint with the partner token once per region of operation. An application is registered only in the regions in which this call has been made. A vehicle driven into an unregistered region reports the application as unregistered.
References: [1], “Step 4 — Call the Register Endpoint”; [3]; [4] (scopes); [5] (regions and countries).
Step 4 — Pair the vehicle
Pairing is an owner action performed in the Tesla app.
- Open
https://tesla.com/_ak/<your-domain>, where<your-domain>is the host serving the public key. - Follow the prompt to add the application to the vehicle.
- If pairing fails, check that:
- the Tesla app is signed in with the same Tesla account used to register the application;
- the application is registered in the vehicle’s current region (Step 3.4);
- the public key is reachable at the
/.well-known/path (Step 2.4).
References: [1], “Next Steps” → “Pairing a public key to a vehicle”; [2], which
documents the tesla.com/_ak/ pairing deep link and the same three failure
modes.
Step 5 — Install the Home Assistant integration
- In HACS [9], add the
tesla_fleetintegration (community-maintained). Installation and configuration options are documented in its HACS README. - Reload custom integrations or restart Home Assistant, then add the integration via Settings → Devices & Services → Add Integration → Tesla Fleet.
- Complete the OAuth flow with the Tesla account credentials. The integration stores the private key locally and signs Vehicle Command traffic through Tesla’s signed-command flow; the private key does not leave the host.
- Once pairing (Step 4) is complete, the vehicle is exposed with its full
entity set — approximately 80 entities on this Model Y, including:
- charge state, charge rate, cable and port status;
- battery level and range, odometer, speed, power draw;
- tire pressures (four corners);
- doors, windows, locks, frunk/trunk/sunroof covers;
- climate control, seat heaters, steering-wheel heater;
- location and route device trackers;
- command buttons: wake, honk, flash lights, HomeLink;
- an update entity for OTA software releases.
References: [6] (signed command traffic); [7] (vehicle state behind the entities in item 4).
Fleet Telemetry (planned)
The target end state replaces polling with push. Under Fleet Telemetry the vehicle streams selected fields — speed, location, state of charge, door state, tire pressures — to a server at configurable intervals down to 500 ms, transmitting a field only when its value has changed and its interval has elapsed. Tesla’s published pricing example puts a lean field configuration at roughly USD 0.01 per hour of driving.
The open decision is where the WebSocket endpoint is hosted:
- a tunnel from Home Assistant to a public endpoint;
- a Worker-terminated stream;
- the integration’s own server component.
This is an infrastructure decision rather than an API one and has been deferred. The vehicle is not yet configured for telemetry.
References: [2] (server requirements — a publicly reachable WebSocket endpoint with a vehicle-trusted certificate — plus vehicle configuration, streaming behaviour, and the cost example); [8] (full list of streamable fields).
Known issues and operational notes
- The public-key endpoint is an availability requirement for the life of the application. If the URL becomes unreachable, pairing and re-validation fail.
- Registration is per region. A vehicle in a region where the register endpoint was not called reports the application as unregistered.
- MFA on the Tesla account is mandatory before an application can be registered at all.
- Only the private key can sign commands. It is kept on a single host and is not committed to version control.
- Do not publish the VIN. A full VIN identifies a specific vehicle; keep it out of any public write-up.
Result
Vehicle state and commands in Home Assistant now run on the official Fleet API. Live state feeds the dashboards and automations the house already runs, and commands are delivered through the signed, documented endpoint, with no dependency on rate-limited private endpoints. The most involved part of the deployment was the roughly 20-line Worker that hosts the public key: the Fleet API onboarding is built around domain ownership, and meeting that requirement reliably — fixed path, sustained availability, no secrets — is what keeps the integration working. Fleet Telemetry is the documented next step and will replace the remaining polling with a vehicle-initiated stream.
References
- Tesla — What is Fleet API? (getting started). https://developer.tesla.com/docs/fleet-api/getting-started/what-is-fleet-api
- Tesla — Fleet Telemetry (overview). https://developer.tesla.com/docs/fleet-api/fleet-telemetry
- Tesla — Partner Endpoints (register endpoint reference). https://developer.tesla.com/docs/fleet-api/endpoints/partner-endpoints
- Tesla — Authentication: Overview (scopes). https://developer.tesla.com/docs/fleet-api/authentication/overview
- Tesla — Regions and Countries. https://developer.tesla.com/docs/fleet-api/getting-started/regions-countries
- Tesla — Vehicle Commands (endpoint reference). https://developer.tesla.com/docs/fleet-api/endpoints/vehicle-commands
- Tesla — Vehicle Endpoints (reference). https://developer.tesla.com/docs/fleet-api/endpoints/vehicle-endpoints
- Tesla — Fleet Telemetry: Available Data. https://developer.tesla.com/docs/fleet-api/fleet-telemetry/available-data
- HACS — Home Assistant Community Store. https://hacs.xyz/