API
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.
Every route below, with its parameters, request and response, errors and samples, is in the API reference.
| Route | What it does |
|---|---|
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. |
GET /v1/vehicles/shared/drives/:token | The drive a share link opens, with nobody signed in: its route, distance, times and charts as the link allows (ends cut, speeds left out), and never places, the driver, tags or events, nor more than the car's privacy shows everyone and its maker sees now (speeds left out where either hides them). 404 for anything a link doesn't open, whatever the reason: ended, revoked, or a drive the car's privacy or its maker's access no longer lets out. |
GET /v1/vehicles/shared/reviews/:token | The Year in Review a share link opens, with nobody signed in: the car's name and the range's numbers from what the car shows everyone, costs and saved places only if the link was made with them, and no drive ids. |
GET /v1/platform/vehicles/pictures | The switch, every rule (with what is wrong with one that fails validation, and overlaps) and the misses. |
GET /v1/platform/vehicles/pictures/rules | The picture rules, and the warnings about them (platform staff). |
PUT /v1/platform/vehicles/pictures/rules/:ruleId | Writes a rule (creating or replacing it by id). Raises rev. |
DELETE /v1/platform/vehicles/pictures/rules/:ruleId | Removes a picture rule. Raises rev. |
GET /v1/platform/vehicles/pictures/misses | The values no rule covers, most recent first: what to map next. |
DELETE /v1/platform/vehicles/pictures/misses | Dismisses a miss (?carType=&slot=&value=); audited. |
GET /v1/platform/vehicles/pictures/switch | Whether car pictures are on. |
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). |
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. |
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. |
GET /v1/me/vehicles/requestable | An org's cars by id and name, for its active, non-guest members to ask for; nothing else about them. |
GET /v1/me/vehicles/sentry-force | Forced Sentry Mode on each of the space's cars: which are forced, and their floors. |
PUT /v1/me/vehicles/sentry-force | Forces Sentry Mode on for every car of the space, each turned on now (queued). |
DELETE /v1/me/vehicles/sentry-force | Lifts forced Sentry Mode on every car of the space. 204. |
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. |
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). |
GET /v1/me/vehicles/connections | Your Tesla connections: status (ok, reconnect), region, granted scopes and whether precise location is on. Never a token. |
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). |
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. |
GET /v1/me/vehicles/fleet | An organisation's fleet (docs/vehicles/fleet.md): its cars the caller holds anything on, each with its state, battery and plate, where it is and who it's shared with, as far as the caller may see each (fleetOf). A Personal space has no fleet. |
GET /v1/me/vehicles/analytics/drives | Drive Analytics over the organisation's cars (docs/vehicles/fleet.md → Fleet analytics, fleetAnalytics): from, to, by and driver as a car's; each car as far as the caller sees its drives. A Personal space has no fleet (404). |
POST /v1/me/vehicles/fleet/commands/:commandName | One command to several of the fleet's cars (docs/vehicles/fleet.md → Commands on several cars): { vehicleIds, args? } with an Idempotency-Key. Only a command the catalogue lets go in bulk (422 not_bulk); one that needs a step-up is refused before any car (403 step_up). Each car is checked as the person, as the command route checks it alone; the answer is the run (FleetRun), every car queued, refused or left out with why. |
GET /v1/me/vehicles/fleet/bulk/:bulkId | How a command sent to several cars is going, car by car, for the person who sent it. |
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. |
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. |
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. |
POST /v1/me/vehicles/manual | Adds a car logged by hand (docs/vehicles/manual.md): any make and fuel, no Tesla connection. 201 { vehicle }; with odometerKm, its first odometer reading is logged too. The space's own (as a claim), from the app or a key; audited as vehicle.add. |
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. |
PUT /v1/me/vehicles/api-access | Turns API key access to your Personal Vehicles on or off. Only you, in the Vehicles app. |
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. |
PUT /v1/me/vehicles/display | Replaces your display units ({ display: { … } }); {} goes back to your language's. Only you, in the Vehicles or phone app. |
GET /v1/me/vehicles/profile | The space's units, currency, default tariff, the trim around a home place on shared routes, and the petrol car drives are compared with. |
PUT /v1/me/vehicles/profile | Changes those that are given; null clears the default tariff, the trim or a fuel figure. The default tariff is one of the space's. |
GET /v1/me/vehicles/places | The space's charging places (a centre and a radius in metres), by name. |
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. |
PATCH /v1/me/vehicles/places/:placeId | Changes the fields given on a place; tariffId: null clears its tariff. |
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). |
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. |
GET /v1/me/vehicles/tariffs | The space's tariffs, by name. |
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. |
PUT /v1/me/vehicles/tariffs/:tariffId | Replaces a tariff with the one given. |
DELETE /v1/me/vehicles/tariffs/:tariffId | Removes a tariff; the default tariff and a place that uses it keep it from going (409). |
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. |
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. |
PATCH /v1/me/vehicles/geofences/:fenceId | Changes the fields given on a geofence. |
DELETE /v1/me/vehicles/geofences/:fenceId | Removes a geofence; an automation triggered by it keeps it from going (409). |
GET /v1/me/vehicles/automations/runs | The space's runs of its automations, newest first: each car's, with what each action did or why it didn't (180 days). One automation's with automationId. |
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 (docs/vehicles/space-automations.md). |
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. |
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. |
DELETE /v1/me/vehicles/automations/:automationId | Removes an automation. 204. |
GET /v1/orgs/:orgId/vehicles/requestable | An org's cars by id and name, for its active, non-guest members to ask for; nothing else about them. |
GET /v1/orgs/:orgId/vehicles/sentry-force | Forced Sentry Mode on each of the space's cars: which are forced, and their floors. |
PUT /v1/orgs/:orgId/vehicles/sentry-force | Forces Sentry Mode on for every car of the space, each turned on now (queued). |
DELETE /v1/orgs/:orgId/vehicles/sentry-force | Lifts forced Sentry Mode on every car of the space. 204. |
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. |
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. |
GET /v1/orgs/:orgId/vehicles/connections | The organization's Tesla connections: status, region, granted scopes and whether precise location is on. Never a token. |
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). |
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. |
GET /v1/orgs/:orgId/vehicles/fleet | An organisation's fleet (docs/vehicles/fleet.md): its cars the caller holds anything on, each with its state, battery and plate, where it is and who it's shared with, as far as the caller may see each (fleetOf). A Personal space has no fleet. |
GET /v1/orgs/:orgId/vehicles/analytics/drives | Drive Analytics over the organisation's cars (docs/vehicles/fleet.md → Fleet analytics, fleetAnalytics): from, to, by and driver as a car's; each car as far as the caller sees its drives. A Personal space has no fleet (404). |
POST /v1/orgs/:orgId/vehicles/fleet/commands/:commandName | One command to several of the fleet's cars (docs/vehicles/fleet.md → Commands on several cars): { vehicleIds, args? } with an Idempotency-Key. Only a command the catalogue lets go in bulk (422 not_bulk); one that needs a step-up is refused before any car (403 step_up). Each car is checked as the person, as the command route checks it alone; the answer is the run (FleetRun), every car queued, refused or left out with why. |
GET /v1/orgs/:orgId/vehicles/fleet/bulk/:bulkId | How a command sent to several cars is going, car by car, for the person who sent it. |
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. |
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. |
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. |
POST /v1/orgs/:orgId/vehicles/manual | Adds a car logged by hand (docs/vehicles/manual.md): any make and fuel, no Tesla connection. 201 { vehicle }; with odometerKm, its first odometer reading is logged too. The space's own (as a claim), from the app or a key; audited as vehicle.add. |
GET /v1/orgs/:orgId/vehicles/profile | The space's units, currency, default tariff, the trim around a home place on shared routes, and the petrol car drives are compared with. |
PUT /v1/orgs/:orgId/vehicles/profile | Changes those that are given; null clears the default tariff, the trim or a fuel figure. The default tariff is one of the space's. |
GET /v1/orgs/:orgId/vehicles/places | The space's charging places (a centre and a radius in metres), by name. |
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. |
PATCH /v1/orgs/:orgId/vehicles/places/:placeId | Changes the fields given on a place; tariffId: null clears its tariff. |
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). |
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. |
GET /v1/orgs/:orgId/vehicles/tariffs | The space's tariffs, by name. |
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. |
PUT /v1/orgs/:orgId/vehicles/tariffs/:tariffId | Replaces a tariff with the one given. |
DELETE /v1/orgs/:orgId/vehicles/tariffs/:tariffId | Removes a tariff; the default tariff and a place that uses it keep it from going (409). |
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. |
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. |
PATCH /v1/orgs/:orgId/vehicles/geofences/:fenceId | Changes the fields given on a geofence. |
DELETE /v1/orgs/:orgId/vehicles/geofences/:fenceId | Removes a geofence; an automation triggered by it keeps it from going (409). |
GET /v1/orgs/:orgId/vehicles/automations/runs | The space's runs of its automations, newest first: each car's, with what each action did or why it didn't (180 days). One automation's with automationId. |
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 (docs/vehicles/space-automations.md). |
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. |
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. |
DELETE /v1/orgs/:orgId/vehicles/automations/:automationId | Removes an automation. 204. |
GET /v1/vehicles/access-links/:token | What a request link opens: the car's name and its owner's, nothing else. 404 for anything that isn't a live link. |
GET /v1/vehicles/access-requests | The person's own requests, and those for the cars they hold through a space (their own, and orgs where they're a fleet admin). |
POST /v1/vehicles/access-requests | Asks for access: through a link's token, or a vehicleId of the org the person is an active, non-guest member of, or of a car they see through a grant. 201 with the request; 404 for a car they can't reach this way, 409 exists or holds, 429 with Retry-After. |
DELETE /v1/vehicles/access-requests/:vehicleId | Withdraws the person's own open request for a car. 204. |
GET /v1/vehicles/:vehicleId/access-requests | A car's requests, for its owner and an org's fleet admins. |
POST /v1/vehicles/:vehicleId/access-requests/:userId/approve | Approves a request, as asked or narrowed (capabilities, params, notBefore, expiresAt, schedule; null clears). |
POST /v1/vehicles/:vehicleId/access-requests/:userId/decline | Declines a request, with an optional note to the asker. 204. |
GET /v1/vehicles/:vehicleId/access-links | The car's live request links (never their tokens). |
POST /v1/vehicles/:vehicleId/access-links | A new request link: its address is in this answer only. |
DELETE /v1/vehicles/:vehicleId/access-links/:linkId | Ends a request link: it opens nothing from now. 204. |
GET /v1/vehicles/:vehicleId/sentry-force | Whether Sentry Mode is forced: its whole state for the owner, whether it is for anyone who can see the car. |
PUT /v1/vehicles/:vehicleId/sentry-force | Forces Sentry Mode on for everyone (or changes the battery floor), and turns it on now. |
DELETE /v1/vehicles/:vehicleId/sentry-force | Lifts forced Sentry Mode: anyone who may change the car's settings can turn it off again. 204. |
GET /v1/vehicles/:vehicleId/speed-limit | A shared drive's Speed Limit Mode session, for the owner: the limit, whose drive, and whether it is being turned off (docs/vehicles/sharing.md → Speed Limit Mode sessions). |
DELETE /v1/vehicles/:vehicleId/speed-limit | The owner ends a session: Speed Limit Mode is turned off at the next park, never mid-drive. 404 when none is open. |
GET /v1/vehicles/:vehicleId | META and LIVE with the caller's capabilities, telemetry health and key status. The position only with location. |
POST /v1/vehicles/:vehicleId/watch | Renews the live lease (open apps send it every 30 s while the car is on screen). 204. |
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. |
GET /v1/vehicles/:vehicleId/trips | Drives, newest first. class, tag, driver, min (km) filter; cursor resumes across months. |
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. |
POST /v1/vehicles/:vehicleId/trips/roads | Drives' lines on the roads they took (docs/maps/timeline.md → Roads), for the drive page and the drives map: { tripIds } (up to 50) answers { roads: { [tripId]: stretches | "pending" | null } }, kept lines and a few new matchings each time (pending: ask again shortly). Drives the caller doesn't see are left out. Display only. |
GET /v1/vehicles/:vehicleId/trips/drivers | Whom the car's drives may be assigned to (DriverChoices, docs/vehicles/app-drives.md → Drivers): the reader, the space's people and those the car is shared with, by name. The car's owner and fleet admins only (403 owner_only), with manage and trips. |
GET /v1/vehicles/:vehicleId/trips/:tripId | A drive: the summary, and its thumbnail path when it has no track (an imported route). ?points=1 adds the decoded track (the server opens it), after since when given. |
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). |
GET /v1/vehicles/:vehicleId/charges | Charging sessions: with trips, the places; with costs, what they cost. Either opens the list. |
GET /v1/vehicles/:vehicleId/idles | Parked periods (battery lost while parked, with Sentry and climate shares). |
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). |
GET /v1/vehicles/:vehicleId/commands/:commandId | A command's state: your own, or anyone's with share. |
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. |
POST /v1/vehicles/:vehicleId/archive | Archives the car (docs/vehicles/tesla.md → Registry): its period ends, nothing more is recorded and its shares end, and its key and history stay for the owner to read (no purge). The owner's alone; 409 for a period already ended. restore undoes it. |
PUT /v1/vehicles/:vehicleId/logging | Pauses or resumes the car's data logging ({ paused }; docs/vehicles/settings.md → Paused logging): paused, nothing is recorded and our telemetry config comes off the car; commands still work. The owner's alone; 409 for a period that has ended. Audited in an organisation's log (vehicle.settings_update, change logging). |
POST /v1/vehicles/:vehicleId/restore | Undoes a removal within 7 days, or an archive (the connection must still list the car and the VIN be free). |
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. |
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. |
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. |
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. Beside them, the months measured while parked (measured, the cap# rows an import or the stream wrote), which win where both exist. Once the months span half a year, what the pack has kept is the median of the last three over the best of the first three (retainedPct, baselineKwh, baselineMonth). Battery Health (docs/vehicles/insights-battery.md → Battery health): health is the latest capacity over the pack's capacity new (the owner's originalKwh, else the best of the first months), with the warranty's terms (limit rows) and when its years end (from the owner's pack date, else the car's history). For a caller who may see charges, readings: each charge that added 5 kWh or more, what the pack held and its rated range at 100%, and the cycles so far; the odometer at each only for a caller who sees every drive (with it, the distance between charges). lifetime: the car's lifetime energy by month, where months measured it. |
GET /v1/vehicles/:vehicleId/tyres | The four tyre pressures as the car last reported them (kPa), the tyre alerts of the last 90 days (left out when raised during a drive the caller does not see, as in the events), and the days in a range (at most two years, the default): each wheel's lowest, highest and cold reading a local day (tyre# rows, streamed or imported). A day's highest says the car was driven, so the days go only to a caller who sees every drive; anyone else gets history: "hidden". |
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. |
GET /v1/vehicles/:vehicleId/costs | What charging has cost in a range (at most three years, the default): the priced charges' cost, energy and count, by where the price came from, by kind of charge and by site (home, Supercharger, elsewhere), and period by period (by: day, week or month, default month, in the space's zone). A charge with no price of its own is priced by the space's tariffs (@cactive/vehicles-service/pricing: its place's tariff or the default, energy spread over its span) and counts in estimated too; one no tariff covers counts in unpriced, not as free, and noTariff says the space has no tariff at all. 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). |
GET /v1/vehicles/:vehicleId/logbook | The business drives of a range for an ATO logbook (at most 15 months, the default): 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. all=1 lists the drives of every class the caller sees, each with its class (the Logbook page classifies them). |
PUT /v1/vehicles/:vehicleId/pins | The car's PINs for Valet Mode and Speed Limit Mode (docs/vehicles/commands.md → PINs): four digits each, which the car takes when the mode goes on and asks for to turn it off. The owner's alone; sealed with the car's key and never answered back. |
PUT /v1/vehicles/:vehicleId/details | The car's details beyond its name (docs/vehicles/settings.md → Vehicle), as Tessie's car info: its number plate, for whoever may change its settings, and the owner's notes (service, registration, insurance), the owner's alone and sealed with the car's key. null clears one; an empty note clears it too. |
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. |
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. |
PATCH /v1/vehicles/:vehicleId/trips | Classifies and tags drives in bulk: { ids (up to 50), class?, purpose? (null clears), tags? (replaces), driver? (null clears) }. 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. driver is the owner's or a fleet admin's (mayAssignDrivers, 403 owner_only), one of the car's people (driverChoices, 400 otherwise). Audited in the space's log (the change and how many, never the purpose; a driver as vehicle.driver_set). |
POST /v1/vehicles/:vehicleId/trips/delete | Deletes drives for good ({ ids }, up to 50; docs/vehicles/app-drives.md → Deleting drives): their rows, routes, events and share links, a pending close, the driver's fleet pointers, then the days' totals rolled up again (@cactive/vehicles-service/drive-delete). The car's owner alone (the person, or the organisation's vehicles:admin) as a person in the app: a grantee 403 owner_only, an API key, Caity or the phone assistant 403 person_only; an ended period 409. A drive that isn't there, is outside the period or isn't shown to the caller is in missing. Audited in an organisation's log with the count, never which drives. |
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. A charge with no price of its own is priced by the tariffs, with the energy by period (byPeriod) and the day's supply charge's share in it (supplyCents) where its tariff puts that on charges. |
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. |
GET /v1/vehicles/:vehicleId/activity/series | Activity's charts (docs/vehicles/insights.md → Routes): the battery, power (driving draws, regenerating and charging add, so charging is negative) and speed through at most two days, a point a minute, from the drives the caller sees and the charges' curves. view opens it; each part needs its own capability. |
GET /v1/vehicles/:vehicleId/analytics/drives | Drives by local day, week or month (trips; Analytics in docs/vehicles/insights.md). |
GET /v1/vehicles/:vehicleId/analytics/charges | Charging by local day, week or month (trips or costs, the cost with costs). |
GET /v1/vehicles/:vehicleId/analytics/parked | Parked periods by local day, week or month (trips, for a caller who sees every drive). |
PUT /v1/vehicles/:vehicleId/battery | The battery pack, as the owner knows it (Battery Health): { packDate?: "YYYY-MM-DD" | null, originalKwh?: number | null }, the install date (not after today) and the capacity new (20 to 250 kWh); null clears one. Needs settings; audited as vehicle.settings_update (change: "battery"). |
GET /v1/vehicles/:vehicleId/maintenance | The car's maintenance (docs/vehicles/insights-alerts.md → Maintenance): each item's interval (limit rows), when it was last done as the owner set it, and whether it is due, soon or not known. The odometer (a distance item's due reading) only where the driving state shows. view. |
PUT /v1/vehicles/:vehicleId/maintenance | Marks an item done ({ item, on: "YYYY-MM-DD", odometerKm? }, not after today; the odometer for the tyre rotation, the car's reading now when left out) or clears it (on: null). Needs settings; audited as vehicle.settings_update (change: maintenance). |
GET /v1/vehicles/:vehicleId/costs/projection | This month's and year's charging cost, projected from the last 28 days (and last year's season), for holders of costs. |
PUT /v1/vehicles/:vehicleId/recommendations | Replaces the cost recommendations the caller ignores for the car: { ignored: [id] } (none removes the row). People in the apps; costs on the car, as the projection that shows them. |
GET /v1/vehicles/:vehicleId/alerts | The caller's own alerts for the car (docs/vehicles/insights-alerts.md): what they chose (nothing until they do) and which kinds they may choose. People in the apps only; view on the car. |
PUT /v1/vehicles/:vehicleId/alerts | Replaces the caller's alerts for the car: { kinds, unlockedMinutes, batteryBelowPct }. A kind they may not choose is 403; no kinds removes the row. Who they are now is kept with it, so each alert is checked against their access when it fires. |
GET /v1/vehicles/:vehicleId/export | The car's data as files: kind one of drives, charges, parked, events, commands, tyres, battery or logbook as CSV, or all (the default) as a ZIP of every kind the caller may see with a README. A range of at most three years (default the last year). Each kind follows its page's rule: drives and the logbook need trips (the drives the caller sees), charges trips or costs (the price only with costs), parked periods, tyres and events every drive; places are names, and positions only for the owner. 413 past the size one answer holds. Audited (vehicle.export). |
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. |
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). |
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. |
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. |
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. |
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. |
GET /v1/vehicles/:vehicleId/data | The car's last read and the state of the read: battery and climate (what the stream doesn't carry), schedules (charging and preconditioning, without where they apply), and raw, every field by section, for those who hold the car through its space (null for anyone else). The table only: open pages poll it while a read runs. |
POST /v1/vehicles/:vehicleId/data/read | Reads the car again: 202 and a vehicles.data_read job. Tesla bills each read (and one of a car that isn't online, so the worker asks Tesla's free car list first); the car is never woken for this. 429 with Retry-After inside the cooldown, while a read runs (rate_limited) or past the car's reads for the day (daily_limit). |
GET /v1/vehicles/:vehicleId/software | The car's software: the version now, the update it reports, and the versions it has reported (software.ts): installs newest first, days since the last and the average gap. |
POST /v1/vehicles/:vehicleId/schedules/:kind | Adds a schedule where the car is now (charging: charge; preconditioning: climate), through the command service. The position is the car's own, read here and never sent back. 409 no_position while the car hasn't reported one. |
PUT /v1/vehicles/:vehicleId/schedules/:kind/:scheduleId | Changes a schedule from the car's last read (only what is sent changes), where it applies kept. 404 for one the read doesn't have. |
GET /v1/vehicles/:vehicleId/imports | The car's imports, newest first. |
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. |
POST /v1/vehicles/:vehicleId/imports/:importId/check | Checks each upload's size and checksum, then queues the check (again with new options): 202. |
GET /v1/vehicles/:vehicleId/imports/:importId | Status, progress, the summary and the problems. |
GET /v1/vehicles/:vehicleId/imports/:importId/rows | The first 200 new rows of a kind, as they will read; places only with location. |
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. |
POST /v1/vehicles/:vehicleId/imports/:importId/undo | Undoes a committed import: its rows go, edits since included. 202. |
DELETE /v1/vehicles/:vehicleId/imports/:importId | Cancels an import before it commits. 202. |
PUT /v1/vehicles/:vehicleId/manual | A manual car's make, model, year and fuel (null clears the model or the year): settings, the same as its name. |
POST /v1/vehicles/:vehicleId/log/drives | Logs a drive by hand: 201 { trip }, the drive as the list shows it. 409 overlaps when another drive covers any of it. |
PATCH /v1/vehicles/:vehicleId/log/drives/:tripId | Changes a drive made by hand (all but its start and route; null clears). 409 not_manual for a recorded drive. |
DELETE /v1/vehicles/:vehicleId/log/drives/:tripId | Deletes a drive made by hand, as any drive goes (its links and photos too). 204. |
POST /v1/vehicles/:vehicleId/log/charges | Logs a charge (kWh) or a refuel (litres) by hand: 201 { charge }. A price needs costs too. 409 overlaps. |
PATCH /v1/vehicles/:vehicleId/log/charges/:chargeId | Changes a charge or refuel made by hand (all but its start and type; null clears): { charge }. A price needs costs; 409 not_manual for a recorded one. |
DELETE /v1/vehicles/:vehicleId/log/charges/:chargeId | Deletes a charge or refuel made by hand, the days' totals following: 204. 409 not_manual for a recorded one. |
GET /v1/vehicles/:vehicleId/log/entries | The car's log, newest first: odometer readings and services for trips, expenses for trips and costs too (an expense is a cost), with the cost only for costs, the odometer with the driving state, and notes and places where place names show. kind filters. |
POST /v1/vehicles/:vehicleId/log/entries | Logs an odometer reading, an expense or a service: 201 { entry }. An expense, or a price on a service, needs costs too. |
PATCH /v1/vehicles/:vehicleId/log/entries/:entryId | Changes an odometer reading, expense or service (all but its kind and day; null clears): { entry }. An expense needs costs too. |
DELETE /v1/vehicles/:vehicleId/log/entries/:entryId | Deletes an entry of the log: 204. A service's maintenance days stay; an expense the caller can't see is 404. |
GET /v1/vehicles/:vehicleId/privacy | { privacy }: what the owner hides from everyone they share the car with (absent fields: each share decides). |
PUT /v1/vehicles/:vehicleId/privacy | Changes the for-everyone settings: a field set caps every share, null leaves it to each share, absent keeps it. pausedUntil pauses every share until then (forever: until turned back on), null resumes. Audited (vehicle.settings_update, privacy, the fields changed, never their values). |
GET /v1/vehicles/:vehicleId/data-policy | { policy }: the car's data policy (docs/vehicles/privacy.md → Data controls); absent fields are today's behaviour. The owner's alone. |
PUT /v1/vehicles/:vehicleId/data-policy | Changes the data policy: a field set takes effect on every read at once (viewRulesFor), null puts it back to today's behaviour, absent keeps it; a retention set also queues the purge of what is past it. Audited (vehicle.settings_update, data_policy, the groups changed, never their values). The owner's alone; 409 once the car's period has ended. |
POST /v1/vehicles/:vehicleId/data/:class/delete | Deletes one class of the car's data for good (drives, positions, charging, telemetry, music, FSD, photos, Sentry): queued for the worker, which deletes everything of the class recorded so far (data-purge.ts); reads leave nothing of it out meanwhile, as it goes. The owner's, and only a person signed in (not a key, Caity or the phone assistant): 202 { queued: class }. Audited. |
PUT /v1/vehicles/:vehicleId/trips/:tripId/privacy | Who a drive is hidden from, and whose sight of its speeds: * or people and circles (empty: nobody). The owner's alone. |
PUT /v1/vehicles/:vehicleId/charges/:chargeId/privacy | Who a charge is hidden from: * or people and circles (empty: nobody). The owner's alone. |
GET /v1/vehicles/:vehicleId/trips/:tripId/links | A drive's share links: each one's linkId, when it was made and ends, and whether it hides the ends or the speeds. Needs share on the car and the drive shown to you; never the secret. |
POST /v1/vehicles/:vehicleId/trips/:tripId/links | → 201 { linkId, url, createdAt, expiresAt, hideEnds, hideSpeed }: anyone with url sees the drive until it ends or is revoked. 403 privacy while the car's privacy hides the drive from anybody (or pauses it); hideSpeed is true whatever was asked while it hides the speeds, or the maker doesn't see them. |
DELETE /v1/vehicles/:vehicleId/trips/:tripId/links/:linkId | Revokes a drive's share link at once: anyone opening it gets the same 404 as for a link that never was. |
GET /v1/vehicles/:vehicleId/charge-plan | Smart Charging: the cheapest start that has the car at its limit by readyBy (the tariff zone's clock, 07:00 by default). |
POST /v1/vehicles/:vehicleId/trip-plan | The trip planner: a plan to to (view; the car's use with trips, prices with costs, the car as the start with location). At most vehicles.trip.plansPerDay a person a day; a POST so a page coming back into view doesn't plan again. |
GET /v1/vehicles/:vehicleId/trip-plan/places | Places to plan a trip to, named like q (2 to 100 characters): saved places first, then Mapbox's. |
GET /v1/vehicles/:vehicleId/drain | Parked Drain: what the parked car loses and why (trips, for a caller who sees every drive); 90 days by default, a year at most. |
GET /v1/vehicles/:vehicleId/savings | Savings: petrol and CO₂ against a petrol car, by month, from the drives the caller sees (trips); money with costs and a fuel price. |
GET /v1/vehicles/:vehicleId/review | The car's Year in Review for from to to (at most 400 days; a year back from to without from): distance, drives, time, charging, energy, the longest drive, busiest day, most efficient drive, climb, months and the places drives ended at most, from the drives and charges you see; costs and savings only with costs. |
GET /v1/vehicles/:vehicleId/music | The music on the drives the caller sees, over a range as the review's (trips; hidden without the owner's say-so). |
GET /v1/vehicles/:vehicleId/review/links | The car owner's Year in Review links: each one's address, range, end and whether it shows costs and place names, and whether a link may go out now (linkable). |
POST /v1/vehicles/:vehicleId/review/links | → 201 { linkId, url, createdAt, expiresAt, from, to, money, places, speeds, music }: anyone with url sees the range's review until the link ends or is revoked. 403 privacy while the car shows its drives to nobody or sharing is paused; places is false whatever was asked while the car hides place names, speeds (off unless asked for) while it hides speeds on drives, and music (off unless asked for) while it hides music. |
DELETE /v1/vehicles/:vehicleId/review/links/:linkId | Ends a Year in Review link at once: anyone opening it gets the same 404 as for a link that never was. |
GET /v1/vehicles/:vehicleId/speed | The car's speeds for from to to (its whole history without from), from the drives whose speed you see with a speed summary by the current rules: the top speed and its drive, the cruising speed, the fastest speed held for 30 seconds, a minute, five and ten, the distance at each whole km/h of sustained cruising and of all moving time with their percentiles and bands, the five fastest drives, and how many drives were counted, imported, hidden or have no speeds yet. Needs trips. |
GET /v1/vehicles/:vehicleId/appearance | Appearance's choices (?base=<ruleId> for another body): the car's choice (choice, or null: automatic), every body the rows draw, and the chosen body's paints, wheels and interiors, each with the configurator's picture of it on that body, signed on our CDN. The worker fetches pictures not yet in the bucket (the API never calls Tesla), within the fetch limit: complete false when some are still to come. In the Tesla rate group, as it can reach Tesla's compositor. |
PUT /v1/vehicles/:vehicleId/appearance | Chooses the car's appearance: a base row and, optionally, a paint, wheels and interior row of its car type (any the rows hold, enabled or not). 400 when a row is gone or doesn't fit the base. Turns the picture on (pictureMode tesla), queues the resolve, and is audited. |
POST /v1/vehicles/:vehicleId/photo/uploads | Starts a photo of the car: { type, size } of the picture the app has already cropped to the car. A presigned PUT, its type and length signed, to up/<uploadId> in the pictures bucket for 15 minutes; the upload is the caller's, for this car, and is checked when it is finished. Within the photo size limit (vehicles.pictures.photoKb, Admin → Limits). |
PUT /v1/vehicles/:vehicleId/photo | Finishes a photo: the upload must be the caller's for this car. The worker checks it (the size and type it declared, read from its first bytes; a picture of a car's crop's size and shape), removes its location and camera details and keeps it as c/<photoId>.<ext> (a new random id), deleting the upload either way. It goes on both rows with the picture on; any earlier photo is queued for the worker to delete. Audited. |
DELETE /v1/vehicles/:vehicleId/photo | Takes the photo off: the next picture by precedence shows, and the worker deletes its file. Audited. |
DELETE /v1/vehicles/:vehicleId/appearance | Back to automatic: the appearance goes, and the configuration's picture shows again (a photo still wins). Audited. |
GET /v1/vehicles/:vehicleId/trips/:tripId/media | A drive's photos and videos: your own on it, others' only where their owners show them (without names or places), and, on your own car, suggestions from your Photos library unless you turned them off, best first, each with its confidence and why (notice the first time). Needs trips and the drive shown to you; a person signed in, never a key. |
GET /v1/vehicles/:vehicleId/trips/:tripId/media/candidates | Your Photos library 12 hours either side of the drive, newest first, each saying whether it's on the drive and whether it was taken during it or at its stop: what Add Photos offers. |
POST /v1/vehicles/:vehicleId/trips/:tripId/media | Puts photos from your own library on the drive (photoIds, up to 50; 200 a drive): references, the files stay in Photos. 404 when none of them is yours. |
PUT /v1/vehicles/:vehicleId/trips/:tripId/media/sharing | Whether your photos on the drive show to the people who can see it (shared); photos you add later follow it. |
PUT /v1/vehicles/:vehicleId/trips/:tripId/media/:photoId | Adds a suggested photo to the drive or dismisses it (status: accepted or dismissed); a dismissed photo isn't suggested for the drive again. |
DELETE /v1/vehicles/:vehicleId/trips/:tripId/media/:photoId | Takes your photo off the drive; it stays in your library. |
GET /v1/vehicles/:vehicleId/media | The drives that started from from to to (at most 400 days) with photos you may see: how many, how many of yours wait for review, and the first few: the drive list's covers and Activity's day. |
GET /v1/vehicles/:vehicleId/review/media | A Year in Review's photos for from to to: up to nine of those you may see, spread across the range, one a drive before a second from any. |
GET /v1/me/widgets/vehicle | The car widget's data for a car the person holds view on: state, charge, range, charging, locks, climate, where it's parked in words, its picture, the buttons they may use. People only. |