JouloDocs

Charging data

Push monthly kWh totals per account, idempotent per month • the CSV delivery model, over REST.

Charging data

Deliver charging data as monthly aggregates — the same model as the CSV delivery, over REST. You already have the data; one generic, idempotent endpoint scales to every customer without per-charger integration on Joulo's side.

Only MID-metered kWh counts toward ERE. Deliver the MID-metered energy per connection per month; Joulo books the month aggregate.

Push a batch

POST /v1/sessions:batch — scope cpo:sessions:write

curl -X POST https://api.joulo.nl/functions/v1/api/v1/sessions:batch \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "account_id": "60092124-c768-4191-9c9d-55ef3fc49999",
    "source": "your-csms",
    "months": [
      { "period": "2026-01", "total_kwh": 182.4, "session_count": 21 },
      { "period": "2026-02", "total_kwh": 143.9, "session_count": 17 }
    ]
  }'
{
  "ok": true,
  "account_id": "60092124-…",
  "connection_id": "2eca20d8-…",
  "accepted": 2,
  "outside_mandate": 0,
  "locked": 0,
  "invalid": 0,
  "results": [
    { "period": "2026-01-01", "status": "ingested" },
    { "period": "2026-02-01", "status": "updated" }
  ]
}

Body

FieldRequiredDescription
account_idyesThe account to deliver for.
connection_idnoDisambiguates a multi-connection account.
sourcenoA label for the origin of the data (e.g. your CSMS name).
monthsyes1–240 months. Each: { period, total_kwh, session_count? }.
months[].periodyesYYYY-MM (or YYYY-MM-DD, normalized to the month).
months[].total_kwhyesMID-metered kWh for the month (>= 0).
months[].session_countnoNumber of sessions, for reporting.

Idempotency

Delivery is idempotent per (connection, month): re-pushing a month overwrites its total rather than adding to it, so a cumulative or repeated delivery never double-counts. Each month's status in results is:

StatusMeaning
ingestedFirst delivery for this month.
updatedOverwrote an existing (not-yet-paid) month.
outside_mandateStored, but the signed machtiging starts after this month, so it will never count.
lockedThe month is already paid out and can't be changed.
invalidThe period or total_kwh was malformed (skipped).

accepted counts every stored month, outside_mandate included.

Months before the machtiging starts

A customer who switches from another ERE provider signs now, but their machtiging starts on 1 January of the next year. A month before that date is stored like any other, and reported as outside_mandate: we will never register it. The rule on your side is the same one we apply: a month counts only from mandate_valid_from (on GET /v1/accounts and GET /v1/ere-positions).

Before the customer signs, a month keeps its normal status. It is waiting for the machtiging, not outside it.

Deliver the complete month total each time. A re-push replaces the stored total, so a partial month would lower it.

Errors

HTTPerror
400invalid_account_id, no_months, too_many_months
404account_not_found
409no_connection

Raw payloads are archived as evidence.