Schemas und Beispiele

Schemas und Beispiele der Admin-API

Diese Datei definiert die wiederverwendbaren JSON-Typen aus Endpunktreferenz. ? bedeutet optional bei Eingabe; | null bedeutet vorhanden und nullfähig in Antworten, sofern der Endpunkt nichts anderes sagt. DateTime ist eine RFC-3339-Zeichenfolge; Anfragezeiten benötigen einen Offset.

Primitive und Referenztypen

PositiveInt = integer > 0
NonnegativeInt = integer >= 0
DateTime = RFC3339 string, for example "2026-08-24T12:30:00Z"
NamedLookup = { id: PositiveInt, name: string }
SiteRef = { id: PositiveInt, name: string|null }
Cost = { currency: string, net: number, tax: number, total: number }

Unbekannte zukünftige Felder sollten ignoriert werden. IDs sind JSON-Zahlen, außer opaken Cursorn und vom Portal verwalteten Token-IDs. Die API liefert keine unmaskierten RFID-UIDs, Gerätepasswörter, Workspace-Tokens, contractId, Anbieter-Geheimnisse oder ungeschwärzten geheimnisähnlichen Konfigurationswerte.

Typumwandlung von Anfragen und unbekannte Eigenschaften

Die API verwendet keine globale Regel zur Zahlenumwandlung:

  • Jede Ressourcenpfad-ID und jeder numerische Abfrageparameter akzeptiert eine Dezimalzeichenfolge wie "12", sofern sie die dokumentierten Ganzzahl- und Bereichsgrenzen erfüllt.
  • Workspace-countryId, Standort-countryId/timezoneId, numerische Felder für Gerätestandort/Anschluss und Befehle sowie sämtliche numerischen Tarif- und Ladeprofilfelder werden auch aus numerischen JSON-Zeichenfolgen umgewandelt.
  • Breiten-/Längengrad, Ladegerät-smartMode, alle Leistungsmanagement- und Berichtszeitplanzahlen sowie IDs und Werte in Bodys für Benutzer/RFID/Zugriff/Grenzen/lokale Benutzer müssen JSON-Zahlen sein und werden nicht umgewandelt.
  • Body-Objekte für Tarife, Ladeprofile, Berichtszeitpläne und Benutzer weisen unbekannte Eigenschaften mit 422 zurück. Workspace-, Standort-, Leistungsmanagement-, andere Ladegeräte-/Berichtsobjekte und Query-Objekte ignorieren unbekannte Eigenschaften.

Diese Angaben beschreiben das Transportverhalten, keine Empfehlung: Clients sollten für numerische Body-Felder JSON-Zahlen senden.

Workspace- und Standorttypen

Workspace = {
  id: PositiveInt,
  name: string,
  email: string|null,
  website: string|null,
  address: {
    line1: string|null, line2: string|null, postalCode: string|null,
    city: string|null, state: string|null, countryId: PositiveInt,
    countryCode: string, countryName: string
  },
  createdAt: DateTime,
  updatedAt: DateTime
}

Site = {
  id: PositiveInt,
  name: string,
  description: string|null,
  address: {
    line1: string|null, line2: string|null, postalCode: string|null,
    city: string|null, state: string|null, countryId: PositiveInt,
    countryCode: string, countryName: string
  },
  timezone: { id: PositiveInt, name: string },
  latitude: number|null,
  longitude: number|null,
  chargerCount: integer
}

SiteSession = {
  id: PositiveInt,
  charger: { id: PositiveInt, name: string },
  portId: PositiveInt,
  connectorId: integer,
  active: boolean,
  startedAt: DateTime,
  stoppedAt: DateTime|null,
  durationSeconds: integer|null,
  energyWh: number,
  costs: Cost[]
}

MetricsWindow = {
  from: DateTime, to: DateTime, sessionLimit: integer,
  sessionsIncluded: integer, totalsCapped: boolean
}

GET /sites/:siteId liefert { site, recentSessions, totals, metricsWindow }. Sein site ergänzt den Basisstandort um eigenen Geräte-/Anschlussstatus; totals enthält sessions, energyWh, energyKwh, durationSeconds und costs: Cost[].

Standortreferenzen sind { countries: {countryId, countryCode, name}[], timezones: {timezoneId, name}[] } mit numerischen IDs und Namen/Codes als Zeichenfolgen.

DashboardSession = {
  id: PositiveInt, chargerId: PositiveInt, connectorId: PositiveInt,
  userId: PositiveInt|null, userName: string|null, chargerName: string|null,
  site: SiteRef|null, status: string|null, energyWh: number,
  startedAt: DateTime|null, stoppedAt: DateTime|null,
  costs: Array<{ currency: string|null, price: number, tax: number }>
}

Dashboard = {
  window: { from: DateTime, to: DateTime, maxSessions: 1000 },
  stats: { chargerCount: integer, onlineChargerCount: integer, siteCount: integer, userCount: integer },
  sessions: DashboardSession[],
  analytics: {
    totals: { sessions: integer, energyWh: number, durationSeconds: integer, costs: Array<{currency:string, amount:number}> },
    daily: Array<{ date:string, sessions:integer, energyWh:number, costs:Array<{currency:string, amount:number}> }>,
    sites: Array<{ id:PositiveInt, name:string|null, sessions:integer, energyWh:number, costs:Array<{currency:string, amount:number}> }>,
    chargers: Array<{ id:PositiveInt, name:string|null, siteId:PositiveInt|null, siteName:string|null, sessions:integer, energyWh:number, costs:Array<{currency:string, amount:number}> }>
  }
}

SiteDetailCharger = {
  id: PositiveInt, name: string|null, identifier: string|null, status: string,
  connection: { lastSeenAt: DateTime|null, leaseExpiresAt: DateTime|null }|null,
  connectors: Array<{ evseId:PositiveInt, evseNumber:integer, portId:PositiveInt, connectorId:integer, status:string|null }>,
  sessionCount: integer,
  totals: { sessions:integer, energyWh:number, energyKwh:number, durationSeconds:integer, costs:Cost[] }
}

Beispiel für Workspace-Patch und Antwort:

PATCH /v2/admin
Authorization: Bearer evc_ws_<selector>.<secret>
Idempotency-Key: workspace-contact-20260824
Content-Type: application/json

{"email":"ops@example.com","city":"Riga"}
{
  "workspace": {
    "id": 7,
    "name": "Example CPO",
    "email": "ops@example.com",
    "website": null,
    "address": {
      "line1": "1 Example Street",
      "line2": null,
      "postalCode": "LV-1001",
      "city": "Riga",
      "state": null,
      "countryId": 1,
      "countryCode": "LV",
      "countryName": "Latvia"
    },
    "createdAt": "2026-01-01T00:00:00.000Z",
    "updatedAt": "2026-08-24T12:30:00.000Z"
  }
}

Beispiel für Standorterstellung/-änderung (Felder mit Standardwerten dürfen fehlen):

{
  "name": "Main depot",
  "addressLine1": "1 Example Street",
  "city": "Riga",
  "countryId": 1,
  "timezoneId": 1,
  "latitude": 56.9496,
  "longitude": 24.1052
}

Leistungsmanagement-Antwort

PowerConfiguration = {
  site: { id: PositiveInt, updatedAt: DateTime },
  chargepoints: Array<{
    id: PositiveInt, name: string|null,
    compatible: boolean, compatibility: string, // values come from shared capability projection
    ...additional smart-charging capability flags
  }>,
  pools: Array<{
    id: PositiveInt, parentId: PositiveInt|null, name: string|null,
    limit: integer, defaultLimit: integer|null, mode: integer|string|null
  }>,
  assignments: Array<{
    poolId: PositiveInt, chargepointId: PositiveInt, priority: integer,
    chargingProfileId: PositiveInt|null,
    chargingProfileSynced: integer|null,
    limit: number|null
  }>,
  meterSources: Array<{
    id: PositiveInt, poolId: PositiveInt, sourceId: PositiveInt,
    provider: string, name: string|null, externalId: string,
    measurementMode: string, valueMode: string,
    reserveA: integer, offlineSafeA: integer, ttlSeconds: integer,
    enabled: boolean, lastComputedLimitA: number|null,
    lastComputedAt: DateTime|null, lastStatus: string|null,
    lastSeenAt: DateTime|null, effectiveLimitA: number|null
  }>,
  connectors: Array<{
    id: PositiveInt, connectorId: integer, chargepointId: PositiveInt,
    status: string|null
  }>
}

Die exakten Namen zusätzlicher Kompatibilitätsfelder erzeugt smartChargingCompatibility(); sein Rückgabetyp ist im Quelltext nicht ausdrücklich benannt. Nur bei diesem Antwortfragment lässt sich die geschlossene Feldliste nicht aus einem exportierten Typ bestimmen. Zusätzliche Felder werden daher bewusst als unklar markiert statt erfunden.

Ersetzungsbeispiel:

{
  "pools": [
    {
      "name": "Depot supply",
      "limit": 125,
      "meterSources": [
        {
          "externalId": "meter-42",
          "measurementMode": "available_headroom",
          "enabled": true
        }
      ],
      "children": [
        {"chargepointId": 11, "priority": 10},
        {"name": "Secondary", "limit": 32, "children": []}
      ]
    }
  ]
}

Ladegerätetypen

Charger = {
  id: PositiveInt, name: string, identifier: string, cpoId: PositiveInt,
  site: { id: PositiveInt, name: string }, status: string,
  isPublic: boolean, invertedRfid: boolean, smartMode: integer,
  automationDisabled: boolean, provisioned: boolean,
  connection: {
    protocol: string|null, lastSeenAt: DateTime|null, leaseExpiresAt: DateTime|null
  } | null,
  evses: Array<{ id: PositiveInt, number: integer, status: string|null }>,
  connectors: Array<{
    evseId: PositiveInt, evseNumber: integer, status: string|null,
    id: PositiveInt, connectorId: integer, portNumber: integer,
    format: { id: PositiveInt, name: string, description: string|null },
    type: { id: PositiveInt, name: string, description: string|null },
    powerType: { id: PositiveInt, name: string, description: string|null },
    maxVoltage: number, maxAmperage: number, maxElectricPower: number,
    maxPowerKw: number
  }>,
  createdAt: DateTime, updatedAt: DateTime
}

ChargerDetail = Charger & {
  configuration: Array<{
    chargepointConfigId: PositiveInt, key: string,
    value: string|null, readonly: boolean|number, setByServer: boolean|number,
    modified: DateTime
  }>,
  firmware: { status: string|null, statusAt: DateTime|null, version: string|null, bootAt: DateTime|null },
  counts: { localUsers: integer, sessions: integer, tariffAssignments: integer, profileAssignments: integer }
}

Die Listenprojektion ergänzt begrenzte Kennzahlenfelder und liefert metricsWindow; die Detailprojektion verwendet die obige Form. Konfigurationswerte sensibler Schlüssel sind exakt "[REDACTED]".

PublicReadiness = {
  ready: boolean,
  missingRequirements: Array<"site_coordinates"|"connector_tariffs"|"billing_plan"|"stripe_connect"|"legacy_payment_data">,
  commercialGateEnabled: boolean, siteCoordinatesDefined: boolean,
  allConnectorsHaveTariffs: boolean, connectorsMissingTariffs: integer[],
  connectorCount: integer, paymentDataDefined: boolean,
  billingAccountId: PositiveInt|null, planCode: string|null,
  billingPlanEligible: boolean, stripeConnectReady: boolean,
  stripeConnectState: "active"|"action_required"|"pending"|"not_configured",
  connectorIds: integer[], missingTariffConnectorIds: integer[]
}

RedactedOcppLog = {
  ocppServerLogId: PositiveInt, timestamp: DateTime, logLevelId: PositiveInt,
  logAction: string|null, logDirection: string|null, logMessage: string|null,
  messageId: string|null, transactionLogId: PositiveInt|null,
  logLevel: { name:string }|null
}

CompositeSchedule = {
  id: PositiveInt, chargepointId: PositiveInt, connectorId: integer,
  evseId: PositiveInt|null, scheduleStart: DateTime, duration: integer,
  minChargingRate: number|null, chargingRateUnitId: PositiveInt,
  chargingRateUnit: string|null, chargingRateUnitDescription: string|null,
  periods: Array<{ id:PositiveInt, startPeriod:number, limit:number, numberPhases:integer|null, phaseToUse:integer|null }>
}

Ein erfolgreicher Anschluss-Patch liefert genau { portId, connectorId, ocpiConnectorFormatEnumId, ocpiConnectorTypeEnumId, ocpiPowerTypeEnumId, maxVoltage, maxAmperage, maxElectricPower }.

connectorLookups enthält folgende Referenzformen: Formate verwenden { ocpiConnectorFormatEnumId, name, description }, Typen { ocpiConnectorTypeEnumId, name, description, icon }, Stromarten { ocpiPowerTypeEnumId, name, shortDescr, description, numPhases }.

Beispiele für Erstellung und Anschlussaktualisierung:

{"name":"Warehouse 1","identifier":"cp-warehouse-1","password":"initial-secret","siteId":3}
{
  "connectorFormatId": 1,
  "connectorTypeId": 2,
  "powerTypeId": 1,
  "maxVoltage": 400,
  "maxAmperage": 32,
  "maxElectricPower": 22000
}

Befehlsantwortobjekte enthalten status: string. Trigger enthält zusätzlich connectorResults: { connectorId: number, status: string }[]; kombinierte Zeitpläne zusätzlich connectorId und compositeSchedule (oder null). Statuswerte sind gespeicherte OCPP- oder nachgelagerte Ergebnisse und werden durch die Route nicht auf eine geschlossene Enumeration begrenzt.

Berichtstypen

ReportSession = {
  id: PositiveInt,
  charger: { id: PositiveInt, name: string, site: { id: PositiveInt, name: string }|null },
  portId: PositiveInt, connectorId: integer,
  user: { id: PositiveInt, name: string }|null,
  active: boolean, energyWh: number,
  startedAt: DateTime, stoppedAt: DateTime|null,
  durationSeconds: integer|null, costs: Cost[]
}

ReportSchedule = {
  id: PositiveInt, workspaceId: PositiveInt, enabled: boolean,
  recipientEmail: string, format: "csv"|"pdf", sendDay: integer,
  sendTime: string, createdAt: DateTime, updatedAt: DateTime,
  lastDeliveryPeriod: string|null, lastDeliveryStatus: string|null,
  lastDeliveryAttemptAt: DateTime|null, lastDeliveryAttemptCount: integer,
  lastDeliveredPeriod: string|null, lastDeliveredAt: DateTime|null
}

ReportDataResponse = {
  items: ReportSession[],
  pageTotals: { sessions:integer, energyWh:number, durationSeconds:integer, costs:Cost[] },
  page: { limit:integer, nextCursor:string|null },
  range: { from:DateTime, to:DateTime, toExclusive:true }
}

MeasurementPoint = { meterValueId:PositiveInt, timestamp:DateTime, elapsedSeconds:integer, value:number }
Measurement = {
  name:string,
  unit:{ symbol:string|null, description:string|null },
  lines:Array<{ phase:string, points:MeasurementPoint[] }>
}
MeasurementsResponse = {
  transactionLogId:PositiveInt, measurements:Measurement[],
  page:{ limit:integer, nextCursor:string|null, sampleValuesTruncated:boolean, sampleLimitPerMeterValue:64 }
}

Beispiel für Zeitplananfrage und -antwort:

{"enabled":true,"recipientEmail":"reports@example.com","format":"csv","sendDay":5,"sendTime":"08:30"}
{
  "schedule": {
    "id": 4,
    "workspaceId": 7,
    "enabled": true,
    "recipientEmail": "reports@example.com",
    "format": "csv",
    "sendDay": 5,
    "sendTime": "08:30",
    "createdAt": "2026-08-01T10:00:00.000Z",
    "updatedAt": "2026-08-24T12:30:00.000Z",
    "lastDeliveryPeriod": null,
    "lastDeliveryStatus": null,
    "lastDeliveryAttemptAt": null,
    "lastDeliveryAttemptCount": 0,
    "lastDeliveredPeriod": null,
    "lastDeliveredAt": null
  }
}

Tariftypen

TariffComponent = {
  id: PositiveInt,
  type: NamedLookup, season: NamedLookup,
  validFromMonth: number|null, validToMonth: number|null,
  validFromWeekDay: number|null, validToWeekDay: number|null,
  validFromHour: number|null, validToHour: number|null,
  priority: number, price: number
}

Tariff = {
  id: PositiveInt, cpoId: PositiveInt, name: string,
  type: NamedLookup,
  site: { id: PositiveInt, name: string, timezone: string|null }|null,
  currency: { id: PositiveInt, code: string, sign: string },
  biddingZone: { id: PositiveInt, code: string, name: string }|null,
  tax: number, fallbackPrice: number|null, price: number|null,
  components: TariffComponent[], assignmentCount: integer
}

TariffAssignment = {
  id: PositiveInt, chargerId: PositiveInt, connectorId: integer,
  tariff: { id: PositiveInt, name: string, currency: { code: string, sign: string } },
  createdAt: DateTime, updatedAt: DateTime
}

MarketPrice = {
  id: PositiveInt, value: number, currencyId: PositiveInt,
  startsAt: integer, endsAt: integer,
  startsAtIso: DateTime, endsAtIso: DateTime, intervalMinutes: number
}

TariffLookups = {
  currencies:Array<{id:PositiveInt,code:string,sign:string,fractionalUnit:string,enabled:boolean,minimalValue:integer}>,
  biddingZones:Array<{id:PositiveInt,code:string,name:string,currencyId:PositiveInt,enabled:boolean}>,
  currencyRates:Array<{currencyId:PositiveInt,rate:number,updatedAt:DateTime}>,
  componentTypes:NamedLookup[], seasons:NamedLookup[], tariffTypes:NamedLookup[]
}

Beispiele für Tarif und Komponenten:

{"name":"Public AC","currencyCode":"EUR","biddingZoneId":1,"tax":21}
{
  "components": [
    {"typeId":1,"seasonId":1,"priority":0,"price":0.25,"validFromHour":0,"validToHour":24}
  ]
}

Ladeprofiltypen

SchedulePeriod = { id: PositiveInt, startPeriod: number, limit: number, numberOfPhases: integer|null }

ChargingProfile = {
  id: PositiveInt, cpoId: PositiveInt, label: string, description: string|null,
  stackLevel: number, location: NamedLookup, purpose: NamedLookup,
  kind: NamedLookup, recurrency: NamedLookup|null,
  validFrom: DateTime|null, validTo: DateTime|null,
  startSchedule: DateTime|null, durationSeconds: number|null,
  rateUnit: NamedLookup, minChargingRate: number|null,
  schedule: SchedulePeriod[], assignmentCount: integer,
  createdAt: DateTime, updatedAt: DateTime
}

ProfileAssignment = {
  id: PositiveInt, chargerId: PositiveInt, connectorId: integer,
  synced: boolean, syncCode: integer,
  syncStatus: "accepted"|"rejected"|"unknown",
  profile: { id: PositiveInt, label: string, stackLevel: number, purpose: string, kind: string|null },
  createdAt: DateTime, updatedAt: DateTime
}

ChargingProfileLookups = {
  locations:NamedLookup[], purposes:NamedLookup[], kinds:NamedLookup[],
  recurrencyKinds:NamedLookup[],
  rateUnits:Array<{id:PositiveInt,name:string,supported:boolean}>,
  allowedRateUnits:string[]
}

Beispiele für Erstellung und Zeitpläne:

{
  "label":"Depot cap","locationId":3,"stackLevel":1,"purposeId":1,"kindId":1,
  "recurrencyKindId":null,"validFrom":null,"validTo":null,"startSchedule":null,
  "rateUnitId":1,"minChargingRate":6,
  "schedule":[{"startPeriod":0,"limit":32,"numberOfPhases":3}]
}
{"rateUnitId":1,"periods":[{"startPeriod":0,"limit":16,"numberOfPhases":3}]}

Benutzertypen

RFID = { id: PositiveInt, maskedUid: string, name: string|null, type: string, valid: boolean }
AccessItem = { id: PositiveInt, chargerId: PositiveInt, chargerName: string, expiresAt: DateTime|null, site: SiteRef|null }
Access = { allChargers: boolean, chargerIds: PositiveInt[], items: AccessItem[] }
Limit = { id: PositiveInt, limitTypeId: PositiveInt, label: string, energyValue: integer, timeValue: integer }

User = {
  id: PositiveInt, membershipId: PositiveInt, name: string, email: string,
  rfids: RFID[], access: AccessItem[], limitCount: integer
}

UserDetail = User & {
  phone: string|null, createdAt: DateTime|null, limits: Limit[]
}

Vehicle = {
  id: PositiveInt, name: string|null, provider: string|null, status: string|null,
  vin: string|null, identifier: string|null, model: string|null,
  batteryCapacityWh: number|null, createdAt: DateTime,
  telemetry: { soc: number|null, chargeLimitSoc: number|null, recordedAt: DateTime|null }|null
}

LocalUser = {
  id: PositiveInt, customerId: PositiveInt, name: string, email: string,
  expiresAt: DateTime|null, systemManaged: boolean
}

LocalUserMutation = {
  chargepointLocalUserId: PositiveInt,
  customerId: PositiveInt,
  expiryDate: DateTime|null,
  customer: {} // `contractId` is removed by the workspace-admin response boundary
}
LocalUserUpdate = { id:PositiveInt, customerId:PositiveInt, expiresAt:DateTime|null }

Invitation = {
  email:string, name:string, chargerIds:PositiveInt[], rfids:string[]
}

UserListResponse = {
  items:User[], invitations:Invitation[], chargers:Array<{id:PositiveInt,name:string,identifier:string|null,site:SiteRef|null}>,
  page:{ nextCursor:number|string|null, memberNextCursor:number|null, invitationNextCursor:string|null, limit:integer }
}

UserSession = {
  id:PositiveInt, chargerId:PositiveInt, chargerName:string|null,
  connectorId:PositiveInt, site:SiteRef|null, energyWh:number,
  startedAt:DateTime|null, stoppedAt:DateTime|null
}

Die Änderungsantwort von POST /chargers/:chargerId/local-users und das Bestandskundenergebnis von POST /chargers/:chargerId/local-users/invitations liefern LocalUserMutation; PATCH /chargers/:chargerId/local-users/:localUserId liefert LocalUserUpdate. Der Listenendpunkt verwendet LocalUser. Clients sollten sie als bewusst unterschiedliche Antworttypen behandeln.

Beispiele für Benutzer/Einladungen/RFID/Zugriff:

{"email":"driver@example.com","name":"Example Driver"}
{
  "email":"new.driver@example.com",
  "name":"New Driver",
  "rfid":"04AABBCCDD",
  "allChargers":false,
  "chargerIds":[11,12]
}
{"uid":"04AABBCCDD","name":"Blue card"}
{"allChargers":false,"chargerIds":[11,12]}

Erfolgreiche Schreibvorgänge geben niemals die unmaskierte RFID-UID zurück. Beispiel:

{"rfid":{"id":31,"maskedUid":"******CCDD","name":"Blue card","type":"RFID","valid":true}}

Leere und binäre Erfolgsantworten

  • 204 bedeutet kein Antwortinhalt.
  • Eine erfolgreiche Ladegeräte-QR-Antwort enthält PNG-Bytes, kein JSON.
  • Ein erfolgreicher Berichtsexport enthält CSV- oder PDF-Bytes, kein JSON.
  • JSON-Fehlerantworten beider binären Endpunkte finden Sie unter Antwort- und Fehlervertrag.

Weitere Beispiele für Änderungs-Bodys

Die Pfade dieser reinen Beispieltabelle sind relativ zu /v2/admin; vollständige Pfade stehen unter Endpunktreferenz. Die längeren Beispiele oben behandeln Workspace, Standort, Leistungsmanagement, Geräteerstellung/Anschlüsse, Berichtszeitpläne, Tarife/Komponenten, Profile/Zeitpläne, Benutzer/Einladungen, RFID und Berechtigungsersatz. Jede andere Änderung mit Body verwendet exakt eine dieser Formen:

EndpunktBeispiel-JSON-Body
PATCH /chargers/:chargerId{"name":"Warehouse east","siteId":4,"invertedRfid":false,"smartMode":1,"automationDisabled":false}; jede nicht leere Teilmenge wird akzeptiert
PATCH /chargers/:chargerId/credentials{"password":"replacement-secret"}
PATCH /chargers/:chargerId/public-listing{"isPublic":true}
PATCH /chargers/:chargerId/configuration{"key":"HeartbeatInterval","value":"60"}
POST /chargers/:chargerId/firmware{"url":"https://firmware.example.com/charger-v2.bin"}
POST /chargers/:chargerId/commands/reset{"resetType":"Soft"}
POST /chargers/:chargerId/commands/availability{"availabilityType":"Operative"}
POST /chargers/:chargerId/commands/trigger{"messageType":"StatusNotification"}
POST /chargers/:chargerId/commands/unlock{"connectorId":1}
POST /chargers/:chargerId/commands/composite-schedule{"connectorId":0,"durationSeconds":86400,"chargingRateUnit":"W"}
POST /chargers/:chargerId/tariff-assignments{"tariffId":17,"connectorId":0}
PATCH /chargers/:chargerId/tariff-assignments/:assignmentId{"tariffId":17,"connectorId":1}
POST oder PATCH /chargers/:chargerId/profile-assignments[...]{"profileId":8,"connectorId":1}
PATCH /users/:userId{"name":"Updated Driver"}
POST /users/invitations/resend oder DELETE /users/invitations{"email":"new.driver@example.com"}
PATCH /users/:userId/rfids/:rfidId{"name":"Replacement label"}; null entfernt die Bezeichnung
POST /users/:userId/limits{"limitTypeId":1,"energyValue":20000,"timeValue":0}
PATCH /users/:userId/limits/:limitId{"energyValue":25000}
POST /chargers/:chargerId/local-users{"customerId":42,"expiresAt":"2026-12-31T23:59:59Z"}
POST /chargers/:chargerId/local-users/invitations oder sein Gegenstück DELETE{"email":"driver@example.com"}
PATCH /chargers/:chargerId/local-users/:localUserId{"expiresAt":null}

Alle anderen Änderungen haben keinen Request-Body. Sie erfordern trotzdem genau einen Idempotency-Key-Header.

Weitere Erfolgsbeispiele

Leere Listen sind gültig und machen die Antwortumschläge auf oberster Ebene eindeutig:

{"items":[],"metricsWindow":{"from":"2026-05-26T00:00:00.000Z","to":"2026-08-24T00:00:00.000Z","sessionLimit":10000,"sessionsIncluded":0,"totalsCapped":false},"connectorLookups":{"formats":[],"types":[],"powerTypes":[]}}
{"items":[],"pageTotals":{"sessions":0,"energyWh":0,"durationSeconds":0,"costs":[]},"page":{"limit":50,"nextCursor":null},"range":{"from":"2026-07-01T00:00:00.000Z","to":"2026-08-01T00:00:00.000Z","toExclusive":true}}
{"status":"Accepted"}
{"status":"Accepted","connectorResults":[{"connectorId":1,"status":"Accepted"}]}
{"sent":true,"format":"csv","rowCount":12,"range":{"from":"2026-07-01T00:00:00.000Z","to":"2026-08-01T00:00:00.000Z"}}
{"items":[],"invitations":[],"chargers":[],"page":{"nextCursor":null,"memberNextCursor":null,"invitationNextCursor":null,"limit":50}}

Bei objektbasierten Antworten setzen Sie das oben benannte DTO in den unter Endpunktreferenz angegebenen Umschlag ein; zum Beispiel ist Tariferstellung { "tariff": Tariff }, Profilerstellung { "profile": ChargingProfile } und Benutzererstellung { "user": User }.