Bot API

Bring your bot

A key from the console (sc_live_…) lets a bot file an email alert, a utility planned outage, a maintenance notice, or other. Bots can trigger other, and other may be several alerts set up by name. The bot can also read vehicles, charge limits, and the last cached home energy. The bot only changes what the owner allowed. Do not put a key in a browser app.

Base URL

This site

/api/v1

Docs · OpenAPI spec

A bot can fetch the spec without signing in. Generate the key in the console and send it as a bearer token.

Auth

API key

Generate a key in the bot section. It starts with sc_live_ and is shown once. Send it on every request.

Authorization: Bearer sc_live_…

401 — Missing, unknown, or revoked key. Revoke a key in the bot section.

403 — The account isn't on an active Giga plan, or the owner hasn't allowed that kind of item.

409 — The bot isn't connected in the console yet, or the item was already handled.

429 — More than 120 requests a minute from one key. Errors come back as { "error": "…" }.

Tesla bills commands your bot handles. Those share a $0.10 monthly budget. /energy is the last cached reading. It does not call Tesla, even when that cache is older than five minutes, and it does not start a paid read. /vehicles is free.

Endpoints

  • GET

    /api/v1/me

    Bot name and which actions it may take: email, utility notices, charge limits, Powerwall reserve, and pausing vehicle charging. otherAlerts lists the named other alerts this household set up. Bots can trigger other, and other may be several alerts set up by name. A bot triggers one with POST /inbox, kind "other", and that name.

  • GET

    /api/v1/inbox

    Email alerts, utility notices, maintenance, and named other alerts waiting to be handled, and ones already handled. An other item includes name.

  • POST

    /api/v1/inbox

    Add an email, a planned utility outage, a maintenance notice, or other. kind is email, utility, maintenance, or other. kind "utility" may set reason to "maintenance" or "other". Bots can trigger other, and other may be several alerts set up by name. For other, name is one of those alerts (for example Garage door or Well pump). A name that does not match an other alert the household set up is rejected. title is required. from and detail are text.

  • POST

    /api/v1/inbox/:id/act

    Act on a new item. An email can raise every car to at least 90%. A utility notice can raise the Powerwall reserve to 80% and pause car charging. Only the permissions the owner turned on are used.

  • POST

    /api/v1/inbox/:id/dismiss

    Drop an item. A charge floor, reserve floor, or charging pause lasts until that email or notice is dismissed.

  • GET

    /api/v1/energy

    The household's last cached energy picture. Does not call Tesla, even when the cache is older than five minutes, and does not start a paid read. Uses the same key as the other bot routes: an active Giga plan and a connected key. energy.gridStatus is the grid. energy.charge is the Powerwall state of charge. energy.backupReserve is the backup reserve. energy.solar is panel production. energy.powershare is vehicle power supplying the house, already removed from solar. energy.homeLoad is home usage. energy.battery is battery charge or discharge power, positive while discharging. energy.gridPower is grid power. energy.stormMode is whether StormControl is holding the reserve up. energy.asOf is when that reading was stored, including when it is stale. vehicles[].vin is the car. vehicles[].everydayLimit is the owner's stored charge limit. vehicles[].raisedTo is the limit StormControl is holding, or null. vehicles[].chargingPaused is whether that car is on the stored pause list. When nothing has been cached the body is { "energy": null, "vehicles": [] }. Not included, because they are not cached and this endpoint will not start a paid vehicle-data read: vehicle state of charge, charge power, and Tesla's live charging state (Charging, Stopped, Complete).

  • GET

    /api/v1/vehicles

    Each car, its daily charge limit, and the limit a rule has raised.

File

An email, an outage, or other

POST /inbox adds the notice. Bots can trigger other, and other may be several alerts set up by name. POST /inbox/:id/act is what raises a charge limit, the reserve, or pauses charging. A named other alert fires only the rules aimed at that name.

curl -X POST /api/v1/inbox \
  -H "Authorization: Bearer sc_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "email",
    "title": "Wind Advisory until 8 PM",
    "from": "[email protected]",
    "detail": "Gusts near 45 mph."
  }'
curl -X POST /api/v1/inbox \
  -H "Authorization: Bearer sc_live_…" \
  -H "Content-Type: application/json" \
  -d '{
  "kind": "other",
  "name": "Garage door",
  "title": "Garage door left open",
  "from": "Home bot",
  "detail": "Open for 10 minutes."
}'

Read

Home energy

The last cached grid, home load, solar, battery, and vehicle charge limits. energy.charge is the Powerwall state of charge. energy.battery is charge or discharge power, positive while discharging. energy.asOf is when that reading was stored, including when it is stale. vehicles[].everydayLimit is the owner's stored charge limit. vehicles[].raisedTo is the limit StormControl is holding, or null. vehicles[].chargingPaused is the stored pause. This does not call Tesla and does not start a paid Tesla read, even when the cache is older than five minutes.

Not included, because they are not cached and this endpoint will not start a paid vehicle-data read: vehicle state of charge, charge power, and Tesla's live charging state (Charging, Stopped, Complete).

curl /api/v1/energy \
  -H "Authorization: Bearer sc_live_…"
{
  "energy": {
    "gridStatus": "Active",
    "charge": "71%",
    "backupReserve": "40%",
    "solar": "1452 W",
    "powershare": "0 W",
    "homeLoad": "20221 W",
    "battery": "0 W",
    "gridPower": "18769 W",
    "stormMode": true,
    "asOf": "2026-10-01T18:04:00.000Z"
  },
  "vehicles": [
    {
      "vin": "5YJ3E1EA7JF000001",
      "everydayLimit": 70,
      "raisedTo": null,
      "chargingPaused": false
    }
  ]
}

When nothing has been cached, the body is {"energy":null,"vehicles":[]}.