Skip to content

Remote vehicle commands ​

TeslaSync exposes 65 unique Tesla Fleet API command endpoints plus a set of convenience aliases. This page is the user-facing reference. The implementation source of truth is internal/tesla/client_commands.go.

How a command is sent ​

Frontend → POST /api/v1/vehicles/{vin}/command
          { "command": "<name>", "params": { ... } }
              │
              ▼
       internal/tesla/client_commands.go::SendCommand
              │
       ┌──────┴──────┐
       │             │
   noProxy=true    noProxy=false  AND  commandProxyURL is set
       │             │
       ▼             ▼
  Fleet API     Vehicle Command Proxy ── signs ─► Fleet API
  (wake_up)
  • wake_up always goes directly to Fleet API — it does not require signing.
  • Every other command is routed through the Vehicle Command Proxy when one is configured (set TESLA_COMMAND_PROXY_URL). The proxy signs the request with your partner key for vehicles that require it (Model 3/Y from 2021+, Model S/X refresh, Cybertruck).
  • If no proxy is configured, the command is sent directly. This works only for vehicles that don't require signing.

Command proxy TLS trust ​

The API verifies the proxy certificate and hostname before sending credentials. Publicly trusted certificates need no extra configuration. For a private CA or self-signed certificate, set TESLA_COMMAND_PROXY_CA_FILE to a PEM trust anchor. Missing or invalid configured trust fails closed; there is no insecure bypass.

For Compose, put only the public CA/certificate in certs/command-proxy-trust/ca.pem (or set COMMAND_PROXY_TRUST_DIR) and set TESLA_COMMAND_PROXY_CA_FILE=/etc/teslasync/command-proxy/ca.pem. The server certificate must contain DNS:vehicle-command-proxy in its subjectAltName when using https://vehicle-command-proxy:4443. Keep TLS and command signing private keys in the proxy's existing data directory, never the API's trust directory.

For a new local installation, provision a self-signed certificate before starting the commands profile (do not overwrite an existing deployment's keys):

bash
install -d -m 700 data/vehicle-command certs/command-proxy-trust
openssl req -x509 -newkey rsa:3072 -nodes -days 365 \
  -subj '/CN=vehicle-command-proxy' \
  -addext 'subjectAltName=DNS:vehicle-command-proxy,DNS:localhost' \
  -keyout data/vehicle-command/tls-key.pem \
  -out certs/command-proxy-trust/ca.pem
chmod 600 data/vehicle-command/tls-key.pem
cp certs/command-proxy-trust/ca.pem data/vehicle-command/tls-cert.pem

This is the TLS key, not the Tesla partner command-signing key; provision private-key.pem and pair the vehicle separately as before.

For Helm, create a separate secret containing ca.pem, set commandProxy.caSecretName to its name and commandProxy.caFile to /etc/teslasync/command-proxy/ca.pem. Issue the proxy certificate with the actual service hostname (for example teslasync-command-proxy) as a DNS SAN. External proxy certificates must match the hostname in commandProxy.external.url. Renew the server certificate and trust anchor together and restart API/worker pods after rotating the CA. Authenticated development also requires HTTPS: session and impersonation cookies are always Secure, independent of forwarded headers.

For a publicly trusted wildcard certificate renewed in another namespace, reflect its TLS Secret into the proxy's namespace and set commandProxy.tlsSecretName to the reflected Secret name. The Helm deployment then reads tls.crt and tls.key from that Secret while retaining the separate Tesla command-signing private-key.pem in commandProxy.secretName. Do not reflect over the signing-key Secret: reflection replaces the whole Secret. When the API uses the in-cluster service URL but the certificate has a different DNS name, set commandProxy.tlsServerName to a name covered by the certificate (for example command.example.com for *.example.com). The API still connects to the internal Service, but verifies the configured certificate name and CA; this does not disable TLS verification or expose the proxy to the internet. Leave tlsServerName empty when the certificate already matches the URL.

yaml
commandProxy:
  enabled: true
  secretName: command-signing-key
  tlsSecretName: reflected-wildcard-tls
  tlsServerName: command.example.com

When tlsSecretName is set, the chart annotates the proxy Deployment for Stakater Reloader to restart it when the reflected Secret changes; the projected volume updates automatically, but the proxy may only load its certificate on startup. Install Reloader for automatic rotation or restart the proxy after each renewal. In Argo CD deployments, ensure reconciliation does not undo Reloader's rollout annotation. The reflected Secret and proxy must be in the same namespace. Once the new chart is deployed, the old TLS certificate and key can be removed from the GitOps-managed signing Secret; retain its private-key.pem. If using a private CA instead, mount its ca.pem into the API and worker pods as described above.

API surface ​

POST /api/v1/vehicles/{vin}/command
Content-Type: application/json

{ "command": "set_charge_limit", "params": { "percent": 80 } }

Successful responses return the Tesla envelope {"response": {"result": true}} verbatim. On failure, the API returns a non-2xx with {"error": "...", "details": "..."}.

Command catalog ​

Wake (1) ​

Frontend nameTesla endpointNotes
wake / wake_upwake_upDirect to Fleet API — never proxied

Security & access (10) ​

Frontend nameTesla endpointDefault params
lockdoor_lock
unlockdoor_unlock
set_sentry_modeset_sentry_modeon: true
sentry_on / sentry_offset_sentry_modeon set accordingly
speed_limit_onspeed_limit_activate
speed_limit_offspeed_limit_deactivate
speed_limit_set_limitspeed_limit_set_limit{ "limit_mph": <num> }
speed_limit_clear_pinspeed_limit_clear_pin{ "pin": "<4-digit>" }
speed_limit_clear_pin_adminspeed_limit_clear_pin_admin
guest_mode_on / guest_mode_offguest_modeenable true/false
erase_user_dataerase_user_dataDestructive — confirm in UI

Valet & PIN-to-drive (5) ​

Frontend nameTesla endpointDefault params
valet_on / valet_offset_valet_modeon true/false
set_valet_modeset_valet_mode{ "on": <bool>, "password": "<4-digit>" }
reset_valet_pinreset_valet_pin
set_pin_to_driveset_pin_to_drive{ "on": <bool>, "password": "<4-digit>" }
reset_pin_to_drive_pinreset_pin_to_drive_pin
clear_pin_to_drive_adminclear_pin_to_drive_admin

Climate (3) ​

Frontend nameTesla endpointDefault params
climate_onauto_conditioning_start
climate_offauto_conditioning_stop
set_tempsset_temps{ "driver_temp": <°C>, "passenger_temp": <°C> }

Seat & steering heat (6) ​

Frontend nameTesla endpointDefault params
seat_heaterremote_seat_heater_request{ "heater": 0..5, "level": 0..3 }
seat_coolerremote_seat_cooler_request{ "seat_position": 0..5, "seat_cooler_level": 0..3 }
auto_seat_climateremote_auto_seat_climate_request{ "auto_seat_position": 0..5, "auto_climate_on": <bool> }
steering_wheel_heatremote_steering_wheel_heater_request{ "on": <bool> }
steering_wheel_levelremote_steering_wheel_heat_level_request{ "level": 0..3 }
auto_steering_heatremote_auto_steering_wheel_heat_climate_request{ "on": <bool> }

Climate protection (7) ​

Frontend nameTesla endpointDefault params
bioweapon_on / bioweapon_offset_bioweapon_modeon + manual_override
cop_onset_cabin_overheat_protection{ "on": true, "fan_only": false }
cop_fan_onlyset_cabin_overheat_protection{ "on": true, "fan_only": true }
cop_offset_cabin_overheat_protection{ "on": false, "fan_only": false }
set_cop_tempset_cop_temp{ "cop_activation_temp": 0..2 }
climate_keeper_offset_climate_keeper_modeclimate_keeper_mode: 0
climate_keeper_onset_climate_keeper_modeclimate_keeper_mode: 1 (Keep)
dog_modeset_climate_keeper_modeclimate_keeper_mode: 2
camp_modeset_climate_keeper_modeclimate_keeper_mode: 3
preconditioning_maxset_preconditioning_max{ "on": true }
preconditioning_resetset_preconditioning_max{ "on": false }

Charging (8) ​

Frontend nameTesla endpointDefault params
open_charge_port / charge_port_opencharge_port_door_open
close_charge_port / charge_port_closecharge_port_door_close
charge_startcharge_start
charge_stopcharge_stop
set_charge_limitset_charge_limit{ "percent": 50..100 }
set_charging_ampsset_charging_amps{ "charging_amps": <num> }
charge_max_rangecharge_max_range
charge_standardcharge_standard

Trunk & frunk (1 endpoint, 2 directions) ​

Frontend nameTesla endpointDefault params
actuate_frunk / frunk / frunk_openactuate_trunkwhich_trunk: "front"
actuate_trunk / trunk_openactuate_trunkwhich_trunk: "rear"

Alerts (2) ​

Frontend nameTesla endpoint
honk_horn / honkhonk_horn
flash_lights / flashflash_lights

Boombox (1 endpoint) ​

Frontend nameTesla endpointDefault params
boombox_fartremote_boomboxsound: 0
boombox_pingremote_boomboxsound: 2000
remote_boomboxremote_boombox{ "sound": <id> }

Windows & sunroof (2) ​

Frontend nameTesla endpointDefault params
vent_windowswindow_controlcommand: "vent"
close_windowswindow_controlcommand: "close"
sunroof_ventsun_roof_controlstate: "vent"
sunroof_closesun_roof_controlstate: "close"
sunroof_stopsun_roof_controlstate: "stop"
Frontend nameTesla endpointDefault params
trigger_homelinktrigger_homelink{ "lat": <°>, "lon": <°> }

Remote start (1) ​

Frontend nameTesla endpointDefault params
remote_start_driveremote_start_drive{ "password": "<account-password>" }

Media (7) ​

Frontend nameTesla endpoint
media_toggle_playbackmedia_toggle_playback
media_next_trackmedia_next_track
media_prev_trackmedia_prev_track
media_next_favmedia_next_fav
media_prev_favmedia_prev_fav
media_volume_downmedia_volume_down
adjust_volumeadjust_volume ({ "volume": 0..11 })

Charge & precondition schedules (6) ​

Two generations of scheduling APIs:

Frontend nameTesla endpointNotes
set_scheduled_departureset_scheduled_departureLegacy (pre-2024.26)
set_scheduled_chargingset_scheduled_chargingLegacy (pre-2024.26)
add_charge_scheduleadd_charge_schedule2024.26+
remove_charge_scheduleremove_charge_schedule2024.26+
add_precondition_scheduleadd_precondition_schedule2024.26+
remove_precondition_scheduleremove_precondition_schedule2024.26+
Frontend nameTesla endpointDefault params
navigation_requestnavigation_request{ "type": "share_ext_content_raw", "value": { "android.intent.extra.TEXT": "<addr>" }, "locale": "en-US" }
navigation_gps_requestnavigation_gps_request{ "lat": <°>, "lon": <°>, "order": 1 }
navigation_sc_requestnavigation_sc_request{ "id": <supercharger_id>, "order": 1 }

Software updates (2) ​

Frontend nameTesla endpointDefault params
schedule_software_updateschedule_software_update{ "offset_sec": <s> }
cancel_software_updatecancel_software_update

Vehicle metadata (1) ​

Frontend nameTesla endpointDefault params
set_vehicle_nameset_vehicle_name{ "vehicle_name": "<text>" }

Validating a command name ​

The automation action executor uses tesla.IsKnownCommand(name) at parse time to reject unknown commands before saving the rule. This means a typo in an automation surfaces immediately, not at firing time.

Where commands appear in the UI ​

  • Vehicle Detail — single-vehicle action bar (most common commands)
  • Dashboard widgets — quick actions for charging / climate / sentry
  • Command palette (Cmd/Ctrl+K) — search by command name
  • Alert Studio — alert rules can trigger commands as a response
  • Automations — multi-step automations chain commands together
  • Admin → Dev Tools → Fleet API — raw command sender + history

Notes ​

  • Rate limits. Tesla applies per-vehicle rate limits. TeslaSync's client obeys a local rate-limiter; rejected requests get back pressure with a clear error rather than silent drops.
  • Tracing. Every command emits an OpenTelemetry span with tesla.vehicle.vin and tesla.command attributes. View in Jaeger when the tracing profile is enabled.
  • Audit. Every command goes through logCallback, which writes to the API logs table — visible at Admin → API Logs.
  • Adding a new command. Add an entry to the commands map in internal/tesla/client_commands.go and the corresponding Tesla endpoint becomes available to the rest of the stack (UI, automations, alerts). IsKnownCommand is the validation surface; no other code needs to change.

Self-hosted Tesla intelligence · MIT licensed · Privacy policy