Skip to content

Instantly share code, notes, and snippets.

@hyun007
Last active February 16, 2025 20:58
Show Gist options
  • Save hyun007/c689fbed10424b558f140c54851659e3 to your computer and use it in GitHub Desktop.
Save hyun007/c689fbed10424b558f140c54851659e3 to your computer and use it in GitHub Desktop.
span.io api documentation

Span.io API Documentation

The Span API does not at this time require any authentication. This will probably change in the future.

Description: Gets panel summary, firmware version, door state, serial number, network status Request: GET /api/v1/status Response:

{
  "software": {
    "firmwareVersion": "spanos2/r202216/04",
    "updateStatus": "idle",
    "env": "prod"
  },
  "system": {
    "manufacturer": "Span",
    "serial": "nt-2139-c1ac4",
    "model": "00200",
    "doorState": "OPEN",
    "uptime": 1475028
  },
  "network": {
    "eth0Link": false,
    "wlanLink": true,
    "wwanLink": false
  }
}

Description: Gets panel state, grid state, power draw for whole panel, and for each breaker Request: GET /api/v1/panel Response:

{
  "mainRelayState": "CLOSED",
  "instantGridPowerW": 8361.962890625,
  "feedthroughPowerW": -82.79021826386452,
  "gridSampleStartMs": 836674,
  "gridSampleEndMs": 836686,
  "dsmGridState": "DSM_GRID_UP",
  "dsmState": "DSM_ON_GRID",
  "currentRunConfig": "PANEL_ON_GRID",
  "branches": [
    {
      "id": 1,
      "relayState": "CLOSED",
      "instantPowerW": -3.015791177749634,
      "importedActiveEnergyWh": 1.4696391820907593,
      "exportedActiveEnergyWh": 12594.255859375
    },
    {
      "id": 2,
      "relayState": "CLOSED",
      "instantPowerW": -8.53760051727295,
      "importedActiveEnergyWh": 343.6731262207031,
      "exportedActiveEnergyWh": 19945.1328125
    },
    {
      "id": 3,
      "relayState": "CLOSED",
      "instantPowerW": -4.699003219604492,
      "importedActiveEnergyWh": 27.433591842651367,
      "exportedActiveEnergyWh": 6132.89697265625
    },
	...
  ]
}

Description: Get information on individual breakers, their positions, names, state, priority Request: GET /api/v1/circuits Response:

{
  "spaces": {
    "xxxxxxxxxxxxxxx": {
      "id": "xxxxxxxxxxxxxxx",
      "name": "Garage 220",
      "relayState": "CLOSED",
      "instantPowerW": -3625.2879638671875,
      "instantPowerUpdateTimeS": 1656531017,
      "importEnergyAccumWh": 4146.5565185546875,
      "exportEnergyAccumWh": 313066.625,
      "energyAccumUpdateTimeS": 1656530716,
      "tabs": [
        12,
        14
      ],
      "priority": "NOT_ESSENTIAL",
      "is_user_controllable": true,
      "is_sheddable": false,
      "is_never_backup": false
    },
    "xxxxxxxxxxxxxxx": {
      "id": "xxxxxxxxxxxxxxx",
      "name": "A/C condeser",
      "relayState": "CLOSED",
      "instantPowerW": -2428.6781005859375,
      "instantPowerUpdateTimeS": 1656531017,
      "importEnergyAccumWh": 11638.456787109375,
      "exportEnergyAccumWh": 752839.09375,
      "energyAccumUpdateTimeS": 1656530716,
      "tabs": [
        16,
        18
      ],
      "priority": "MUST_HAVE",
      "is_user_controllable": true,
      "is_sheddable": false,
      "is_never_backup": false
    },
    "xxxxxxxxxxxxxxx": {
      "id": "xxxxxxxxxxxxxxx",
      "name": "Tesla charger",
      "relayState": "CLOSED",
      "instantPowerW": -503.9554138183594,
      "instantPowerUpdateTimeS": 1656531017,
      "importEnergyAccumWh": 30.012138724327087,
      "exportEnergyAccumWh": 218781.4375,
      "energyAccumUpdateTimeS": 1656530716,
      "tabs": [
        26,
        28
      ],
      "priority": "NICE_TO_HAVE",
      "is_user_controllable": true,
      "is_sheddable": false,
      "is_never_backup": false
    },
    ...
  }
}

Description: Change breaker state, turn on/off a breaker Valid Values: OPEN, CLOSED Request: POST /api/v1/circuits/xxxxxxxxxxxxxxx

{
	"relay_state_in": {
		"relayState":"OPEN"
	}
}

Response:

{
	"id":"xxxxxxxxxxxxxxx",
	"name":"Garage outlets*",
	"relayState":"OPEN",
	"instantPowerW":0.0,
	"instantPowerUpdateTimeS":1656538555,
	"importEnergyAccumWh":722.7332153320312,
	"exportEnergyAccumWh":973.8363037109375,
	"energyAccumUpdateTimeS":1656538493,
	"tabs":[6],
	"priority":"NOT_ESSENTIAL",
	"is_user_controllable":true,
	"is_sheddable":false,
	"is_never_backup":false
}

Description: Change breaker priority Valid Values: MUST_HAVE, NICE_TO_HAVE, NOT_ESSENTIAL Request: POST /api/v1/circuits/xxxxxxxxxxxxxxx

{
	"priority_in": {
		"priority":"NICE_TO_HAVE"
	}
}

Response:

{
	"id":"xxxxxxxxxxxxxxx",
	"name":"Garage outlets*",
	"relayState":"OPEN",
	"instantPowerW":0.0,
	"instantPowerUpdateTimeS":1656539097,
	"importEnergyAccumWh":722.7332153320312,
	"exportEnergyAccumWh":973.8363037109375,
	"energyAccumUpdateTimeS":1656538493,
	"tabs":[6],
	"priority":"NICE_TO_HAVE",
	"is_user_controllable":true,
	"is_sheddable":false,
	"is_never_backup":false
}
@ahasha
Copy link

ahasha commented Aug 10, 2024

So pleased to find this! I got a new Span a couple of weeks ago and was feeling disappointed about the available data exports from the app relative to the iotawatt I had installed in my old panel. I'd like to build a client that samples the panel API every second and stores the instantaneous power data in a time-series database so I can recreate the analytics I was used to having on iotawatt.

@pavandave
Copy link

There is an additional API that shows the battery percentage if you have a battery/solar connected:

GET <IP_Address>api/v1/storage/soe

Output:
{ "soe": { "percentage": 83 } }

@Panda88CO
Copy link

I have additional fields in the panel returns

"mainMeterEnergy":
{
"producedEnergyWh": 0.006601779256016016,
"consumedEnergyWh": 5307234.375
},
and
"feedthroughEnergy":
{
"producedEnergyWh": 7466325.181264432,
"consumedEnergyWh": 5262319.911074999
}

Any idea what they represent - is it related to solar (being the difference between Produced and consumed )
but the numbers seem too small (only 5MWh over lifespan) or if uptime is in sec it is too large (only 37 days)
I do not see a time field besides uptime in status

@dblessing
Copy link

dblessing commented Dec 24, 2024

Anyone encountered Client SPAN_API_User_2 not authorized to <method> on <endpoint> error for endpoints like listing clients or deleting clients? I can register just fine, and call most other endpoints.

@giri-v
Copy link

giri-v commented Jan 15, 2025

Thanks to @hyun007 for his work on the API. Anyone have definitions for any of the fields?

@muenchris
Copy link

muenchris commented Feb 11, 2025

There is an additional API that shows the battery percentage if you have a battery/solar connected:

GET <IP_Address>api/v1/storage/soe

Output: { "soe": { "percentage": 83 } }

Do you know if there is an API call to get the "instantPower" from the Solar Array that the SPAN panel is connected to?

To elaborate a bit: My SPAN Panel is connected to a SolarEdge Inverter via Modbus. I can see my solar production in the SPAN App but the local API does not show this data. I am wondering if anyone has found a new local API that reflects this data
Since SPAN is keeping the Modbus connection to my SolarEdge inverter open and that inverter only supports once connection, I cannot access it directly using Modbus (ie.with the SolarEdge Plugin for HA).

@joergbattermann
Copy link

Does anyone know / has seen any API endpoints re: Span's "Span Drive" EV Charger for folks that have one of those? Would be curious if/what's exposed which might make it into i.e. the HA integration

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment