API reference

Vehicles

Your Tesla vehicles and your organization's fleet: live state, commands, drives, charging, parked periods, keys and drivers, places, tariffs and sharing.

See Vehicles. A vehicle belongs to one space, your Personal space or an organization's, and routes take that space in their path. A key needs vehicles:read to read, vehicles:write to change settings, places and tariffs, and vehicles:control to send commands; each command also needs the matching capability on that vehicle. A vehicle's position is only in answers where its sharing allows it.

GET /v1/vehicles/tesla/callback

Tesla's registered redirect after sign-in (no token): spends the one-time state, hands the code to Vehicles' worker and redirects the browser to the app's finish page with a ticket or a reason. Never shows a page of its own.

Auth: none

Errors

StatusMessage
404Vehicles isn't available here.

GET /v1/platform/vehicles/pictures

The switch, every rule (with what is wrong with one that fails validation, and overlaps) and the misses.

Auth: user access token or platform agent key · Scope: platform:admin in the platform organization

Response 200

{
  switch: {
    enabled: boolean
    rev: number
    epoch: number
  }
  rules: {
    invalid?: string
    ruleId: string
    carType: string
    fromYear?: number
    toYear?: number
    slot: "trim" | "base" | "paint" | "wheels" | "roof" | "spoiler" | "exteriorTrim"
    value: string
    codes: string[]
    enabled: boolean
    note?: string
    model?: string
    defaults?: {
      trim?: string[]
      paint?: string[]
      wheels?: string[]
      roof?: string[]
      spoiler?: string[]
      exteriorTrim?: string[]
    }
  }[]
  warnings: {
    ruleId: string
    other: string
    message: string
  }[]
  misses: {
    carType: string
    slot: string
    value: string
    count: number
    firstSeen: number
    lastSeen: number
  }[]
}

Errors

StatusMessage
503The platform table isn't available here.

GET /v1/platform/vehicles/pictures/rules

The picture rules, and the warnings about them (platform staff).

Auth: user access token or platform agent key · Scope: platform:admin in the platform organization

Response 200

{
  rules: {
    invalid?: string
    ruleId: string
    carType: string
    fromYear?: number
    toYear?: number
    slot: "trim" | "base" | "paint" | "wheels" | "roof" | "spoiler" | "exteriorTrim"
    value: string
    codes: string[]
    enabled: boolean
    note?: string
    model?: string
    defaults?: {
      trim?: string[]
      paint?: string[]
      wheels?: string[]
      roof?: string[]
      spoiler?: string[]
      exteriorTrim?: string[]
    }
  }[]
  warnings: {
    ruleId: string
    other: string
    message: string
  }[]
}

Errors

StatusMessage
503The platform table isn't available here.

PUT /v1/platform/vehicles/pictures/rules/:ruleId

Writes a rule (creating or replacing it by id). Raises rev.

Auth: user access token or platform agent key · Scope: platform:admin in the platform organization

Path parameterDescription
:ruleIdRule id: a storage lifecycle rule (as returned by the settings or lifecycle routes), an issue automation rule (rul_…) or a Mirage AutoMod rule (mar_…).

Request body

FieldTypeRequiredDefaultNotes
carTypestringYesup to 40 characters
fromYearintegerNocan be null
toYearintegerNocan be null
slotstringYesup to 20 characters
valuestringYesup to 200 characters
codesstring[]Yesup to 50 items; each up to 20 characters
enabledbooleanNotrue
notestringNoup to 1,000 characters; can be null
modelstringNoup to 20 characters; can be null
defaultsobjectNokeys up to 20 characters; values: string[] (up to 50 items, each up to 20 characters); can be null

Also checked: Unknown fields are rejected.

Response 200

{
  rule: {
    ruleId: string
    carType: string
    fromYear?: number
    toYear?: number
    slot: "trim" | "base" | "paint" | "wheels" | "roof" | "spoiler" | "exteriorTrim"
    value: string
    codes: string[]
    enabled: boolean
    note?: string
    model?: string
    defaults?: {
      trim?: string[]
      paint?: string[]
      wheels?: string[]
      roof?: string[]
      spoiler?: string[]
      exteriorTrim?: string[]
    }
  }
  warnings: {
    ruleId: string
    other: string
    message: string
  }[]
  switch: {
    enabled: boolean
    rev: number
    epoch: number
  }
}

Errors

StatusMessage
503The platform table isn't available here.

DELETE /v1/platform/vehicles/pictures/rules/:ruleId

Removes a picture rule. Raises rev.

Auth: user access token or platform agent key · Scope: platform:admin in the platform organization

Path parameterDescription
:ruleIdRule id: a storage lifecycle rule (as returned by the settings or lifecycle routes), an issue automation rule (rul_…) or a Mirage AutoMod rule (mar_…).

Response 200

{
  ok: true
  switch: {
    enabled: boolean
    rev: number
    epoch: number
  }
}

Errors

StatusMessage
404Rule not found
503The platform table isn't available here.

GET /v1/platform/vehicles/pictures/misses

The values no rule covers, most recent first: what to map next.

Auth: user access token or platform agent key · Scope: platform:admin in the platform organization

Response 200

{
  misses: {
    carType: string
    slot: string
    value: string
    count: number
    firstSeen: number
    lastSeen: number
  }[]
}

Errors

StatusMessage
503The platform table isn't available here.

DELETE /v1/platform/vehicles/pictures/misses

Dismisses a miss (?carType=&slot=&value=); audited.

Auth: user access token or platform agent key · Scope: platform:admin in the platform organization

Response 200

{
  ok: true
}

Errors

StatusMessage
503The platform table isn't available here.

GET /v1/platform/vehicles/pictures/switch

Whether car pictures are on.

Auth: user access token or platform agent key · Scope: platform:admin in the platform organization

Response 200

{
  switch: {
    enabled: boolean
    rev: number
    epoch: number
  }
}

Errors

StatusMessage
503The platform table isn't available here.

PUT /v1/platform/vehicles/pictures/switch

Turns pictures on or off. Off: no picture anywhere and no fetch, within a minute (the API's cache).

Auth: user access token or platform agent key · Scope: platform:admin in the platform organization

Request body

FieldTypeRequiredNotes
enabledbooleanYes

Also checked: Unknown fields are rejected.

Response 200

{
  switch: {
    enabled: boolean
    rev: number
    epoch: number
  }
}

Errors

StatusMessage
503The platform table isn't available here.

POST /v1/platform/vehicles/pictures/refresh-all

Refresh all: new keys in the bucket (a new epoch), fetched as cars are seen, and every car resolved again.

Auth: user access token or platform agent key · Scope: platform:admin in the platform organization

Response 200

{
  switch: {
    enabled: boolean
    rev: number
    epoch: number
  }
}

Errors

StatusMessage
503The platform table isn't available here.

POST /v1/platform/vehicles/pictures/preview

Resolves submitted values through the worker: { year?, config: { carType, exteriorColor, … }, include?: [ruleId] } (include: disabled rows to use for this preview only). ready carries signed links on our CDN for each view, the model and the codes it sent; every other outcome carries a message.

Auth: user access token or platform agent key · Scope: platform:admin in the platform organization

Request body

FieldTypeRequiredNotes
yearintegerNo
configobjectYeskeys up to 40 characters; values: string (up to 200 characters)
includestring[]Noup to 20 items; each up to 80 characters

Also checked: Unknown fields are rejected.

Response 200

{
  model?: string
  codes?: string[]
  misses?: {
    carType: string
    slot: string
    value: string
  }[]
  outcome: "busy" | "no_rule" | "mapping" | "fetch" | "timeout"
  message: string
}
| {
  views: {
    "3qtr"?: {
      srcset: {
        url: string
        width: number
        height: number
      }[]
      box: {
        x: number
        y: number
        w: number
        h: number
      }
    }
    side?: {
      srcset: {
        url: string
        width: number
        height: number
      }[]
      box: {
        x: number
        y: number
        w: number
        h: number
      }
    }
  }
  approximate?: string[]
  outcome: string
  model: string
  codes: string[]
}

Errors

StatusMessage
403The preview is for people in Admin.
503The platform table isn't available here.
503The picture CDN isn't on here, so there is nothing to show a preview from.

POST /v1/me/vehicles/connections/tesla/authorize

Starts connecting your Tesla account: send the consent you gave (each data category, and precise location as its own choice); returns Tesla's sign-in url and a browserValue for the app to keep as an HttpOnly cookie and send back to finish. Only from the Vehicles and phone apps.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Request body

FieldTypeRequiredNotes
returnTostringNoup to 300 characters
reconnectstringNoup to 80 characters
consentobjectYes
consent.categories("vehicle_state" | "commands" | "charging")[]Yes
consent.locationbooleanYes

Response 200

{
  url: string
  browserValue: string
  expiresAt: number
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
403Connect a Tesla account in the Vehicles app.
404Not found

POST /v1/me/vehicles/connections/tesla/finish

Finishes the connection with the ticket from the redirect and the browserValue. Kept only for the person and browser that started it, otherwise the tokens are discarded. 202 pending while the exchange is still running (ask again in a second).

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Request body

FieldTypeRequiredNotes
ticketstringYes1–200 characters
browserValuestringYes1–200 characters

Response 200

{
  connection: {
    connectionId: string
    provider: "tesla"
    status: "ok" | "revoked" | "reconnect" | "disconnecting"
    region: "na-apac" | "eu"
    scopes: string[]
    location: boolean
    createdAt: number
    createdBy?: string
    lastRefreshAt?: number
    notice?: string
  }
  returnTo?: string
  reconnected: boolean
  sameAccount: boolean
}

Response 202

{
  status: string
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
403Connect a Tesla account in the Vehicles app.
404Not found

GET /v1/me/vehicles/connections

Your Tesla connections: status (ok, reconnect), region, granted scopes and whether precise location is on. Never a token.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:read (when actor.type === "user")

Response 200

{
  connections: {
    connectionId: string
    provider: "tesla"
    status: "ok" | "revoked" | "reconnect" | "disconnecting"
    region: "na-apac" | "eu"
    scopes: string[]
    location: boolean
    createdAt: number
    createdBy?: string
    lastRefreshAt?: number
    notice?: string
  }[]
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:read on a key made by a person.
404Vehicles isn't available here.
404Not found

DELETE /v1/me/vehicles/connections/:connectionId

Disconnects a Tesla account: its tokens are removed at once and its telemetry stops. Returns Tesla's page for withdrawing the app's access there too (consentUrl).

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:connectionIdA Tesla connection's id (vconn_…); under vehicles the connection to end, rediscover or list the cars of.

Response 200

{
  consentUrl: string
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
403Connect a Tesla account in the Vehicles app.
404Not found

GET /v1/me/vehicles

The garage: the cars of this space the caller holds anything on, each with their capabilities and a status summary ({ vehicles }). In a Personal space also the cars shared with them. An organisation's members see the cars they have been granted, a fleet admin all of them.

Auth: user access token or platform agent key · Scopes: vehicles:read (when orgId), vehicles:read (when actor.type === "user")

Response 200

{
  vehicles: {
    [key: string]: unknown
  }[]
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:read on a key made by a person.
404Vehicles isn't available here.
404Not found

GET /v1/me/vehicles/connections/:connectionId/vehicles

Every car Tesla shows for a connection, and which can be added: status available, claimed_here, claimed_elsewhere or unavailable, the last two with a reason in words ({ vehicles }; asks Tesla, so it is limited and 503 where that isn't wired). For a person in the app, a car in another space they manage, which this account owns, is movable with that space's fromSpaceName and fromSpaceKind: a claim moves it here. Of any other space nothing is said.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:connectionIdA Tesla connection's id (vconn_…); under vehicles the connection to end, rediscover or list the cars of.

Response 200

{
  vehicles: {
    fromSpaceKind?: "org" | "personal"
    fromSpaceName?: string
    movable?: boolean
    providerVehicleId?: string
    reason?: string
    vehicleId?: string
    vin: string
    name?: string
    model?: string
    accessType?: "OWNER" | "DRIVER"
    state?: string
    status: "unavailable" | "available" | "claimed_here" | "claimed_elsewhere"
  }[]
}

Errors

StatusMessage
400Not a connection id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found

POST /v1/me/vehicles/connections/:connectionId/sync

Rediscover a connection's cars: queued for the worker (the API never calls Tesla), 202. List them again a moment later.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:connectionIdA Tesla connection's id (vconn_…); under vehicles the connection to end, rediscover or list the cars of.

Response 202

{
  queued: true
}

Errors

StatusMessage
400Not a connection id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Connection not found
409Reconnect this Tesla account first.

POST /v1/me/vehicles/claim

Adds a car the connection lists to this space and starts key pairing. The VIN is only ever accepted if the connection lists it now. 201 { outcome: "claimed" | "took_over", vehicle }, 200 for exists and moved, and 409 grant_request with the holder's vehicleId when someone else holds the car and this account may not take it.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Request body

FieldTypeRequiredNotes
connectionIdstringYes
vinstringYesmatches ^[A-HJ-NPR-Z0-9]{17}$; trimmed; uppercased
namestringNo1–60 characters; trimmed

Response 200

{
  outcome: "exists" | "moved"
  vehicle: {
    vehicleId: string
    model?: string
    trim?: string
    vinTail: string
    accessType?: "OWNER" | "DRIVER"
    keyStatus: "pending" | "lost" | "paired" | "unpaired" | "not_required"
    periodStart?: string
  }
}

Response 201

{
  outcome: string
  vehicle: {
    vehicleId: string
    model?: string
    trim?: string
    vinTail: string
    accessType?: "OWNER" | "DRIVER"
    keyStatus: "pending" | "lost" | "paired" | "unpaired" | "not_required"
    periodStart?: string
  }
  ended: {
    vehicleId: string
  }
}
| {
  outcome: string
  vehicle: {
    vehicleId: string
    model?: string
    trim?: string
    vinTail: string
    accessType?: "OWNER" | "DRIVER"
    keyStatus: "pending" | "lost" | "paired" | "unpaired" | "not_required"
    periodStart?: string
  }
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
409Someone else holds this car. Ask them to share it with you.

GET /v1/me/vehicles/api-access

Whether API keys (yours, and your organizations' keys made by you) may use your Personal Vehicles. Off until you turn it on.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:read (when actor.type === "user")

Response 200

{
  enabled: boolean
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:read on a key made by a person.
403Change this in the Vehicles app.
404Vehicles isn't available here.
404Not found

PUT /v1/me/vehicles/api-access

Turns API key access to your Personal Vehicles on or off. Only you, in the Vehicles app.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Request body

FieldTypeRequiredNotes
enabledbooleanYes

Response 200

{
  enabled: boolean
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
403Connect a Tesla account in the Vehicles app.
404Not found

GET /v1/me/vehicles/display

The display units you chose, the same in every space: distance (km, mi), temperature (C, F), pressure (kPa, bar, psi), efficiency (Wh/km, km/kWh, Wh/mi, mi/kWh), battery (percent, range) and map (standard, satellite). Only what you chose; the rest follows your language. Every other answer stays metric.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:read (when actor.type === "user")

Response 200

{
  display: {
    distance?: "km" | "mi"
    temperature?: "C" | "F"
    pressure?: "kPa" | "bar" | "psi"
    efficiency?: "Wh/km" | "km/kWh" | "Wh/mi" | "mi/kWh"
    battery?: "range" | "percent"
    map?: "standard" | "satellite"
  }
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:read on a key made by a person.
404Vehicles isn't available here.
404Not found

PUT /v1/me/vehicles/display

Replaces your display units ({ display: { … } }); {} goes back to your language's. Only you, in the Vehicles or phone app.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Request body

FieldTypeRequiredNotes
displayobjectYes
display.distance"km" | "mi"No
display.temperature"C" | "F"No
display.pressure"kPa" | "bar" | "psi"No
display.efficiency"Wh/km" | "km/kWh" | "Wh/mi" | "mi/kWh"No
display.battery"percent" | "range"No
display.map"standard" | "satellite"No

Response 200

{
  display: {
    distance?: "km" | "mi"
    temperature?: "C" | "F"
    pressure?: "kPa" | "bar" | "psi"
    efficiency?: "Wh/km" | "km/kWh" | "Wh/mi" | "mi/kWh"
    battery?: "range" | "percent"
    map?: "standard" | "satellite"
  }
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
403Connect a Tesla account in the Vehicles app.
404Not found

GET /v1/me/vehicles/profile

The space's units, currency, default tariff and the trim around a home place on shared routes.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:read (when actor.type === "user")

Response 200

{
  units: "metric" | "imperial"
  currency: string
  defaultTariffId: null | string
  homeTrimRadiusM: null | number
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:read on a key made by a person.
404Vehicles isn't available here.
404Not found

PUT /v1/me/vehicles/profile

Changes those that are given; null clears the default tariff or the trim. The default tariff is one of the space's.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Request body

FieldTypeRequiredNotes
units"metric" | "imperial"No
currencystringNomatches ^[A-Z]{3}$
defaultTariffIdstringNocan be null
homeTrimRadiusMintegerNo0–2000; can be null

Also checked: Say what to change.

Response 200

{
  units: "metric" | "imperial"
  currency: string
  defaultTariffId: null | string
  homeTrimRadiusM: null | number
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Tariff not found

GET /v1/me/vehicles/places

The space's charging places (a centre and a radius in metres), by name.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:read (when actor.type === "user")

Response 200

{
  places: {
    placeId: string
    name?: string
    kind: "home" | "other" | "work"
    lat: number
    lon: number
    radiusM: number
    tariffId: null | string
  }[]
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:read on a key made by a person.
404Vehicles isn't available here.
404Not found

POST /v1/me/vehicles/places

Adds a charging place: a name, a centre and a radius in metres (default 100), a kind and a tariff if it has one. 201; 409 limit_reached at the space's limit.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Request body

FieldTypeRequiredDefaultNotes
nameany JSONYes
kindany JSONNo"other"
latnumberYes-90–90
lonnumberYes-180–180
radiusMany JSONNo100
tariffIdany JSONNo

Response 201

{
  placeId: string
  name: string
  kind: "home" | "other" | "work"
  lat: number
  lon: number
  radiusM: number
  tariffId: null | string
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Tariff not found

PATCH /v1/me/vehicles/places/:placeId

Changes the fields given on a place; tariffId: null clears its tariff.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:placeIdA place's id: in Maps a saved place (plc_…), in Vehicles a space's charging place (vpl_…).

Request body

FieldTypeRequiredNotes
nameany JSONNo
kindany JSONNo
latnumberNo-90–90
lonnumberNo-180–180
radiusMany JSONNo
tariffIdany JSONNo

Also checked: Say what to change.

Response 200

{
  placeId: string
  name?: string
  kind: "home" | "other" | "work"
  lat: number
  lon: number
  radiusM: number
  tariffId: null | string
}

Errors

StatusMessage
400Not a place id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Place not found
404Tariff not found

DELETE /v1/me/vehicles/places/:placeId

Removes a place; an automation that names it stops it, so the place stays until that automation is changed (409).

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:placeIdA place's id: in Maps a saved place (plc_…), in Vehicles a space's charging place (vpl_…).

Response 204 with no body.

Errors

StatusMessage
400Not a place id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Place not found

GET /v1/me/vehicles/tariffs/plans

Retailer plans for a postcode, from the AER's reference data (cached a day; the NECF states only). plans is empty for a postcode no plan serves.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:read (when actor.type === "user")

Query parameterTypeRequiredNotes
postcodestringYesmatches ^\d{4}$
retailerstringYesmatches ^[a-z0-9][a-z0-9-]{1,38}$

Response 200

{
  fetchedAt: string
  truncated?: true
  postcode: string
  state: "ACT" | "NSW" | "NT" | "QLD" | "SA" | "TAS" | "VIC" | "WA"
  retailer: string
  plans: {
    planId: string
    name: string
    brand: string
    customerType: string
    type: string
  }[]
}

Errors

StatusMessage
400Not an Australian postcode.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:read on a key made by a person.
404Vehicles isn't available here.
404Not found

GET /v1/me/vehicles/tariffs

The space's tariffs, by name.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:read (when actor.type === "user")

Response 200

{
  tariffs: {
    [key: string]: unknown
    [key: number]: unknown
  }[]
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:read on a key made by a person.
404Vehicles isn't available here.
404Not found

POST /v1/me/vehicles/tariffs

Adds a tariff: flat, or time of use with windows that tile the day for weekdays and weekends. 201; 409 limit_reached.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Request body

FieldTypeRequiredDefaultNotes
nameany JSONYes
kind"flat" | "tou"Yes
flatTenthsCentsintegerNo0–10000
zonestringNoup to 64 characters
periodsobject[]No1–12 items
periods[].name"peak" | "shoulder" | "offpeak"Yes
periods[].days"weekday" | "weekend" | "all"Yes
periods[].fromstringYesmatches ^([01]\d|2[0-3]):[0-5]\d$
periods[].tostring | "24:00"Yesmatches ^([01]\d|2[0-3]):[0-5]\d$
periods[].tenthsCentsintegerYes0–10000
exportTenthsCentsintegerNo0–10000
supplyCentsPerDayintegerNo0–10000
supplySharebooleanNofalse

Also checked: A flat tariff has flatTenthsCents; a time-of-use tariff has zone and periods. Sharing the supply charge needs supplyCentsPerDay.

Response 201

{
  tariffId: string
  name: string
  kind: "flat" | "tou"
  supplyShare: boolean
  flatTenthsCents?: number
  zone?: string
  periods?: {
    name: "peak" | "shoulder" | "offpeak"
    days: "all" | "weekday" | "weekend"
    from: string
    to: string
    tenthsCents: number
  }[]
  exportTenthsCents?: number
  supplyCentsPerDay?: number
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found

PUT /v1/me/vehicles/tariffs/:tariffId

Replaces a tariff with the one given.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:tariffIdA tariff's id (vtf_…).

Request body

FieldTypeRequiredDefaultNotes
nameany JSONYes
kind"flat" | "tou"Yes
flatTenthsCentsintegerNo0–10000
zonestringNoup to 64 characters
periodsobject[]No1–12 items
periods[].name"peak" | "shoulder" | "offpeak"Yes
periods[].days"weekday" | "weekend" | "all"Yes
periods[].fromstringYesmatches ^([01]\d|2[0-3]):[0-5]\d$
periods[].tostring | "24:00"Yesmatches ^([01]\d|2[0-3]):[0-5]\d$
periods[].tenthsCentsintegerYes0–10000
exportTenthsCentsintegerNo0–10000
supplyCentsPerDayintegerNo0–10000
supplySharebooleanNofalse

Also checked: A flat tariff has flatTenthsCents; a time-of-use tariff has zone and periods. Sharing the supply charge needs supplyCentsPerDay.

Response 200

{
  tariffId: string
  name: string
  kind: "flat" | "tou"
  supplyShare: boolean
  flatTenthsCents?: number
  zone?: string
  periods?: {
    name: "peak" | "shoulder" | "offpeak"
    days: "all" | "weekday" | "weekend"
    from: string
    to: string
    tenthsCents: number
  }[]
  exportTenthsCents?: number
  supplyCentsPerDay?: number
}

Errors

StatusMessage
400Not a tariff id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Tariff not found

DELETE /v1/me/vehicles/tariffs/:tariffId

Removes a tariff; the default tariff and a place that uses it keep it from going (409).

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:tariffIdA tariff's id (vtf_…).

Response 204 with no body.

Errors

StatusMessage
400Not a tariff id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Tariff not found

GET /v1/me/vehicles/geofences

The space's geofences: a circle (metres) or a polygon of up to 500 points. Enter and leave are told with the fence's name, never its coordinates.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:read (when actor.type === "user")

Response 200

{
  geofences: {
    fenceId: string
    name?: string
    shape: {
      type: "circle"
      lat: number
      lon: number
      radiusM: number
    } | {
      type: "polygon"
      points: number[][]
    }
    enabled: boolean
    notifyOn: "both" | "leave" | "enter"
  }[]
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:read on a key made by a person.
404Vehicles isn't available here.
404Not found

POST /v1/me/vehicles/geofences

Adds a geofence: a circle or a polygon, sealed at rest. 201; 400 for an antimeridian crossing; 409 limit_reached.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Request body

FieldTypeRequiredDefaultNotes
nameany JSONYes
shapeobject | objectYes
enabledbooleanNotrue
notifyOn"enter" | "leave" | "both"No"both"

Response 201

{
  fenceId: string
  name: string
  shape: {
    type: "circle"
    lat: number
    lon: number
    radiusM: number
  } | {
    type: "polygon"
    points: number[][]
  }
  enabled: boolean
  notifyOn: "both" | "leave" | "enter"
}

Errors

StatusMessage
400A fence can't cross the antimeridian.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found

PATCH /v1/me/vehicles/geofences/:fenceId

Changes the fields given on a geofence.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:fenceIdA geofence's id (vfn_…).

Request body

FieldTypeRequiredNotes
nameany JSONNo
shapeobject | objectNo
enabledbooleanNo
notifyOn"enter" | "leave" | "both"No

Also checked: Say what to change.

Response 200

{
  fenceId: string
  name?: string
  shape: {
    type: "circle"
    lat: number
    lon: number
    radiusM: number
  } | {
    type: "polygon"
    points: number[][]
  }
  enabled: boolean
  notifyOn: "both" | "leave" | "enter"
}

Errors

StatusMessage
400Not a geofence id.
400A fence can't cross the antimeridian.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Geofence not found

DELETE /v1/me/vehicles/geofences/:fenceId

Removes a geofence; an automation triggered by it keeps it from going (409).

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:fenceIdA geofence's id (vfn_…).

Response 204 with no body.

Errors

StatusMessage
400Not a geofence id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Geofence not found

GET /v1/me/vehicles/automations

The space's automations: a trigger, conditions and up to five actions on the cars named, run with the creator's capabilities. The engine that runs them is not built, so these are stored and shown, and none fires yet.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:read (when actor.type === "user")

Response 200

{
  automations: {
    [key: string]: unknown
    [key: number]: unknown
  }[]
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:read on a key made by a person.
404Vehicles isn't available here.
404Not found

POST /v1/me/vehicles/automations

Adds an automation. Command actions follow the confirmation table: a tap is stored, a hold needs a fresh step-up, a step-up command is refused. 201.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Request body

FieldTypeRequiredDefaultNotes
nameany JSONYes
enabledbooleanYes
vehicleIdsstring[]Yes1–50 items
triggerobject | object | object | object | object | object | object | object | objectYes
conditionsobjectYes
conditions.insidePlaceIdstringNo
conditions.windowobjectNo
conditions.window.fromstringYesmatches ^([01]\d|2[0-3]):[0-5]\d$
conditions.window.tostringYesmatches ^([01]\d|2[0-3]):[0-5]\d$
conditions.window.zonestringYesup to 64 characters
conditions.socMinintegerNo0–100
conditions.socMaxintegerNo0–100
conditions.pluggedbooleanNo
conditions.nobodyInsidebooleanNo
actions(object | object)[]Yes1–5 items
enabledany JSONNotrue
conditionsobjectNo{}
conditions.insidePlaceIdstringNo
conditions.windowobjectNo
conditions.window.fromstringYesmatches ^([01]\d|2[0-3]):[0-5]\d$
conditions.window.tostringYesmatches ^([01]\d|2[0-3]):[0-5]\d$
conditions.window.zonestringYesup to 64 characters
conditions.socMinintegerNo0–100
conditions.socMaxintegerNo0–100
conditions.pluggedbooleanNo
conditions.nobodyInsidebooleanNo

Response 201

{
  automationId: string
  name: string
  createdBy: string
  enabled: boolean
  vehicleIds: string[]
  trigger: {
    type: "schedule"
    at: string
    days: ("sun" | "mon" | "tue" | "wed" | "thu" | "fri" | "sat")[]
    zone: string
  } | {
    type: "once"
    at: string
  } | {
    type: "geofence"
    fenceId: string
    on: "leave" | "enter"
  } | {
    type: "plugged"
    on: "out" | "in"
  } | {
    type: "charge_reached"
    socPct: number
  } | {
    type: "soc_below"
    socPct: number
  } | {
    type: "outside_temp"
    aboveC?: number
    belowC?: number
  } | {
    type: "drive_ended"
  } | {
    type: "left_unlocked"
    minutes: number
  }
  conditions: {
    insidePlaceId?: string
    window?: {
      from: string
      to: string
      zone: string
    }
    socMin?: number
    socMax?: number
    plugged?: boolean
    nobodyInside?: boolean
  }
  actions: {
    type: "command"
    command: string
    args: {
      [key: string]: unknown
    }
    confirmedAt?: number
  } | {
    type: "notify"
    message: string
    confirmedAt?: number
  }[]
  createdAt: number
  updatedAt: number
}

Errors

StatusMessage
400"…" isn't a command.
400…: …
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Vehicle not found
404Geofence not found
404Place not found

PATCH /v1/me/vehicles/automations/:automationId

Changes an automation. Only its creator changes the cars, trigger, conditions or actions (403 not_creator); another admin may switch or rename it.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:automationIdAn automation's id (vau_…).

Request body

FieldTypeRequiredNotes
nameany JSONNo
enabledany JSONNo
vehicleIdsany JSONNo
triggerobject | object | object | object | object | object | object | object | objectNo
conditionsobjectNo
conditions.insidePlaceIdstringNo
conditions.windowobjectNo
conditions.window.fromstringYesmatches ^([01]\d|2[0-3]):[0-5]\d$
conditions.window.tostringYesmatches ^([01]\d|2[0-3]):[0-5]\d$
conditions.window.zonestringYesup to 64 characters
conditions.socMinintegerNo0–100
conditions.socMaxintegerNo0–100
conditions.pluggedbooleanNo
conditions.nobodyInsidebooleanNo
actionsany JSONNo

Also checked: Say what to change.

Response 200

{
  [key: string]: unknown
}

Errors

StatusMessage
400Not a automation id.
400"…" isn't a command.
400…: …
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Automation not found
404Vehicle not found
404Geofence not found
404Place not found

DELETE /v1/me/vehicles/automations/:automationId

Removes an automation. 204.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:automationIdAn automation's id (vau_…).

Response 204 with no body.

Errors

StatusMessage
400Not a automation id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Automation not found

POST /v1/orgs/:orgId/vehicles/connections/tesla/authorize

Starts connecting a Tesla account to the organization (owners and admins, from the app): returns Tesla's sign-in url and the browserValue to keep and send back to finish.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).

Request body

FieldTypeRequiredNotes
returnTostringNoup to 300 characters
reconnectstringNoup to 80 characters
consentobjectYes
consent.categories("vehicle_state" | "commands" | "charging")[]Yes
consent.locationbooleanYes

Response 200

{
  url: string
  browserValue: string
  expiresAt: number
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
403Connect a Tesla account in the Vehicles app.
404Not found

POST /v1/orgs/:orgId/vehicles/connections/tesla/finish

Finishes the organization's Tesla connection with the redirect's ticket and the browserValue; 202 pending while the exchange is running.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).

Request body

FieldTypeRequiredNotes
ticketstringYes1–200 characters
browserValuestringYes1–200 characters

Response 200

{
  connection: {
    connectionId: string
    provider: "tesla"
    status: "ok" | "revoked" | "reconnect" | "disconnecting"
    region: "na-apac" | "eu"
    scopes: string[]
    location: boolean
    createdAt: number
    createdBy?: string
    lastRefreshAt?: number
    notice?: string
  }
  returnTo?: string
  reconnected: boolean
  sameAccount: boolean
}

Response 202

{
  status: string
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
403Connect a Tesla account in the Vehicles app.
404Not found

GET /v1/orgs/:orgId/vehicles/connections

The organization's Tesla connections: status, region, granted scopes and whether precise location is on. Never a token.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:read (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).

Response 200

{
  connections: {
    connectionId: string
    provider: "tesla"
    status: "ok" | "revoked" | "reconnect" | "disconnecting"
    region: "na-apac" | "eu"
    scopes: string[]
    location: boolean
    createdAt: number
    createdBy?: string
    lastRefreshAt?: number
    notice?: string
  }[]
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:read on a key made by a person.
404Vehicles isn't available here.
404Not found

DELETE /v1/orgs/:orgId/vehicles/connections/:connectionId

Disconnects the organization's Tesla account: tokens removed at once, telemetry stopped; returns Tesla's page for withdrawing access (consentUrl).

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).
:connectionIdA Tesla connection's id (vconn_…); under vehicles the connection to end, rediscover or list the cars of.

Response 200

{
  consentUrl: string
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
403Connect a Tesla account in the Vehicles app.
404Not found

GET /v1/orgs/:orgId/vehicles

The garage: the cars of this space the caller holds anything on, each with their capabilities and a status summary ({ vehicles }). In a Personal space also the cars shared with them. An organisation's members see the cars they have been granted, a fleet admin all of them.

Auth: user access token or platform agent key · Scopes: vehicles:read (when orgId), vehicles:read (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).

Response 200

{
  vehicles: {
    [key: string]: unknown
  }[]
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:read on a key made by a person.
404Vehicles isn't available here.
404Not found

GET /v1/orgs/:orgId/vehicles/connections/:connectionId/vehicles

Every car Tesla shows for a connection, and which can be added: status available, claimed_here, claimed_elsewhere or unavailable, the last two with a reason in words ({ vehicles }; asks Tesla, so it is limited and 503 where that isn't wired). For a person in the app, a car in another space they manage, which this account owns, is movable with that space's fromSpaceName and fromSpaceKind: a claim moves it here. Of any other space nothing is said.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).
:connectionIdA Tesla connection's id (vconn_…); under vehicles the connection to end, rediscover or list the cars of.

Response 200

{
  vehicles: {
    fromSpaceKind?: "org" | "personal"
    fromSpaceName?: string
    movable?: boolean
    providerVehicleId?: string
    reason?: string
    vehicleId?: string
    vin: string
    name?: string
    model?: string
    accessType?: "OWNER" | "DRIVER"
    state?: string
    status: "unavailable" | "available" | "claimed_here" | "claimed_elsewhere"
  }[]
}

Errors

StatusMessage
400Not a connection id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found

POST /v1/orgs/:orgId/vehicles/connections/:connectionId/sync

Rediscover a connection's cars: queued for the worker (the API never calls Tesla), 202. List them again a moment later.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).
:connectionIdA Tesla connection's id (vconn_…); under vehicles the connection to end, rediscover or list the cars of.

Response 202

{
  queued: true
}

Errors

StatusMessage
400Not a connection id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Connection not found
409Reconnect this Tesla account first.

POST /v1/orgs/:orgId/vehicles/claim

Adds a car the connection lists to this space and starts key pairing. The VIN is only ever accepted if the connection lists it now. 201 { outcome: "claimed" | "took_over", vehicle }, 200 for exists and moved, and 409 grant_request with the holder's vehicleId when someone else holds the car and this account may not take it.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).

Request body

FieldTypeRequiredNotes
connectionIdstringYes
vinstringYesmatches ^[A-HJ-NPR-Z0-9]{17}$; trimmed; uppercased
namestringNo1–60 characters; trimmed

Response 200

{
  outcome: "exists" | "moved"
  vehicle: {
    vehicleId: string
    model?: string
    trim?: string
    vinTail: string
    accessType?: "OWNER" | "DRIVER"
    keyStatus: "pending" | "lost" | "paired" | "unpaired" | "not_required"
    periodStart?: string
  }
}

Response 201

{
  outcome: string
  vehicle: {
    vehicleId: string
    model?: string
    trim?: string
    vinTail: string
    accessType?: "OWNER" | "DRIVER"
    keyStatus: "pending" | "lost" | "paired" | "unpaired" | "not_required"
    periodStart?: string
  }
  ended: {
    vehicleId: string
  }
}
| {
  outcome: string
  vehicle: {
    vehicleId: string
    model?: string
    trim?: string
    vinTail: string
    accessType?: "OWNER" | "DRIVER"
    keyStatus: "pending" | "lost" | "paired" | "unpaired" | "not_required"
    periodStart?: string
  }
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
409Someone else holds this car. Ask them to share it with you.

GET /v1/orgs/:orgId/vehicles/profile

The space's units, currency, default tariff and the trim around a home place on shared routes.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:read (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).

Response 200

{
  units: "metric" | "imperial"
  currency: string
  defaultTariffId: null | string
  homeTrimRadiusM: null | number
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:read on a key made by a person.
404Vehicles isn't available here.
404Not found

PUT /v1/orgs/:orgId/vehicles/profile

Changes those that are given; null clears the default tariff or the trim. The default tariff is one of the space's.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).

Request body

FieldTypeRequiredNotes
units"metric" | "imperial"No
currencystringNomatches ^[A-Z]{3}$
defaultTariffIdstringNocan be null
homeTrimRadiusMintegerNo0–2000; can be null

Also checked: Say what to change.

Response 200

{
  units: "metric" | "imperial"
  currency: string
  defaultTariffId: null | string
  homeTrimRadiusM: null | number
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Tariff not found

GET /v1/orgs/:orgId/vehicles/places

The space's charging places (a centre and a radius in metres), by name.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:read (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).

Response 200

{
  places: {
    placeId: string
    name?: string
    kind: "home" | "other" | "work"
    lat: number
    lon: number
    radiusM: number
    tariffId: null | string
  }[]
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:read on a key made by a person.
404Vehicles isn't available here.
404Not found

POST /v1/orgs/:orgId/vehicles/places

Adds a charging place: a name, a centre and a radius in metres (default 100), a kind and a tariff if it has one. 201; 409 limit_reached at the space's limit.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).

Request body

FieldTypeRequiredDefaultNotes
nameany JSONYes
kindany JSONNo"other"
latnumberYes-90–90
lonnumberYes-180–180
radiusMany JSONNo100
tariffIdany JSONNo

Response 201

{
  placeId: string
  name: string
  kind: "home" | "other" | "work"
  lat: number
  lon: number
  radiusM: number
  tariffId: null | string
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Tariff not found

PATCH /v1/orgs/:orgId/vehicles/places/:placeId

Changes the fields given on a place; tariffId: null clears its tariff.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).
:placeIdA place's id: in Maps a saved place (plc_…), in Vehicles a space's charging place (vpl_…).

Request body

FieldTypeRequiredNotes
nameany JSONNo
kindany JSONNo
latnumberNo-90–90
lonnumberNo-180–180
radiusMany JSONNo
tariffIdany JSONNo

Also checked: Say what to change.

Response 200

{
  placeId: string
  name?: string
  kind: "home" | "other" | "work"
  lat: number
  lon: number
  radiusM: number
  tariffId: null | string
}

Errors

StatusMessage
400Not a place id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Place not found
404Tariff not found

DELETE /v1/orgs/:orgId/vehicles/places/:placeId

Removes a place; an automation that names it stops it, so the place stays until that automation is changed (409).

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).
:placeIdA place's id: in Maps a saved place (plc_…), in Vehicles a space's charging place (vpl_…).

Response 204 with no body.

Errors

StatusMessage
400Not a place id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Place not found

GET /v1/orgs/:orgId/vehicles/tariffs/plans

Retailer plans for a postcode, from the AER's reference data (cached a day; the NECF states only). plans is empty for a postcode no plan serves.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:read (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).
Query parameterTypeRequiredNotes
postcodestringYesmatches ^\d{4}$
retailerstringYesmatches ^[a-z0-9][a-z0-9-]{1,38}$

Response 200

{
  fetchedAt: string
  truncated?: true
  postcode: string
  state: "ACT" | "NSW" | "NT" | "QLD" | "SA" | "TAS" | "VIC" | "WA"
  retailer: string
  plans: {
    planId: string
    name: string
    brand: string
    customerType: string
    type: string
  }[]
}

Errors

StatusMessage
400Not an Australian postcode.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:read on a key made by a person.
404Vehicles isn't available here.
404Not found

GET /v1/orgs/:orgId/vehicles/tariffs

The space's tariffs, by name.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:read (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).

Response 200

{
  tariffs: {
    [key: string]: unknown
    [key: number]: unknown
  }[]
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:read on a key made by a person.
404Vehicles isn't available here.
404Not found

POST /v1/orgs/:orgId/vehicles/tariffs

Adds a tariff: flat, or time of use with windows that tile the day for weekdays and weekends. 201; 409 limit_reached.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).

Request body

FieldTypeRequiredDefaultNotes
nameany JSONYes
kind"flat" | "tou"Yes
flatTenthsCentsintegerNo0–10000
zonestringNoup to 64 characters
periodsobject[]No1–12 items
periods[].name"peak" | "shoulder" | "offpeak"Yes
periods[].days"weekday" | "weekend" | "all"Yes
periods[].fromstringYesmatches ^([01]\d|2[0-3]):[0-5]\d$
periods[].tostring | "24:00"Yesmatches ^([01]\d|2[0-3]):[0-5]\d$
periods[].tenthsCentsintegerYes0–10000
exportTenthsCentsintegerNo0–10000
supplyCentsPerDayintegerNo0–10000
supplySharebooleanNofalse

Also checked: A flat tariff has flatTenthsCents; a time-of-use tariff has zone and periods. Sharing the supply charge needs supplyCentsPerDay.

Response 201

{
  tariffId: string
  name: string
  kind: "flat" | "tou"
  supplyShare: boolean
  flatTenthsCents?: number
  zone?: string
  periods?: {
    name: "peak" | "shoulder" | "offpeak"
    days: "all" | "weekday" | "weekend"
    from: string
    to: string
    tenthsCents: number
  }[]
  exportTenthsCents?: number
  supplyCentsPerDay?: number
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found

PUT /v1/orgs/:orgId/vehicles/tariffs/:tariffId

Replaces a tariff with the one given.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).
:tariffIdA tariff's id (vtf_…).

Request body

FieldTypeRequiredDefaultNotes
nameany JSONYes
kind"flat" | "tou"Yes
flatTenthsCentsintegerNo0–10000
zonestringNoup to 64 characters
periodsobject[]No1–12 items
periods[].name"peak" | "shoulder" | "offpeak"Yes
periods[].days"weekday" | "weekend" | "all"Yes
periods[].fromstringYesmatches ^([01]\d|2[0-3]):[0-5]\d$
periods[].tostring | "24:00"Yesmatches ^([01]\d|2[0-3]):[0-5]\d$
periods[].tenthsCentsintegerYes0–10000
exportTenthsCentsintegerNo0–10000
supplyCentsPerDayintegerNo0–10000
supplySharebooleanNofalse

Also checked: A flat tariff has flatTenthsCents; a time-of-use tariff has zone and periods. Sharing the supply charge needs supplyCentsPerDay.

Response 200

{
  tariffId: string
  name: string
  kind: "flat" | "tou"
  supplyShare: boolean
  flatTenthsCents?: number
  zone?: string
  periods?: {
    name: "peak" | "shoulder" | "offpeak"
    days: "all" | "weekday" | "weekend"
    from: string
    to: string
    tenthsCents: number
  }[]
  exportTenthsCents?: number
  supplyCentsPerDay?: number
}

Errors

StatusMessage
400Not a tariff id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Tariff not found

DELETE /v1/orgs/:orgId/vehicles/tariffs/:tariffId

Removes a tariff; the default tariff and a place that uses it keep it from going (409).

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).
:tariffIdA tariff's id (vtf_…).

Response 204 with no body.

Errors

StatusMessage
400Not a tariff id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Tariff not found

GET /v1/orgs/:orgId/vehicles/geofences

The space's geofences: a circle (metres) or a polygon of up to 500 points. Enter and leave are told with the fence's name, never its coordinates.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:read (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).

Response 200

{
  geofences: {
    fenceId: string
    name?: string
    shape: {
      type: "circle"
      lat: number
      lon: number
      radiusM: number
    } | {
      type: "polygon"
      points: number[][]
    }
    enabled: boolean
    notifyOn: "both" | "leave" | "enter"
  }[]
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:read on a key made by a person.
404Vehicles isn't available here.
404Not found

POST /v1/orgs/:orgId/vehicles/geofences

Adds a geofence: a circle or a polygon, sealed at rest. 201; 400 for an antimeridian crossing; 409 limit_reached.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).

Request body

FieldTypeRequiredDefaultNotes
nameany JSONYes
shapeobject | objectYes
enabledbooleanNotrue
notifyOn"enter" | "leave" | "both"No"both"

Response 201

{
  fenceId: string
  name: string
  shape: {
    type: "circle"
    lat: number
    lon: number
    radiusM: number
  } | {
    type: "polygon"
    points: number[][]
  }
  enabled: boolean
  notifyOn: "both" | "leave" | "enter"
}

Errors

StatusMessage
400A fence can't cross the antimeridian.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found

PATCH /v1/orgs/:orgId/vehicles/geofences/:fenceId

Changes the fields given on a geofence.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).
:fenceIdA geofence's id (vfn_…).

Request body

FieldTypeRequiredNotes
nameany JSONNo
shapeobject | objectNo
enabledbooleanNo
notifyOn"enter" | "leave" | "both"No

Also checked: Say what to change.

Response 200

{
  fenceId: string
  name?: string
  shape: {
    type: "circle"
    lat: number
    lon: number
    radiusM: number
  } | {
    type: "polygon"
    points: number[][]
  }
  enabled: boolean
  notifyOn: "both" | "leave" | "enter"
}

Errors

StatusMessage
400Not a geofence id.
400A fence can't cross the antimeridian.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Geofence not found

DELETE /v1/orgs/:orgId/vehicles/geofences/:fenceId

Removes a geofence; an automation triggered by it keeps it from going (409).

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).
:fenceIdA geofence's id (vfn_…).

Response 204 with no body.

Errors

StatusMessage
400Not a geofence id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Geofence not found

GET /v1/orgs/:orgId/vehicles/automations

The space's automations: a trigger, conditions and up to five actions on the cars named, run with the creator's capabilities. The engine that runs them is not built, so these are stored and shown, and none fires yet.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:read (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).

Response 200

{
  automations: {
    [key: string]: unknown
    [key: number]: unknown
  }[]
}

Errors

StatusMessage
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:read on a key made by a person.
404Vehicles isn't available here.
404Not found

POST /v1/orgs/:orgId/vehicles/automations

Adds an automation. Command actions follow the confirmation table: a tap is stored, a hold needs a fresh step-up, a step-up command is refused. 201.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).

Request body

FieldTypeRequiredDefaultNotes
nameany JSONYes
enabledbooleanYes
vehicleIdsstring[]Yes1–50 items
triggerobject | object | object | object | object | object | object | object | objectYes
conditionsobjectYes
conditions.insidePlaceIdstringNo
conditions.windowobjectNo
conditions.window.fromstringYesmatches ^([01]\d|2[0-3]):[0-5]\d$
conditions.window.tostringYesmatches ^([01]\d|2[0-3]):[0-5]\d$
conditions.window.zonestringYesup to 64 characters
conditions.socMinintegerNo0–100
conditions.socMaxintegerNo0–100
conditions.pluggedbooleanNo
conditions.nobodyInsidebooleanNo
actions(object | object)[]Yes1–5 items
enabledany JSONNotrue
conditionsobjectNo{}
conditions.insidePlaceIdstringNo
conditions.windowobjectNo
conditions.window.fromstringYesmatches ^([01]\d|2[0-3]):[0-5]\d$
conditions.window.tostringYesmatches ^([01]\d|2[0-3]):[0-5]\d$
conditions.window.zonestringYesup to 64 characters
conditions.socMinintegerNo0–100
conditions.socMaxintegerNo0–100
conditions.pluggedbooleanNo
conditions.nobodyInsidebooleanNo

Response 201

{
  automationId: string
  name: string
  createdBy: string
  enabled: boolean
  vehicleIds: string[]
  trigger: {
    type: "schedule"
    at: string
    days: ("sun" | "mon" | "tue" | "wed" | "thu" | "fri" | "sat")[]
    zone: string
  } | {
    type: "once"
    at: string
  } | {
    type: "geofence"
    fenceId: string
    on: "leave" | "enter"
  } | {
    type: "plugged"
    on: "out" | "in"
  } | {
    type: "charge_reached"
    socPct: number
  } | {
    type: "soc_below"
    socPct: number
  } | {
    type: "outside_temp"
    aboveC?: number
    belowC?: number
  } | {
    type: "drive_ended"
  } | {
    type: "left_unlocked"
    minutes: number
  }
  conditions: {
    insidePlaceId?: string
    window?: {
      from: string
      to: string
      zone: string
    }
    socMin?: number
    socMax?: number
    plugged?: boolean
    nobodyInside?: boolean
  }
  actions: {
    type: "command"
    command: string
    args: {
      [key: string]: unknown
    }
    confirmedAt?: number
  } | {
    type: "notify"
    message: string
    confirmedAt?: number
  }[]
  createdAt: number
  updatedAt: number
}

Errors

StatusMessage
400"…" isn't a command.
400…: …
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Vehicle not found
404Geofence not found
404Place not found

PATCH /v1/orgs/:orgId/vehicles/automations/:automationId

Changes an automation. Only its creator changes the cars, trigger, conditions or actions (403 not_creator); another admin may switch or rename it.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).
:automationIdAn automation's id (vau_…).

Request body

FieldTypeRequiredNotes
nameany JSONNo
enabledany JSONNo
vehicleIdsany JSONNo
triggerobject | object | object | object | object | object | object | object | objectNo
conditionsobjectNo
conditions.insidePlaceIdstringNo
conditions.windowobjectNo
conditions.window.fromstringYesmatches ^([01]\d|2[0-3]):[0-5]\d$
conditions.window.tostringYesmatches ^([01]\d|2[0-3]):[0-5]\d$
conditions.window.zonestringYesup to 64 characters
conditions.socMinintegerNo0–100
conditions.socMaxintegerNo0–100
conditions.pluggedbooleanNo
conditions.nobodyInsidebooleanNo
actionsany JSONNo

Also checked: Say what to change.

Response 200

{
  [key: string]: unknown
}

Errors

StatusMessage
400Not a automation id.
400"…" isn't a command.
400…: …
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Automation not found
404Vehicle not found
404Geofence not found
404Place not found

DELETE /v1/orgs/:orgId/vehicles/automations/:automationId

Removes an automation. 204.

Auth: user access token or platform agent key · Scopes: vehicles:admin (when orgId), vehicles:write (when actor.type === "user")

Path parameterDescription
:orgIdOrganization id (org_…).
:automationIdAn automation's id (vau_…).

Response 204 with no body.

Errors

StatusMessage
400Not a automation id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
403Its owner hasn't let API keys use their Personal Vehicles (Vehicles → Privacy).
403Vehicles needs vehicles:write on a key made by a person.
404Vehicles isn't available here.
404Not found
404Automation not found

GET /v1/vehicles/:vehicleId

META and LIVE with the caller's capabilities, telemetry health and key status. The position only with location.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.

Response 200

{
  restorableUntil?: string
  ended?: {
    at?: string
    reason?: "removed" | "access_lost" | "new_owner" | "ownership_changed"
  }
  pictureMode?: "tesla" | "drawing"
  vehicleId: string
  name: string
  model?: string
  trim?: string
  capabilities: string[]
  health?: {
    key: string
    connection: string
    checkedAt?: string
    profile?: "standard" | "economy"
    telemetry: "error" | "pending" | "off" | "configured" | "streaming" | "waiting_for_key" | "firmware_too_old" | "limit_reached" | "unsupported" | "suspended" | "unsigned"
    telemetryLabel: string
    polling: boolean
  }
  position?: {
    [key: string]: unknown
  }
  state?: "offline" | "charging" | "parked" | "driving" | "asleep"
  lastSeen?: string
  battery?: {
    soc?: number
    rangeKm?: number
    estRangeKm?: number
  }
  charge?: {
    plugged?: boolean
    portOpen?: boolean
    kw?: number
    limit?: number
    etaMin?: number
  }
  locks?: {
    locked?: boolean
    doorsOpen?: string[]
    windowsOpen?: string[]
    trunk?: "open" | "closed"
    frunk?: "open" | "closed"
    powerLiftgate?: boolean
  }
  climate?: {
    setpoint?: {
      driverC?: number
      passengerC?: number
    }
    on?: boolean
    insideC?: number
    outsideC?: number
  }
  sentry?: boolean
  odometerKm?: number
  speedKmh?: number
  gear?: "N" | "D" | "R" | "P"
  tyres?: {
    kpa?: number[]
  }
  software?: {
    update?: null | {
      status: "available" | "scheduled" | "downloading" | "installing"
      version: string
      minutes?: number
      percent?: number
    }
    version?: string
  }
  colour?: string
  art?: string
  picture?: {
    views: {
      "3qtr"?: {
        srcset: {
          url: string
          width: number
          height: number
        }[]
        box: {
          x: number
          y: number
          w: number
          h: number
        }
      }
      side?: {
        srcset: {
          url: string
          width: number
          height: number
        }[]
        box: {
          x: number
          y: number
          w: number
          h: number
        }
      }
    }
    approximate?: true
  }
}

Errors

StatusMessage
400Not a vehicle id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

POST /v1/vehicles/:vehicleId/watch

Renews the live lease (open apps send it every 30 s while the car is on screen). 204.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.

Response 204 with no body.

Errors

StatusMessage
400Not a vehicle id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.
409This car's period has ended.

GET /v1/vehicles/:vehicleId/key

Pairing status, the pairing link and what to do next; opening it restarts the key checks when they have lapsed.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.

Response 200

{
  checkedAt?: string
  status: "pending" | "lost" | "paired" | "unpaired" | "not_required"
  required: boolean
  link?: string
  requirements: ("tesla_app_same_account" | "car_online")[]
  keyCount?: number
  keysFull: boolean
  keyListUrl?: string
  firmware?: string
  pollMs?: number
  vehicleId: string
}

Errors

StatusMessage
400Not a vehicle id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.
409This car's period has ended.

GET /v1/vehicles/:vehicleId/trips

Drives, newest first. class, tag, driver, min (km) filter; cursor resumes across months.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
Query parameterTypeRequiredNotes
fromstringNoup to 40 characters
tostringNoup to 40 characters
cursorstringNoup to 700 characters
limitintegerNo1–100; coerced from a string
class"business" | "personal" | "commute" | "private"No
tagstringNo1–40 characters; trimmed
driverstringNoup to 60 characters
minnumberNo0–100000; coerced from a string
nearstringNomatches ^-?\d{1,2}(\.\d{1,7})?,-?\d{1,3}(\.\d{1,7})?(,\d{2,5})?$

Response 200

{
  next?: string
  trips: {
    hasTrack: boolean
    path?: {
      lat: number
      lon: number
    }[]
    startPlace?: string
    endPlace?: string
    score?: number
    secondsOver?: {
      [key: string]: number
    }
    kmOver?: {
      [key: string]: number
    }
    harshAccel?: number
    harshBraking?: number
    harshCornering?: number
    tripId: string
    startedAt?: string
    endedAt?: string
    distanceKm?: number
    energyKwh?: number
    whPerKm?: number
    socFrom?: number
    socTo?: number
    maxSpeedKmh?: number
    avgMovingSpeedKmh?: number
    class?: "private" | "personal" | "business" | "commute"
    purpose?: string
    tags?: string[]
    driverId?: string
    outsideCMin?: number
    outsideCMax?: number
    elevationGainM?: number
    elevationLossM?: number
    assistedKm?: number
    weather?: string
    mine: boolean
  }[]
}

Errors

StatusMessage
400Not a vehicle id.
400near: not a position.
400near: 50 to 50,000 metres.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

GET /v1/vehicles/:vehicleId/trips/current

The drive still open, as far as the car has gone: its points after since, for the app that draws it while it goes (it asks every 5 s, and only for what is new). Needs trips and location (shown always: a grant that shows the position only while the holder drives never does, as in the detail), and a grant whose trips filter shows the open drive, which has no class or driver yet: only every drive, with no class tag. Without one, or without a drive open, the answer is the same open: false.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
Query parameterTypeRequiredNotes
sincestringNoup to 40 characters

Response 200

{
  open: false
  points: []
}
| {
  truncated?: true
  through?: number
  open: true
  tripId: string
  startedAt?: string
  points: {
    t: number
    lat: number
    lon: number
    speedKmh: number
    headingDeg: number
    soc: number
    powerKw: number
    limitKmh?: number
  }[]
}

Errors

StatusMessage
400Not a vehicle id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

GET /v1/vehicles/:vehicleId/trips/:tripId

A drive: the summary and, for those who may see where it went, the thumbnail path. ?points=1 adds the decoded track (the server opens it), after since when given.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
:tripIdA drive's id (drv_…), as the drives list gives it.
Query parameterTypeRequiredNotes
points"0" | "1"No
sincestringNoup to 40 characters

Response 200

{
  trip: {
    hasTrack: boolean
    path?: {
      lat: number
      lon: number
    }[]
    startPlace?: string
    endPlace?: string
    score?: number
    secondsOver?: {
      [key: string]: number
    }
    kmOver?: {
      [key: string]: number
    }
    harshAccel?: number
    harshBraking?: number
    harshCornering?: number
    tripId: string
    startedAt?: string
    endedAt?: string
    distanceKm?: number
    energyKwh?: number
    whPerKm?: number
    socFrom?: number
    socTo?: number
    maxSpeedKmh?: number
    avgMovingSpeedKmh?: number
    class?: "private" | "personal" | "business" | "commute"
    purpose?: string
    tags?: string[]
    driverId?: string
    outsideCMin?: number
    outsideCMax?: number
    elevationGainM?: number
    elevationLossM?: number
    assistedKm?: number
    weather?: string
    mine: boolean
  }
  events: {
    eventId: string
    kind: string
    at?: string
    severity?: string
    values?: {
      [key: string]: boolean | number
    }
  }[]
  track: {
    available: boolean
    count?: number
    points?: {
      [key: string]: undefined | number
    }[]
  }
}

Errors

StatusMessage
400Not a vehicle id.
400Not a drive id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

GET /v1/vehicles/:vehicleId/stats/today

Today's drives: the distance and energy, and the count for those who see every drive, as totals and nothing finer. The day is cut in the zone asked for (?tz=, a place's IANA name) for those who see every drive, else in the car's space's. view is enough for the distance and energy, whatever the grant's trip filters hide, because a sum names no drive, time or place (docs/vehicles/api.md → Today's totals).

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
Query parameterTypeRequiredNotes
tzstringNo1–64 characters; trimmed

Response 200

{
  drives?: number
  day: string
  timeZone: string
  from?: string
  to?: string
  distanceKm: number
  energyKwh: number
}

Errors

StatusMessage
400Not a vehicle id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

GET /v1/vehicles/:vehicleId/charges

Charging sessions: with trips, the places; with costs, what they cost. Either opens the list.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
Query parameterTypeRequiredNotes
fromstringNoup to 40 characters
tostringNoup to 40 characters
cursorstringNoup to 700 characters
limitintegerNo1–100; coerced from a string

Response 200

{
  next?: string
  charges: {
    place?: string
    costCents?: number
    costSource?: string
    tariffId?: string
    chargeId: string
    startedAt?: string
    endedAt?: string
    kind?: "home" | "other" | "work" | "supercharger"
    kwhAdded?: number
    kwhDrawn?: number
    socFrom?: number
    socTo?: number
    maxKw?: number
  }[]
}

Errors

StatusMessage
400Not a vehicle id.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

GET /v1/vehicles/:vehicleId/idles

Parked periods (battery lost while parked, with Sentry and climate shares).

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
Query parameterTypeRequiredNotes
fromstringNoup to 40 characters
tostringNoup to 40 characters
cursorstringNoup to 700 characters
limitintegerNo1–100; coerced from a string

Response 200

{
  idles: []
  hidden: true
}
| {
  next?: string
  idles: {
    place?: string
    idleId: string
    startedAt?: string
    endedAt?: string
    socLostPct?: number
    kwhLost?: number
    sentryFraction?: number
    climateFraction?: number
    asleepFraction?: number
  }[]
}

Errors

StatusMessage
400Not a vehicle id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

POST /v1/vehicles/:vehicleId/commands/:commandName

Sends a command through K2's command service (docs/vehicles/commands.md → The service): the capability each needs, its arguments, the grant's terms, the confirmation (a nonce for a hold, the token's step-up), the limits and the queue are the service's, from commandDef. Idempotency-Key is required and makes a repeat return the first result. 200 { commandId, status: "succeeded" }, 202 { commandId, status, approvalId } while it is queued or waits for approval, and the service's refusals with their status and code: 409 confirm (with a nonce), 403 terms, step_up, approval_required, 409 boot_open (a lock while the boot or front trunk is open) and no_update (a software update the car hasn't got ready), 424 vehicle (with Tesla's reason), 429 (Retry-After), 422 bad_args and unsupported (Close Trunk on a boot that closes by hand).

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
:commandNameA command's name, such as lock, climate_on or charge_limit; its capability decides who may send it.

Request body

FieldTypeRequiredNotes
argsobjectNokeys up to 40 characters; values: any JSON
noncestringNo1–100 characters
fixobjectNo
fix.latnumberYes-90–90
fix.lonnumberYes-180–180
fix.fixAtintegerYes0–8640000000000000

Response 200

{
  commandId: string
  status: string
}

Response 202

{
  commandId: string
  status: "unknown" | "queued" | "failed" | "sent" | "succeeded" | "needs_approval" | "waking"
  approvalId: null | string
}

Errors

StatusMessage
400Send an Idempotency-Key header, so a repeated request returns the first result.
400Not a vehicle id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Unknown command.
404Vehicles isn't available here.
409This car's period has ended.

GET /v1/vehicles/:vehicleId/commands/:commandId

A command's state: your own, or anyone's with share.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
:commandIdA command's id (cmd_…), as sending it returned it.

Response 200

{
  at?: string
  approvalId: null | string
  reason?: string
  commandId: string
  command: string
  status: "unknown" | "queued" | "failed" | "sent" | "succeeded" | "needs_approval" | "waking"
}

Errors

StatusMessage
400Not a vehicle id.
400Not a command id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

DELETE /v1/vehicles/:vehicleId

/** Removes a car with a 7-day undo. For a period that ended some other way (sold, access lost), ?history=delete deletes its history for good.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
Query parameterTypeRequiredNotes
history"delete"No

Response 200

{
  vehicleId: string
  removedAt?: string
  restorableUntil?: string
}
| {
  vehicleId: string
  historyDeletion: string
}

Errors

StatusMessage
400Not a vehicle id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.
409This car's period has ended.

POST /v1/vehicles/:vehicleId/restore

Undoes a removal within 7 days (the connection must still list the car and the VIN be free).

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.

Response 200

{
  vehicle: {
    vehicleId: string
    model?: string
    trim?: string
    vinTail: string
    accessType?: "OWNER" | "DRIVER"
    keyStatus: "pending" | "lost" | "paired" | "unpaired" | "not_required"
    periodStart?: string
  }
}

Errors

StatusMessage
400Not a vehicle id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

PUT /v1/vehicles/:vehicleId/settings

The car's settings: its name (1 to 60 characters, no control or invisible formatting characters) and its picture, Tesla's or our drawing (pictureMode on both rows; docs/vehicles/pictures.md). Audited as vehicle.settings_update with the change, never the value.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.

Request body

FieldTypeRequiredNotes
namestringNoup to 200 characters
picture"tesla" | "drawing"No

Also checked: Send a name or a picture.

Response 200

{
  pictureMode?: "tesla" | "drawing"
  name?: string
  vehicleId: string
}

Errors

StatusMessage
400Not a vehicle id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.
404Vehicle not found
409This car's period has ended.

POST /v1/vehicles/:vehicleId/picture

Reads the car's configuration again and resolves its picture (the owner's Refresh picture): 202, queued for the worker, which alone reads Tesla and only when the car is online. 429 with Retry-After within a day of the last read, 409 for a finished period.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.

Response 202

{
  lastReadAt?: string
  queued: true
}

Errors

StatusMessage
400Not a vehicle id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.
409This car's period has ended.

GET /v1/vehicles/:vehicleId/events

What happened to the car, newest first: alerts and the car being moved while parked, and with the drives' events (speeding, harsh braking) for those who see every drive and hold behaviour. kind narrows it. An event the caller may not see is left out as if it were not there, and so is an alert raised while the car was in a drive they do not see (its time would place that drive); next is sealed.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
Query parameterTypeRequiredNotes
fromstringNoup to 40 characters
tostringNoup to 40 characters
cursorstringNoup to 700 characters
limitintegerNo1–100; coerced from a string
kindstringNo1–60 characters; matches ^[A-Za-z0-9_.:-]+$; trimmed

Response 200

{
  next?: string
  events: {
    tripId?: string
    eventId: string
    kind: string
    at?: string
    severity?: "warning" | "critical" | "info"
    values?: {
      [key: string]: boolean | number
    }
  }[]
}

Errors

StatusMessage
400Not a vehicle id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

GET /v1/vehicles/:vehicleId/battery

The battery now, and its capacity over time as the charges give it: each charge that took the state of charge up by 20 points or more says what the battery holds (kWh added over the points gained), and a month's figure is the median. It is an estimate from charging, not a measurement of the pack; there is no health percentage until the car's original capacity is known.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
Query parameterTypeRequiredNotes
fromany JSONYes
toany JSONYes

Response 200

{
  truncated?: true
  now: {
    soc?: number
    rangeKm?: number
    estRangeKm?: number
    odometerKm?: number
    plugged?: boolean
    chargeLimitPct?: number
    chargeKw?: number
  }
  capacity: {
    cycles?: number
    latestKwh?: number
    method: string
    unit: string
    months: {
      charges?: number
      month: string
      kwh: number
    }[]
  }
  from?: string
  to?: string
}

Errors

StatusMessage
400Not a vehicle id.
400Ask for at most 730 days at a time.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

GET /v1/vehicles/:vehicleId/tyres

The four tyre pressures as the car last reported them (kPa), and the tyre alerts of the last 90 days (left out when raised during a drive the caller does not see, as in the events). There is no history yet.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.

Response 200

{
  warnings: {
    eventId: string
    kind: string
    at?: string
    ongoing: boolean
  }[]
  reportedAt?: string
  kpa?: {
    fl?: number
    fr?: number
    rl?: number
    rr?: number
  }
}

Errors

StatusMessage
400Not a vehicle id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

GET /v1/vehicles/:vehicleId/efficiency

Wh/km by outside temperature and speed, from the drives the caller sees (so a holder of some drives gets their own picture, and the count says how many that was): each cell is the distance-weighted average of the drives in that 5 °C and 20 km/h band, with the distance and drives in it. The real-world range is the battery's estimated capacity at the state of charge over the average. There is no model of what a drive should have used, nor climate, wind or tyre effects, yet.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
Query parameterTypeRequiredNotes
fromany JSONYes
toany JSONYes

Response 200

{
  truncated?: true
  method: string
  realWorldRangeKm?: number
  matrix: {
    outsideC: [number, number]
    speedKmh: [number, number]
    whPerKm: number
    km: number
    drives: number
  }[]
  whPerKm?: number
  from?: string
  to?: string
  drives: number
  distanceKm: number
}

Errors

StatusMessage
400Not a vehicle id.
400Ask for at most 365 days at a time.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

GET /v1/vehicles/:vehicleId/costs

What charging has cost in a range (default 90 days): the priced charges' cost, energy and count, by where the price came from and by kind of charge. A charge nobody priced counts in unpriced, not as free. The same for every holder of costs (no routes or places, and the drive filters don't apply to charges); cost per km only for a caller who sees every drive (with any other range a caller could difference two ranges into a day's distance). There are no tariffs or fuel comparison yet, so a price is whatever was set on the charge.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
Query parameterTypeRequiredNotes
fromany JSONYes
toany JSONYes

Response 200

{
  truncated?: true
  centsPerKwh?: number
  centsPerKm?: number
  from?: string
  to?: string
  currency: string
  charges: number
  kwhAdded: number
  priced: {
    charges: number
    kwh: number
    costCents: number
  }
  unpriced: {
    charges: number
    kwh: number
  }
  bySource: {
    [key: string]: string | number
    charges: number
    kwh: number
    costCents: number
  }[]
  byKind: {
    [key: string]: string | number
    charges: number
    kwh: number
    costCents: number
  }[]
}

Errors

StatusMessage
400Not a vehicle id.
400Ask for at most 366 days at a time.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

GET /v1/vehicles/:vehicleId/logbook

The business drives of a range for an ATO logbook (default 90 days, at most 15 months): each one's date, odometer at the start and end, kilometres and purpose, oldest first, from the drives the caller sees. The summary says how many lack a purpose. Only a caller who sees every drive of every class gets what needs them all: business-use percent, the whole period's kilometres and odometer span, and the gaps (14 days or more with no drive); partial: true says the rest is from what they see. Whether the range is a valid logbook period (12 continuous weeks) is weeks and meetsTwelveWeeks. Storing a period is not built yet.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
Query parameterTypeRequiredNotes
fromany JSONYes
toany JSONYes

Response 200

{
  truncated?: true
  openingOdometerKm?: number
  closingOdometerKm?: number
  totalKm?: number
  businessPercent?: number
  gaps?: {
    from: string
    to: string
  }[]
  from?: string
  to?: string
  weeks: number
  meetsTwelveWeeks: boolean
  partial: boolean
  trips: {
    tripId: string
    date?: string
    startOdometerKm?: number
    endOdometerKm?: number
    km?: number
    purpose: null | string
  }[]
  businessTrips: number
  businessKm: number
  missingPurpose: number
}

Errors

StatusMessage
400Not a vehicle id.
400Ask for at most 456 days at a time.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

GET /v1/vehicles/:vehicleId/settings

The car's settings that exist so far: its name and colour, whether its PINs are set (never the PINs), the key's state and the telemetry profile. PINs and the key are the owner's to know.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.

Response 200

{
  pinsSet?: {
    speedLimit: boolean
    valet: boolean
  }
  keyStatus?: "pending" | "lost" | "paired" | "unpaired" | "not_required"
  telemetryProfile?: "standard" | "economy"
  vehicleId: string
  name: string
  model?: string
  colour?: string
}

Errors

StatusMessage
400Not a vehicle id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

GET /v1/vehicles/:vehicleId/commands

The commands sent to the car, newest first: the caller's own, and everyone's for a holder of share. K2's history; actor is named only for someone else's. next is sealed.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
Query parameterTypeRequiredNotes
fromany JSONYes
toany JSONYes
cursorany JSONYes
limitany JSONYes

Response 200

{
  next?: string
  commands: {
    actor?: string
    mine: boolean
    parameterClasses?: string[]
    at?: string
    code?: string
    reason?: string
    commandId: string
    command: string
    via: "key" | "app" | "caity" | "automation"
    status: string
  }[]
}

Errors

StatusMessage
400Not a vehicle id.
400Ask for at most 366 days at a time.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

PATCH /v1/vehicles/:vehicleId/trips

Classifies and tags drives in bulk: { ids (up to 50), class?, purpose? (null clears), tags? (replaces) }. Needs manage and trips, and only drives the caller sees change: an id that is missing, outside the car's period or hidden from the caller is in missing, the same for all three. Audited in an organisation's log (the change and how many, never the purpose).

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.

Request body

FieldTypeRequiredNotes
idsstring[]Yes1–50 items; each matches ^drv_[0-9a-z]{8,40}$
class"business" | "personal" | "commute" | "private"No
purposeany JSONNocan be null
tagsany JSON[]Noup to 10 items

Also checked: Say what to change: class, purpose or tags.

Response 200

{
  updated: string[]
  missing: string[]
}

Errors

StatusMessage
400Not a vehicle id.
400Send drives from at most 12 separate stretches at a time.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.
409This car's period has ended.

GET /v1/vehicles/:vehicleId/charges/:chargeId

One charge session: its summary (the place only for those who see places, the cost only for costs), how long, the average power and the charging efficiency (energy added over drawn), and its curve, power in kW and the state of charge every 30 seconds from curve.startedAt. For trips or costs, as the list. The curve carries no position. The cost by tariff period needs the tariff engine, which is not built, so a price is the one the charge has.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
:chargeIdA charge's id (chg_…), as the charges list gives it.

Response 200

{
  curve: null | {
    startedAt?: string
    stepS: number
    kw: number[]
    soc: number[]
  }
  centsPerKwh?: number
  efficiencyPct?: number
  avgKw?: number
  durationMin?: number
  place?: string
  costCents?: number
  costSource?: string
  tariffId?: string
  chargeId: string
  startedAt?: string
  endedAt?: string
  kind?: "home" | "other" | "work" | "supercharger"
  kwhAdded?: number
  kwhDrawn?: number
  socFrom?: number
  socTo?: number
  maxKw?: number
}

Errors

StatusMessage
400Not a vehicle id.
400Not a charge id.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.
404Charge not found

PATCH /v1/vehicles/:vehicleId/charges/:chargeId

Overrides a charge's price or place: { costCents?, place? (null clears) }. Needs manage; a price needs costs and a place needs the sight of places (every drive of every class, or the owner). A price set by hand says costSource: "manual". Audited in an organisation's log.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
:chargeIdA charge's id (chg_…), as the charges list gives it.

Request body

FieldTypeRequiredNotes
costCentsintegerNo0–1000000
placeany JSONNocan be null

Also checked: Say what to change: costCents or place.

Response 200

{
  place?: null | string
  costCents?: number
  costSource?: string
  chargeId: string
}

Errors

StatusMessage
400Not a vehicle id.
400Not a charge id.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.
404Charge not found
409This car's period has ended.

GET /v1/vehicles/:vehicleId/keys

The keychain as last read, labelled, and the state of the read. The table only: open apps poll it while a read runs.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.

Response 200

{
  vehicleId: string
  keyCount: null | number
  maxKeys: number
  readable: boolean
  entries: {
    keyId: string
    slot: number
    kind: "phone" | "app" | "unread" | "this_app" | "key_card" | "driver_phone" | "fob_or_phone"
    label: string
    role: null | string
    driverId: null | string
    leaving: boolean
    firstSeenAt?: string
  }[]
  readAt: null | string
  reading: boolean
  lastOutcome: null | "ok" | "partial" | "failed" | "reconnect" | "asleep" | "refused" | "rate_limited"
  lastTriedAt: null | string
  countChanged: boolean
  nextReadAt: null | string
  howToUrl: string
}

Errors

StatusMessage
400Not a vehicle id.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.
409This car's period has ended.

POST /v1/vehicles/:vehicleId/keys/read

Reads the car's keychain again: 202 and a vehicles.keys_read job. Tesla bills each question and the car must be awake (it is never woken for this). 429 with Retry-After inside the cooldown or while a read runs; 409 for a car that doesn't use Tesla's command protocol (pre-2021 Model S and X).

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.

Response 202

{
  queued: true
}

Errors

StatusMessage
400Not a vehicle id.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.
409This car's period has ended.

GET /v1/vehicles/:vehicleId/drivers

The car's Tesla drivers and pending invitations (Tesla's sharing in its own app), each driver with how many of their keys were on the car when it was last read. A car added with a driver's account (not_owner), a connection whose scopes Tesla refuses (not_allowed) or one that needs signing in again (reconnect) is available: false with the reason, so the page still shows the rest.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.

Response 200

{
  available: false
  reason: string
  drivers: []
  invitations: []
}
| {
  available: true
  drivers: {
    driverId: string
    name: string
    keysOnCar: number
  }[]
  invitations: {
    inviteId: string
    link: null | string
    expiresAt: null | string
  }[]
}

Errors

StatusMessage
400Not a vehicle id.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.
409This car's period has ended.

POST /v1/vehicles/:vehicleId/drivers/invitations

A single-use link to Tesla's app that makes its account a driver of the car for good (it lapses unused after 24 hours). Step-up; audited.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.

Response 201

{
  inviteId: string
  link?: string
  expiresAt: null | string
}

Errors

StatusMessage
400Not a vehicle id.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.
409This car's period has ended.

POST /v1/vehicles/:vehicleId/drivers/invitations/:inviteId/revoke

Revokes a pending invitation: its link stops working. It only takes access away, so no step-up; audited.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
:inviteIdInvite id (inv_…); under vehicles, Tesla's id for a driver invitation, as the drivers list gives it.

Response 200

{
  revoked: true
}

Errors

StatusMessage
400Not a invitation id.
400Not a vehicle id.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.
409This car's period has ended.

DELETE /v1/vehicles/:vehicleId/drivers/:driverId

Removes a Tesla driver: their access in Tesla's app, and their phone keys on the car when it is next online. Step-up; audited.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
:driverIdA Tesla driver's id, as Tesla gives it (digits): the car's drivers list names it.

Response 200

{
  removed: true
}

Errors

StatusMessage
400Not a driver id.
400Not a vehicle id.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.
409This car's period has ended.

GET /v1/vehicles/:vehicleId/imports

The car's imports, newest first.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.

Response 200

{
  imports: {
    importId: string
    source: "tessie_export" | "tessie_template" | "vehicles_csv"
    status: "ready" | "expired" | "done" | "failed" | "cancelled" | "uploading" | "refused" | "checking" | "importing" | "undoing" | "undone"
    version: number
    progress: number
    files: {
      name: string
      bytes: number
    }[]
    fileNames: string[]
    options: {
      timeZone?: string
      currency?: string
      businessTags?: string[]
    }
    summary: null | {
      from?: string
      to?: string
      kinds: {
        drive: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        idle: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        battery: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        charge: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        tyre: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
      }
      rows: number
      invalidRows: number
      distanceKm: number
      kwhUsed: number
      kwhAdded: number
      drivesByMonth: {
        [key: string]: number
      }
      carCheck: "vin" | "odometer"
      locations: boolean
      units?: "km" | "mi"
      timeZone?: string
      repeatedHour: number
      trimmed: number
    }
    problems: {
      file: number
      row: number
      column?: string
      code: string
    }[]
    problemCount: number
    refusal: null | {
      at?: string
      code: string
      file?: number
      missing?: string[]
      unexpected?: string[]
      limit?: string
    }
    from: null | string
    to: null | string
    written: number
    createdAt?: string
    checkedAt: null | string
    committedAt: null | string
    undoneAt: null | string
  }[]
}

Errors

StatusMessage
400Not a vehicle id.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

POST /v1/vehicles/:vehicleId/imports

A new import and an upload link per file (one key, length and SHA-256, an hour). 413 over a limit, 409 import_open, 429 past the day's.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.

Request body

FieldTypeRequiredNotes
source"tessie_export" | "tessie_template" | "vehicles_csv"Yes
filesobject[]Yes1–1,000 items
files[].namestringYes1–200 characters; trimmed
files[].bytesintegerYes1–17179869184
files[].sha256stringYesmatches ^[A-Za-z0-9+/]{43}=$

Response 201

{
  importId: string
  import: {
    importId: string
    source: "tessie_export" | "tessie_template" | "vehicles_csv"
    status: "ready" | "expired" | "done" | "failed" | "cancelled" | "uploading" | "refused" | "checking" | "importing" | "undoing" | "undone"
    version: number
    progress: number
    files: {
      name: string
      bytes: number
    }[]
    fileNames: string[]
    options: {
      timeZone?: string
      currency?: string
      businessTags?: string[]
    }
    summary: null | {
      from?: string
      to?: string
      kinds: {
        drive: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        idle: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        battery: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        charge: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        tyre: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
      }
      rows: number
      invalidRows: number
      distanceKm: number
      kwhUsed: number
      kwhAdded: number
      drivesByMonth: {
        [key: string]: number
      }
      carCheck: "vin" | "odometer"
      locations: boolean
      units?: "km" | "mi"
      timeZone?: string
      repeatedHour: number
      trimmed: number
    }
    problems: {
      file: number
      row: number
      column?: string
      code: string
    }[]
    problemCount: number
    refusal: null | {
      at?: string
      code: string
      file?: number
      missing?: string[]
      unexpected?: string[]
      limit?: string
    }
    from: null | string
    to: null | string
    written: number
    createdAt?: string
    checkedAt: null | string
    committedAt: null | string
    undoneAt: null | string
  }
  uploads: {
    url: string
    headers: {
      [key: string]: string
    }
  }[]
}

Errors

StatusMessage
400Not a vehicle id.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

POST /v1/vehicles/:vehicleId/imports/:importId/check

Checks each upload's size and checksum, then queues the check (again with new options): 202.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
:importIdTakeout import id (imp_…); under me/food a Food import (fim_…); under vehicles an import of a car's history (vim_…), as the imports list gives it.

Request body

FieldTypeRequiredNotes
timeZonestringNo1–64 characters; trimmed
currencystringNomatches ^[A-Z]{3}$
businessTagsstring[]Noup to 20 items; each 1–40 characters, trimmed

Response 202

{
  import: {
    importId: string
    source: "tessie_export" | "tessie_template" | "vehicles_csv"
    status: "ready" | "expired" | "done" | "failed" | "cancelled" | "uploading" | "refused" | "checking" | "importing" | "undoing" | "undone"
    version: number
    progress: number
    files: {
      name: string
      bytes: number
    }[]
    fileNames: string[]
    options: {
      timeZone?: string
      currency?: string
      businessTags?: string[]
    }
    summary: null | {
      from?: string
      to?: string
      kinds: {
        drive: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        idle: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        battery: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        charge: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        tyre: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
      }
      rows: number
      invalidRows: number
      distanceKm: number
      kwhUsed: number
      kwhAdded: number
      drivesByMonth: {
        [key: string]: number
      }
      carCheck: "vin" | "odometer"
      locations: boolean
      units?: "km" | "mi"
      timeZone?: string
      repeatedHour: number
      trimmed: number
    }
    problems: {
      file: number
      row: number
      column?: string
      code: string
    }[]
    problemCount: number
    refusal: null | {
      at?: string
      code: string
      file?: number
      missing?: string[]
      unexpected?: string[]
      limit?: string
    }
    from: null | string
    to: null | string
    written: number
    createdAt?: string
    checkedAt: null | string
    committedAt: null | string
    undoneAt: null | string
  }
}

Errors

StatusMessage
400Not a vehicle id.
400Not a import id.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

GET /v1/vehicles/:vehicleId/imports/:importId

Status, progress, the summary and the problems.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
:importIdTakeout import id (imp_…); under me/food a Food import (fim_…); under vehicles an import of a car's history (vim_…), as the imports list gives it.

Response 200

{
  import: {
    importId: string
    source: "tessie_export" | "tessie_template" | "vehicles_csv"
    status: "ready" | "expired" | "done" | "failed" | "cancelled" | "uploading" | "refused" | "checking" | "importing" | "undoing" | "undone"
    version: number
    progress: number
    files: {
      name: string
      bytes: number
    }[]
    fileNames: string[]
    options: {
      timeZone?: string
      currency?: string
      businessTags?: string[]
    }
    summary: null | {
      from?: string
      to?: string
      kinds: {
        drive: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        idle: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        battery: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        charge: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        tyre: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
      }
      rows: number
      invalidRows: number
      distanceKm: number
      kwhUsed: number
      kwhAdded: number
      drivesByMonth: {
        [key: string]: number
      }
      carCheck: "vin" | "odometer"
      locations: boolean
      units?: "km" | "mi"
      timeZone?: string
      repeatedHour: number
      trimmed: number
    }
    problems: {
      file: number
      row: number
      column?: string
      code: string
    }[]
    problemCount: number
    refusal: null | {
      at?: string
      code: string
      file?: number
      missing?: string[]
      unexpected?: string[]
      limit?: string
    }
    from: null | string
    to: null | string
    written: number
    createdAt?: string
    checkedAt: null | string
    committedAt: null | string
    undoneAt: null | string
  }
}

Errors

StatusMessage
400Not a vehicle id.
400Not a import id.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.
404Import not found.

GET /v1/vehicles/:vehicleId/imports/:importId/rows

The first 200 new rows of a kind, as they will read; places only with location.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
:importIdTakeout import id (imp_…); under me/food a Food import (fim_…); under vehicles an import of a car's history (vim_…), as the imports list gives it.
Query parameterTypeRequiredNotes
kind"drive" | "charge" | "idle"Yes

Response 200

{
  rows: {
    start?: {
      name: null | string
      lat: null | number
      lon: null | number
    }
    end?: {
      name: null | string
      lat: null | number
      lon: null | number
    }
    track?: boolean
    id: string
    kind: "drive" | "idle" | "charge"
    startedAt?: string
    endedAt?: string
    chargeKind?: unknown
    place?: {
      name: null | string
      lat: null | number
      lon: null | number
    }
  }[]
  places: boolean
}

Errors

StatusMessage
400Not a vehicle id.
400Not a import id.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.
404Import not found.

POST /v1/vehicles/:vehicleId/imports/:importId/commit

Commits the check named by version: 202; 409 stale for an older one, confirm_skip until invalid rows' skipping is confirmed.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
:importIdTakeout import id (imp_…); under me/food a Food import (fim_…); under vehicles an import of a car's history (vim_…), as the imports list gives it.

Request body

FieldTypeRequiredDefaultNotes
versionintegerYes≥ 1
skipInvalidbooleanNofalse

Response 202

{
  import: {
    importId: string
    source: "tessie_export" | "tessie_template" | "vehicles_csv"
    status: "ready" | "expired" | "done" | "failed" | "cancelled" | "uploading" | "refused" | "checking" | "importing" | "undoing" | "undone"
    version: number
    progress: number
    files: {
      name: string
      bytes: number
    }[]
    fileNames: string[]
    options: {
      timeZone?: string
      currency?: string
      businessTags?: string[]
    }
    summary: null | {
      from?: string
      to?: string
      kinds: {
        drive: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        idle: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        battery: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        charge: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        tyre: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
      }
      rows: number
      invalidRows: number
      distanceKm: number
      kwhUsed: number
      kwhAdded: number
      drivesByMonth: {
        [key: string]: number
      }
      carCheck: "vin" | "odometer"
      locations: boolean
      units?: "km" | "mi"
      timeZone?: string
      repeatedHour: number
      trimmed: number
    }
    problems: {
      file: number
      row: number
      column?: string
      code: string
    }[]
    problemCount: number
    refusal: null | {
      at?: string
      code: string
      file?: number
      missing?: string[]
      unexpected?: string[]
      limit?: string
    }
    from: null | string
    to: null | string
    written: number
    createdAt?: string
    checkedAt: null | string
    committedAt: null | string
    undoneAt: null | string
  }
}

Errors

StatusMessage
400Not a vehicle id.
400Not a import id.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

POST /v1/vehicles/:vehicleId/imports/:importId/undo

Undoes a committed import: its rows go, edits since included. 202.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
:importIdTakeout import id (imp_…); under me/food a Food import (fim_…); under vehicles an import of a car's history (vim_…), as the imports list gives it.

Response 202

{
  import: {
    importId: string
    source: "tessie_export" | "tessie_template" | "vehicles_csv"
    status: "ready" | "expired" | "done" | "failed" | "cancelled" | "uploading" | "refused" | "checking" | "importing" | "undoing" | "undone"
    version: number
    progress: number
    files: {
      name: string
      bytes: number
    }[]
    fileNames: string[]
    options: {
      timeZone?: string
      currency?: string
      businessTags?: string[]
    }
    summary: null | {
      from?: string
      to?: string
      kinds: {
        drive: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        idle: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        battery: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        charge: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        tyre: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
      }
      rows: number
      invalidRows: number
      distanceKm: number
      kwhUsed: number
      kwhAdded: number
      drivesByMonth: {
        [key: string]: number
      }
      carCheck: "vin" | "odometer"
      locations: boolean
      units?: "km" | "mi"
      timeZone?: string
      repeatedHour: number
      trimmed: number
    }
    problems: {
      file: number
      row: number
      column?: string
      code: string
    }[]
    problemCount: number
    refusal: null | {
      at?: string
      code: string
      file?: number
      missing?: string[]
      unexpected?: string[]
      limit?: string
    }
    from: null | string
    to: null | string
    written: number
    createdAt?: string
    checkedAt: null | string
    committedAt: null | string
    undoneAt: null | string
  }
}

Errors

StatusMessage
400Not a vehicle id.
400Not a import id.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

DELETE /v1/vehicles/:vehicleId/imports/:importId

Cancels an import before it commits. 202.

Auth: user access token or platform agent key

Path parameterDescription
:vehicleIdA vehicle's id (veh_…): one owner's period with one VIN. Another owner of the same car has another id.
:importIdTakeout import id (imp_…); under me/food a Food import (fim_…); under vehicles an import of a car's history (vim_…), as the imports list gives it.

Response 202

{
  import: {
    importId: string
    source: "tessie_export" | "tessie_template" | "vehicles_csv"
    status: "ready" | "expired" | "done" | "failed" | "cancelled" | "uploading" | "refused" | "checking" | "importing" | "undoing" | "undone"
    version: number
    progress: number
    files: {
      name: string
      bytes: number
    }[]
    fileNames: string[]
    options: {
      timeZone?: string
      currency?: string
      businessTags?: string[]
    }
    summary: null | {
      from?: string
      to?: string
      kinds: {
        drive: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        idle: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        battery: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        charge: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
        tyre: {
          new: number
          duplicate: number
          short: number
          recent: number
          invalid: number
          incomplete: number
        }
      }
      rows: number
      invalidRows: number
      distanceKm: number
      kwhUsed: number
      kwhAdded: number
      drivesByMonth: {
        [key: string]: number
      }
      carCheck: "vin" | "odometer"
      locations: boolean
      units?: "km" | "mi"
      timeZone?: string
      repeatedHour: number
      trimmed: number
    }
    problems: {
      file: number
      row: number
      column?: string
      code: string
    }[]
    problemCount: number
    refusal: null | {
      at?: string
      code: string
      file?: number
      missing?: string[]
      unexpected?: string[]
      limit?: string
    }
    from: null | string
    to: null | string
    written: number
    createdAt?: string
    checkedAt: null | string
    committedAt: null | string
    undoneAt: null | string
  }
}

Errors

StatusMessage
400Not a vehicle id.
400Not a import id.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.

GET /v1/me/widgets/vehicle

The Vehicle widget's numbers for a car the person holds view on: state, state of charge, range, charging, locks and cabin temperature; no position. People only.

Auth: user access token or platform agent key

Query parameterTypeRequiredNotes
vehicleIdstringYesup to 60 characters

Response 200

{
  vehicleId: string
  name: string
  ended: {
    at?: string
  }
}
| {
  vehicleId: string
  name: string
  state?: "offline" | "charging" | "parked" | "driving" | "asleep"
  lastSeen?: string
  soc?: number
  rangeKm?: number
  plugged?: boolean
  chargeKw?: number
  chargeLimitPct?: number
  etaMin?: number
  locked?: boolean
  insideC?: number
}

Errors

StatusMessage
400Not a vehicle id.
403Widgets belong to people.
403Widgets are read by the app.
403Vehicles isn't available to the phone assistant.
403Vehicles is reachable from the Vehicles and phone apps.
403Vehicles needs a key made by a person.
404Vehicles isn't available here.