Model a site's circuits

Describe a site's wiring once, as a tree of circuits with their ratings, and attach each outlet to the circuit that feeds it.

4 min readEdit this page
On this page

Tell Flowion how a site is wired and it can share the site's power between the cars charging there. You describe it once: a location, a tree of circuits with their ratings, and which circuit feeds each outlet. From then on Flowion keeps every car within what its circuits can carry — see Keep a site within its electrical limits.

Location "Depot A"
 └─ Main     three-phase, 63 A   ← the grid connection
     ├─ Row 1  three-phase, 32 A   → outlets 1–4
     └─ Row 2  single-phase L2, 16 A → outlet 5

In the console, a location's Circuits tab shows the same tree, and Add circuit adds to it. Everything below works over the API too. Changing the wiring needs the asset.circuit.manage permission; reading it needs asset.circuit.read.

Create a location

POST/v1/projects/$PROJECT/locationsbash
curl -X POST "$API/projects/$PROJECT/locations" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Depot A",
       "address": {"line1": "Hamngatan 1", "city": "Stockholm",
                   "postalCode": "111 47", "country": "SE"}}'

address and coordinates are optional. An address needs at least line1 and country, or the request is refused with 422 invalidAddress.

Every location starts with one circuit: a three-phase circuit named Main, rated 32 A. It stands for the grid connection.

Set the Main circuit's rating

Find the Main circuit, then give it the rating of the site's main fuse:

GET/v1/locations/$LOCATION/circuitsbash
curl "$API/locations/$LOCATION/circuits" \
  -H "Authorization: Bearer $TOKEN"
PUT/v1/circuits/$MAIN/rated-currentbash
curl -X PUT "$API/circuits/$MAIN/rated-current" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"ratedCurrentAmps": 63}'

A rating is per line, in amperes: a three-phase 63 A circuit carries 63 A on each of L1, L2 and L3.

Add the circuits below it

Each sub-distribution board or group fuse that feeds chargers becomes a circuit, nested under the circuit that feeds it:

POST/v1/locations/$LOCATION/circuitsbash
curl -X POST "$API/locations/$LOCATION/circuits" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Row 1", "parentCircuitId": "'"$MAIN"'",
       "phaseCount": 3, "ratedCurrentAmps": 32}'
200Response
{
  "id": "2b6c1f0e-8d1a-4c47-9f5e-3a7d2c9b1e04",
  "locationId": "9a3e5d71-0c2b-4f6a-8e19-5b4d7c2a6f13",
  "parentCircuitId": "5f2a9c3e-1b7d-4e08-a6c4-0d9e8f7b2a51",
  "name": "Row 1",
  "phaseCount": 3,
  "line": null,
  "ratedCurrentAmps": 32,
  "createdAt": "2026-10-01T08:12:40Z",
  "updatedAt": "2026-10-01T08:12:40Z"
}
  • phaseCount is 1 or 3.

  • A single-phase circuit names its line: "L1", "L2" or "L3". A three-phase circuit leaves it out.

  • A single-phase circuit can only sit on a line its parent carries, and a circuit cannot be moved below itself. Both are refused.

  • parentCircuitId: null makes another top-level circuit, for a site with more than one grid connection.

Circuits below a parent may add up to more than the parent's rating. That is how real sites are built — eight 32 A chargers behind a 63 A supply — and Flowion handles it by never giving a car more than the tightest circuit above it can spare.

Change the tree later

ToCall
Rename a circuitPUT /circuits/{circuitId}/name with {"name": "..."}
Change its ratingPUT /circuits/{circuitId}/rated-current
Move it under another parentPATCH /circuits/{circuitId} with {"parentCircuitId": "..."}
Remove itDELETE /circuits/{circuitId}

A circuit's phase count and line are fixed once it is created; to change them, add a new circuit and move the outlets over. A circuit that still feeds others (409 hasChildCircuits) or is the location's last one (409 lastCircuitOnLocation) cannot be removed.

Attach each outlet to its circuit

An outlet is one place a car charges — the API calls it an EVSE. A charger with two outlets can have them on different circuits, so you attach outlets, not chargers. An outlet on no circuit is not load balanced.

List a charger's outlets, then attach one by its id:

GET/v1/charging-stations/$CHARGER/evsesbash
curl "$API/charging-stations/$CHARGER/evses" \
  -H "Authorization: Bearer $TOKEN"
PATCH/v1/charging-stations/$CHARGER/evses/$EVSE/circuitbash
curl -X PATCH "$API/charging-stations/$CHARGER/evses/$EVSE/circuit" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"circuitId": "'"$ROW_1"'"}'

Send "circuitId": null to detach it.

Attaching an outlet also places its charger at that circuit's location, and all of a charger's outlets are always at one location. To move a charger to another location, place every outlet in one request:

PUT/v1/charging-stations/$CHARGER/placementbash
curl -X PUT "$API/charging-stations/$CHARGER/placement" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"outlets": [{"evseId": "'"$EVSE_1"'", "circuitId": "'"$ROW_1"'"},
                   {"evseId": "'"$EVSE_2"'", "circuitId": "'"$ROW_1"'"}]}'

If the new location lets more cards charge than the old one, the move answers 409 confirmationRequired. Check that this is what you want, then send the same request with "confirmMorePermissive": true.

Say which line a single-phase outlet uses

A single-phase outlet on a three-phase circuit loads one line. Record which one, so Flowion counts its current there and nowhere else:

PATCH/v1/charging-stations/$CHARGER/evses/$EVSE/phase-rotationbash
curl -X PATCH "$API/charging-stations/$CHARGER/evses/$EVSE/phase-rotation" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"phaseRotation": "Sxx"}'

Three letters, one per phase of the outlet: R is the circuit's L1, S is L2, T is L3, and x is not connected. Sxx is a single-phase outlet on L2; RST is a three-phase outlet wired straight through. Some chargers report this themselves (reportedPhaseRotation); what you record wins. When neither is known, Flowion counts the outlet's current on every line of its circuit, which is the safe assumption but leaves capacity unused.

Read what a circuit is doing

QuestionCall
What is every line drawing right now, and which cars want more?GET /circuits/{circuitId}/stats
What did each line draw over the last day or week, against its rating?GET /circuits/{circuitId}/current?range=24h (or 7d)
The whole location at once: every circuit per line, every charger's draw and allowanceGET /locations/{locationId}/supply

stats reports each connector's demand as wantsMore, releasable (it has current it is not using, releasableAmps of it) or steady. When an energy monitor is on the circuit, its measured reading appears beside Flowion's own figure as monitorAmps.

supply gives, for each charger, what it draws (deliveredAmps), what Flowion currently allows it (allocatedAmps), whether it is being held back (constrained) and why (reason).

See why a charger got what it got

Every time Flowion raises or lowers a charger, it records why:

GET/v1/circuits/$CIRCUIT/allocation-log?limit=50bash
curl "$API/circuits/$CIRCUIT/allocation-log?limit=50" \
  -H "Authorization: Bearer $TOKEN"
200Response
{
  "data": [
    {
      "at": "2026-10-01T17:42:10Z",
      "circuitId": "2b6c1f0e-8d1a-4c47-9f5e-3a7d2c9b1e04",
      "connectorId": "c41e7a2d-5f3b-4a98-b0d6-7e1f2c8a9b35",
      "fromAmps": 16,
      "toAmps": 10,
      "reason": "circuitCeiling"
    }
  ]
}
reasonMeans
circuitCeilingA circuit above the charger is fully shared out
demandReleasedThe car was not using all of its allowance, so the rest went back
priceWindowThe session waits for, or charges in, a cheaper hour
deadlineThe session charges now because its finish time leaves no room to wait

The list is closed. It also holds priority and starvationFloor; treat them like circuitCeiling.

For a chart rather than a feed, GET /circuits/{circuitId}/allocation-decisions counts the same decisions per hour, direction and reason, over the last windowHours (24 by default, up to 720). Both calls also exist for a whole location: /locations/{locationId}/allocation-log and /locations/{locationId}/allocation-decisions.

Endpoints

Locations & Circuits · EVSEs & Connectors · Energy

In the API reference