Tesla Fleet API

A practical guide for developers: OAuth token flows, Fleet Telemetry, virtual keys & command proxy, code examples, and a troubleshooting checklist—optimized for real production integrations.

Want the working checklist + updates? Get early access.

I’ll email you the latest fixes/pitfalls (OAuth, PEM hosting, telemetry) and the downloadable PDF checklist.

  • OAuth: redirect URI + refresh-token rotation checklist
  • PEM hosting: exact well-known path + “no redirect / no HTML” validation
  • Telemetry vs polling: cost-safe design rules
Download PDF checklist No spam. Unsubscribe anytime.
Best for: apps, fleets, analytics, automation
Realtime data: Fleet Telemetry (preferred)
Commands: virtual keys + command proxy
Auth: Bearer tokens via OAuth

Official Tesla docs referenced throughout: What is Fleet API, Authentication, Fleet Telemetry, Best Practices, FAQ.

Quickstart checklist

1) Know which token type you need

  • Third-party customer tokens: a customer authorizes your app (authorization_code flow). See Tesla “Third-Party Tokens”.
  • Partner/business tokens: for business/fleet scenarios (depending on your integration model).

Start here: Third-Party Tokens and Authentication Overview.

2) Avoid expensive patterns

  • Don’t poll “vehicle data/device data” endpoints on an interval.
  • Use Fleet Telemetry for ongoing realtime data streaming.
  • Check connectivity state before requesting data or commands.

Tesla best practices: Best Practices and Billing & Limits.

Production rule of thumb: If you need data “all the time,” use Fleet Telemetry. If you need a one-off value occasionally, use the appropriate vehicle endpoint sparingly.

OAuth & tokens (what actually matters in production)

Fleet API endpoints use a standard Bearer token header: Authorization: Bearer <token>. See Tesla’s Authentication and Conventions.

Authorization Code flow (customer grants access)

  1. Redirect user to Tesla authorization URL (your client_id + scopes + redirect_uri).
  2. Receive code at your redirect_uri.
  3. Exchange code for access_token + refresh_token.
  4. Store refresh token securely, rotate on every refresh.
Refresh-token pitfall: after exchanging a refresh token, store the NEW refresh token and use it next time. Tesla notes refresh token validity and rotation behavior in the FAQ. See FAQ.

Token storage & rotation

If you’re doing this “just for yourself”: EVFleetPulse is building owner-friendly automations on top of Fleet API so you don’t have to maintain token refresh + cron jobs.
Get EVFleetPulse beta (owners automations) Email me the PDF checklist
Get the checklist (email)

OAuth redirect + refresh rotation mistakes are the #1 time sink. I’ll email you the PDF checklist.

Fleet Telemetry (realtime streaming)

Fleet Telemetry streams vehicle signals to a server you run on the public internet. Tesla documents server and vehicle setup here: Fleet Telemetry and available fields here: Available Data.

Prerequisites (watch these)

How it works (architecture)

  • Your app runs a Telemetry server (ingest endpoint).
  • You configure vehicles to stream to your server (configuration is signed).
  • You process protobuf/event messages → store in TSDB → analytics/dashboard.
  • Use telemetry connectivity state to avoid waking vehicles.
  • Implement backpressure: queue + batch writes.
  • Alerting: deltas + thresholds (don’t alert on jitter).
Why this matters: Tesla explicitly recommends avoiding polling device/vehicle data and using Fleet Telemetry for ongoing needs. Best Practices.

Commands, virtual keys & the Vehicle Command Proxy

Vehicle commands require signed payloads for many vehicles, using your application’s virtual key. Tesla’s docs: Vehicle Commands and Virtual Keys Developer Guide.

High-level rules

Operational tip: Treat your private key like a production secret. Never ship it to browsers or mobile apps. Keep it server-side only.

Examples

These examples are intentionally “minimal but real.” You’ll still need your app’s OAuth config, scopes, and the correct Fleet API base URLs per Tesla’s docs.

Example: call an authenticated endpoint (curl)

curl -sS \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  "https://fleet-api.prd.na.vn.cloud.tesla.com/api/1/vehicles"

Example: token exchange (server-side) with authorization_code

curl -sS -X POST \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "code=AUTH_CODE_FROM_REDIRECT" \
  -d "redirect_uri=https://yourdomain.com/callback" \
  "https://auth.tesla.com/oauth2/v3/token"

Reference: Tesla’s third-party token flow docs: Third-Party Tokens.

Example: refresh token rotation (pseudo)

// Pseudo: always store the NEW refresh token you receive
function refreshAccessToken(userId) {
  lock("refresh:" + userId, () => {
    const current = db.getRefreshToken(userId);
    const resp = POST("https://auth.tesla.com/oauth2/v3/token", {
      grant_type: "refresh_token",
      client_id: "...",
      client_secret: "...",
      refresh_token: current
    });
    db.saveTokens(userId, {
      accessToken: resp.access_token,
      refreshToken: resp.refresh_token, // IMPORTANT: rotate!
      expiresAt: now() + resp.expires_in
    });
  });
}

Tesla notes refresh token behavior and common issues in: FAQ.

Example: Java (Spring WebClient) request

import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

public class TeslaFleetClient {
  private final WebClient webClient;

  public TeslaFleetClient(String baseUrl) {
    this.webClient = WebClient.builder()
        .baseUrl(baseUrl)
        .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
        .build();
  }

  public Mono<String> listVehicles(String accessToken) {
    return webClient.get()
        .uri("/api/1/vehicles")
        .header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken)
        .retrieve()
        .bodyToMono(String.class);
  }
}

Troubleshooting checklist

Auth & tokens

Public key hosting / well-known PEM (common app registration pitfall)

If you don’t want to babysit OAuth + PEM hosting: EVFleetPulse is building the owner automations layer (charge rules, preconditioning, alerts) so you can skip the plumbing.
Get EVFleetPulse beta (owners automations) Email me the PDF checklist
Email me the PEM hosting checklist (PDF)

This is the most common app registration failure: wrong path, redirect, or HTML instead of PEM.

403 “Access Denied” during token exchange

Telemetry not streaming

Commands failing

Design smell: If your app frequently wakes vehicles, Tesla considers that a sign of improper design. Prefer streaming and only do on-demand queries/commands when necessary. Billing & Limits.

FAQ

Is Fleet Telemetry required?

Not for every use case, but for ongoing realtime data needs it’s the preferred approach. Polling vehicle/device data endpoints regularly is discouraged. See: Best Practices.

Do I need the Vehicle Command Proxy?

Many commands must be signed with your virtual key. The proxy signs requests server-side and forwards them. Tesla’s docs explain when it’s required and how it works: Vehicle Commands.

Why did my refresh token stop working?

Refresh tokens have lifetimes and rotation behavior. When you exchange a refresh token, save the new refresh token returned and use that next time. Reference: Tesla Fleet API FAQ.

Why EVFleetPulse exists

A lot of people start with “I just want SoC twice a day,” then end up maintaining OAuth refresh, key hosting, sleep/wake edge cases, and alert logic. EVFleetPulse is the owner-focused layer on top of Fleet API so you can get useful outcomes without building an app platform.

Resources

More guides in this series

Get the checklist + early access

If this guide helped, grab the PDF checklist and updates (OAuth pitfalls, PEM hosting, telemetry gotchas).

Download PDF
No spam. Unsubscribe anytime.
Want the owner automations layer instead of building Fleet API plumbing? Get EVFleetPulse beta.