Endpointy

Požadavky a odpovědi endpointů API pro správu pracovního prostoru

Toto je reference požadavků/odpovědí pro každý endpoint /v2/admin. Ověření, idempotence, limity požadavků, vytváření tokenů a význam rozsahů jsou popsány v API pro správu pracovního prostoru. Opakovaně použitelné typy polí a příklady jsou ve Schématech a příkladech. Každý řádek endpointu čtěte společně s Kontraktem odpovědí a chyb, který uvádí všechna možná sdílená a specifická neúspěšná těla odpovědí.

Společný kontrakt

Každá cesta začíná nasazeným originem app-api. Prostor se odvozuje výhradně z ověřeného tokenu; klienti nesmějí posílat cpoId. Všechny dokumentované hodnoty cest zdrojů :...Id jsou kladná celá desetinná čísla. Každý požadavek potřebuje právě jednu:

Authorization: Bearer <workspace-access-token>

Požadavky uvedené s tělem JSON vyžadují Content-Type: application/json. Všechny změny vyžadují Idempotency-Key (POST, PUT, PATCH a DELETE), včetně POST /v2/admin/reports/send; pokud řádek neuvádí jinak, typ obsahu úspěšné odpovědi je application/json, data JSON jsou řetězce RFC 3339 a čísla jsou čísla JSON.

Každý požadavek může obsahovat X-Request-Id a X-Error-Format: envelope; viz Kontrakt odpovědí a chyb. Tyto hlavičky nemění schémata úspěchu.

Použitá notace:

  • none znamená žádné tělo požadavku. DELETE, které dokumentuje tělo JSON, toto tělo stále vyžaduje.
  • ? označuje volitelnou vlastnost nebo parametr dotazu.
  • T | null znamená, že vlastnost je přítomna a může být null.
  • 204 empty znamená žádné tělo odpovědi.
  • CursorPage<T> znamená { items: T[], nextCursor: number|string|null }, kromě případů, kdy řádek výslovně uvádí objekt page nebo pagination.
  • Všechny nenalezené vnořené zdroje, i ID jiného prostoru, používají 404 { "error": "Workspace resource not found", "code": "RESOURCE_NOT_FOUND" }, pokud funkce neuvádí konkrétnější konflikt.

Sdílená schémata požadavků

Vstupy pracovních prostorů a lokalit

WorkspacePatch = {
  name?: string(1..100), email?: email|null, website?: string|null,
  addressLine1?: string|null, addressLine2?: string|null,
  postalCode?: string|null, city?: string|null, state?: string|null,
  countryId?: positive integer
} // at least one property

SiteInput = {
  name: string(1..255), description?: string|null = null,
  addressLine1?: string|null = null, addressLine2?: string|null = null,
  postalCode?: string|null = null, city?: string|null = null, state?: string|null = null,
  countryId: positive integer, timezoneId: positive integer,
  latitude?: number[-90,90]|null = null, longitude?: number[-180,180]|null = null
}

Vstup řízení výkonu

PowerConfigurationInput = { pools: PowerPoolInput[0..200] }
PowerPoolInput = {
  id?: positive integer|null, name?: string(0..255),
  limit: integer[0,100000000], meterSources?: ExternalMeterInput[0..16],
  children?: (PowerPoolInput | ChargerPoolChild)[0..1000]
}
ChargerPoolChild = { chargepointId: positive integer, priority?: integer[-1000000,1000000] }
ExternalMeterInput = {
  id?: positive integer|null, sourceId?: positive integer|null,
  provider?: "perific", name?: string(0..255), externalId: string(1..80),
  measurementMode?: "available_headroom"|"external_non_ev_load_only"|"total_site_load_including_ev",
  valueMode?: "perific_relative"|"perific_direct"|"perific_meter",
  reserveA?: integer[0,100000], offlineSafeA?: integer[0,100000],
  ttlSeconds?: integer[30,86400], enabled?: boolean
}

Vstupy nabíječky

ChargerCreate = { name: string(1..40), identifier: string(1..40), password?: string(0..40) = "", siteId: positive integer }
ChargerPatch = {
  name?: string(1..40), siteId?: positive integer, invertedRfid?: boolean,
  smartMode?: integer[0,3], automationDisabled?: boolean
} // at least one
ConnectorPatch = {
  connectorFormatId: positive integer, connectorTypeId: positive integer,
  powerTypeId: positive integer, maxVoltage: integer[1,10000],
  maxAmperage: integer[1,10000], maxElectricPower: integer[1,100000000]
}

Vstupy přehledů

ReportFilters = {
  from?: RFC3339, to?: RFC3339, siteId?: positive integer,
  chargerId?: positive integer, userId?: positive integer,
  anonymous?: true|false|1|0, active?: true|false|1|0
}
ReportScheduleInput = {
  enabled: boolean, recipientEmail: email(max 255; may be empty only when disabled), format: "csv"|"pdf",
  sendDay: integer[1,28], sendTime: UTC "HH:mm"
}

Rozsahy přehledů musí splňovat from < to a nesmějí přesáhnout 90 dní. Při vynechání se použije posledních 90 dní. userId a anonymous=true se vzájemně vylučují. Plánované exporty doženou zmeškanou minutu UTC a používají omezené opakování (prodleva 5/10 minut, 30minutový pronájem zastaralého zpracování, tři pokusy).

Vstupy tarifů

TariffInput = {
  name: string(1..64),
  exactly one of currencyId: positive integer, currencyCode: 3 letters, currency: 3 letters,
  biddingZoneId?: positive integer|null, tax?: finite number
}
TariffComponentInput = {
  typeId: positive integer, seasonId: positive integer, priority?: finite number,
  price: finite number, validFromMonth?: finite number, validToMonth?: finite number,
  validFromWeekDay?: finite number, validToWeekDay?: finite number,
  validFromHour?: finite number, validToHour?: finite number
}
TariffAssignmentCreateInput = { tariffId: positive integer, connectorId?: nonnegative integer }
TariffAssignmentUpdateInput = { tariffId: positive integer, connectorId: positive integer }

Vstupy nabíjecích profilů

ChargingProfileInput = {
  label: string(1..40), locationId: positive integer, stackLevel: nonnegative number,
  purposeId: positive integer, kindId: positive integer,
  recurrencyKindId?: positive integer|null, validFrom?: RFC3339|null,
  validTo?: RFC3339|null, startSchedule?: RFC3339|null,
  rateUnitId: positive integer, minChargingRate?: nonnegative number|null
}
ChargingProfileCreate = ChargingProfileInput & { schedule?: SchedulePeriod[0..256] }
SchedulePeriod = { startPeriod: nonnegative number, limit: nonnegative number, numberOfPhases?: positive integer|null }
ChargingScheduleInput = { rateUnitId: positive integer, periods: SchedulePeriod[1..256] }
ProfileAssignmentInput = { profileId: positive integer, connectorId?: nonnegative integer }

Vstupy uživatelů

UserCreate = { email: email(max 255), name: string(1..255) }
InvitationInput = {
  email: email, name?: string|null, rfid?: string|null,
  allChargers?: boolean, chargerIds?: unique positive integer[0..500]
} // chargerIds must be non-empty unless allChargers=true
AccessInput = { allChargers?: boolean, chargerIds?: unique positive integer[0..500] }
LimitCreate = { limitTypeId: positive integer, energyValue?: nonnegative integer = 0, timeValue?: nonnegative integer = 0 }
LimitPatch = { limitTypeId?: positive integer, energyValue?: nonnegative integer, timeValue?: nonnegative integer }

Při vytváření limitu musí být alespoň jedno z energyValue nebo timeValue větší než nula. E-maily se oříznou a převedou na malá písmena. RFID UID se přijímají jen při zápisu a při čtení jsou maskována.

Souhrn DTO odpovědí

Tabulky endpointů uvádějí všechny obálky odpovědí nejvyšší úrovně. Toto jsou hlavní opakovaně použitelné DTO uvnitř těchto obálek:

DTOPole
Workspaceid, name, email, website, address { line1, line2, postalCode, city, state, countryId, countryCode, countryName }, createdAt, updatedAt
Siteid, name, description, address, timezone { id, name }, latitude, longitude, chargerCount; detail přidává normalizované chargers a stav konektorů
GeocodeCandidateplaceId, displayName, latitude, longitude; přihlašovací údaje poskytovatele ani jeho specifická metadata se nikdy nevracejí
MetricsWindowfrom, to, limity/počty relací a případně totalsCapped
Chargerid, name, identifier, cpoId, site, normalizované status, isPublic, příznaky RFID/Smart/automatizace, provisioned, connection, evses, connectors, createdAt, updatedAt; detail přidává skryté configuration, firmware a počty
ConnectorportId, connectorId, ID číselníků konektorů, maxVoltage, maxAmperage, maxElectricPower
ReportSessionid, nabíječka/lokalita, ID portu a konektoru, minimalizovaný uživatel, active, energyWh, začátek/konec/trvání a čisté ceny/daň/celkové ceny podle měny
ReportScheduleid, workspaceId, enabled, recipientEmail, format, UTC sendDay/sendTime, vytvoření/aktualizace a bezpečná metadata posledního doručení včetně počtu pokusů
Tariffid, cpoId, name, objekty typu/lokality/měny/nabídkové zóny, tax, fallbackPrice, účinné price, components, assignmentCount
ChargingProfileid, cpoId, label, description, stackLevel, objekty umístění/účelu/druhu/opakování/jednotky sazby, platnost, rozvrh, assignmentCount, časová razítka
Userid, membershipId, name, email, maskované rfids, access nabíječky, limitCount; detail přidává phone, createdAt a limits. Autorizační údaje OCPP jako contractId se nikdy nevracejí.
RFIDid, maskedUid, name, type, valid; nezpracované UID se nikdy nevrací
AccessallChargers, seřazené chargerIds a items obsahující metadata oprávnění/nabíječky/lokality/vypršení
Limitid, limitTypeId, label, energyValue, timeValue
LocalUserDTO seznamu: id, customerId, name, email, expiresAt, systemManaged. Změny místních uživatelů používají odlišné tvary LocalUserMutation/LocalUserUpdate v Schématech a příkladech.

Referenční objekty vracejí seznamové a detailní routy, aby klienti našli platná ID. Nová neznámá pole berte jako dopředně kompatibilní a větvěte jen podle dokumentovaných stabilních polí a kódů.

Endpointy pracovních prostorů

Metoda a cestaRozsahPožadavekÚspěšná odpověď
GET /v2/adminworkspaces:readTělo: žádné200 { workspace: Workspace }
PATCH /v2/adminworkspaces:updateTělo: WorkspacePatch200 { workspace: Workspace }
GET /v2/admin/dashboardworkspaces:read + reports:readTělo/dotaz: žádné200 { window, stats { chargerCount, onlineChargerCount, siteCount, userCount }, sessions: DashboardSession[], analytics }; relace jsou omezeny na 1 000 za 90 dní

Endpointy lokalit a řízení výkonu

Metoda a cestaRozsahPožadavekÚspěšná odpověď
GET /v2/admin/sitessites:readTělo/dotaz: žádné200 { items: Site[], metricsWindow: MetricsWindow, lookups { countries, timezones } }
GET /v2/admin/sites/geocodesites:readDotaz: volitelné street (max. 160), city, state, country (každé max. 100), countryCode (max. 2); volitelná hlavička Accept-Language; ulice a město/stát musí dohromady obsahovat alespoň dva znaky200 { results: GeocodeCandidate[] }; shodná probíhající hledání se slučují a práce poskytovatele používá omezenou sériovou frontu a omezenou mezipaměť na serveru; neplatná hledání vracejí 400 INVALID_GEOCODE_QUERY, zaplnění fronty 429 GEOCODING_BUSY s Retry-After a selhání poskytovatele 502 GEOCODING_UNAVAILABLE
POST /v2/admin/sitessites:createTělo: SiteInput201 { site: Site }
GET /v2/admin/sites/:siteIdsites:read + reports:readTělo/dotaz: žádné200 { site: SiteDetail, recentSessions: SiteSession[], totals, metricsWindow }
PATCH /v2/admin/sites/:siteIdsites:updateTělo: úplné SiteInput200 { site: Site }
DELETE /v2/admin/sites/:siteIdsites:deleteTělo: žádné204 empty; neprázdná lokalita vrací 409 SITE_NOT_EMPTY
GET /v2/admin/sites/:siteId/power-managementsites:power-managementTělo/dotaz: žádné200 { configuration: PowerConfiguration } obsahující vlastněnou lokalitu, nabíječky/konektory, skupiny, zdroje měření, přiřazení a stav kompatibility
PUT /v2/admin/sites/:siteId/power-managementsites:power-managementTělo: PowerConfigurationInput200 { configuration: PowerConfiguration }; odmítnutí OCPP, časový limit nebo souběžná změna vrací 409 POWER_MANAGEMENT_CONFLICT bez použití náhrady

Endpointy nabíječek

Metoda a cestaRozsahPožadavekÚspěšná odpověď
GET /v2/admin/chargerschargers:readTělo/dotaz: žádné200 { items: Charger[], metricsWindow: MetricsWindow, connectorLookups { formats, types, powerTypes } }
POST /v2/admin/chargerschargers:createTělo: ChargerCreate; identifikátor se převede na velká písmena201 { charger: Charger }; heslo se nikdy nevrací
GET /v2/admin/chargers/:chargerIdchargers:readTělo/dotaz: žádné200 { charger: ChargerDetail }
PATCH /v2/admin/chargers/:chargerIdchargers:updateTělo: ChargerPatch200 { charger: ChargerDetail }
DELETE /v2/admin/chargers/:chargerIdchargers:deleteTělo: žádné204 empty
PATCH /v2/admin/chargers/:chargerId/credentialschargers:credentialsTělo: { password: string(0..40) }200 { success: true }
PATCH /v2/admin/chargers/:chargerId/connectors/:portIdchargers:connector-settingsTělo: ConnectorPatch200 { connector: Connector }
PATCH /v2/admin/chargers/:chargerId/public-listingchargers:publicTělo: { isPublic: boolean }200 { isPublic: boolean }; nesplněná připravenost vrací 409 CHARGER_CONFLICT
GET /v2/admin/chargers/:chargerId/public-readinesschargers:readTělo/dotaz: žádné200 { readiness: { ready, missingRequirements, connectorIds, missingTariffConnectorIds, ...commercialState } }
GET /v2/admin/chargers/:chargerId/logschargers:readDotaz: cursor?, limit?=50 (1..200), from?, to?, action?, direction?, levelId?200 { items: RedactedOcppLog[], nextCursor: number or null }
GET /v2/admin/chargers/:chargerId/sessionschargers:read + reports:readDotaz: page?=1, limit?=25 (1..100), from?, to?, customerId?: positive integer or "unknown"200 { items: ChargerSession[], pagination { page, limit, total, totalPages }, filters { customers }, totals, totalsCapped }
GET /v2/admin/chargers/:chargerId/qrchargers:readDotaz: connector?: integer[0,255]200 image/png binární, 300 px, Content-Disposition: inline, Cache-Control: no-store
GET /v2/admin/chargers/:chargerId/composite-scheduleschargers:readDotaz: cursor?, limit?=20 (1..50), connectorId?200 { items: CompositeSchedule[], nextCursor: number or null }
GET /v2/admin/chargers/:chargerId/configurationchargers:readTělo/dotaz: žádné200 { items: ChargerConfiguration[] }; hodnoty podobné tajným údajům jsou [REDACTED]
PATCH /v2/admin/chargers/:chargerId/configurationchargers:configurationTělo: { key: string(1..50), value: string(0..500) }200 { status: string }, kde stav je výsledek nabíječky/OCPP
POST /v2/admin/chargers/:chargerId/configuration/reloadchargers:configurationTělo: žádné200 { status: string }
GET /v2/admin/chargers/:chargerId/firmwarechargers:readTělo/dotaz: žádné200 { firmware: { status, notifiedAt, currentVersion, bootNotifiedAt } }
POST /v2/admin/chargers/:chargerId/firmwarechargers:firmwareTělo: { url: HTTP-or-HTTPS URL, max 2048 characters }202 { status: string }
POST /v2/admin/chargers/:chargerId/commands/resetchargers:commandsTělo: { resetType: "Soft" or "Hard" }200 { status: string }
POST /v2/admin/chargers/:chargerId/commands/availabilitychargers:commandsTělo: { availabilityType: "Operative" or "Inoperative" }200 { status: string }
POST /v2/admin/chargers/:chargerId/commands/triggerchargers:commandsTělo: { messageType: "BootNotification", "Heartbeat", "StatusNotification", or "MeterValues" }200 { status: string, connectorResults: { connectorId, status }[] }
POST /v2/admin/chargers/:chargerId/commands/unlockchargers:commandsTělo: { connectorId: positive integer }200 { status: string }
POST /v2/admin/chargers/:chargerId/commands/composite-schedulechargers:commandsTělo: { connectorId: nonnegative integer, durationSeconds?: integer[60,604800], chargingRateUnit?: "W" or "A" }200 { status: string, connectorId: number, compositeSchedule: CompositeSchedule or null }

Endpointy přehledů

Metoda a cestaRozsahPožadavekÚspěšná odpověď
GET /v2/admin/reports/datareports:readDotaz: ReportFilters, neprůhledné cursor?, limit?=50 (1..100)200 { items: ReportSession[], pageTotals, page { limit, nextCursor }, range { from, to, toExclusive: true } }
GET /v2/admin/reports/schedulereports:readTělo/dotaz: žádné200 { schedule: ReportSchedule or null }
PUT /v2/admin/reports/schedulereports:schedulesTělo: striktní ReportScheduleInput200 { schedule: ReportSchedule }
POST /v2/admin/reports/sendreports:sendTělo: žádné; vyžadována hlavička Idempotency-Key200 { sent: true, format: "csv" or "pdf", rowCount: number, range { from, to } }; žádný uložený rozvrh vrací 409 REPORT_SCHEDULE_REQUIRED
GET /v2/admin/reports/measurementsreports:readDotaz: povinné transactionLogId, neprůhledné cursor?, limit?=500 (1..1000)200 { transactionLogId, measurements: { name, unit, lines[] }[], page { limit, nextCursor, sampleValuesTruncated, sampleLimitPerMeterValue: 64 } }
GET /v2/admin/reports/exportreports:exportDotaz: ReportFilters, format?="csv" or "pdf"200 binární CSV/PDF s názvem přílohy, Cache-Control: private, no-store, X-Content-Type-Options: nosniff; více než 2 000 řádků vrací 422 REPORT_EXPORT_ROW_LIMIT

Endpointy tarifů

Metoda a cestaRozsahPožadavekÚspěšná odpověď
GET /v2/admin/tariffstariffs:readTělo/dotaz: žádné200 { items: Tariff[], lookups { currencies, biddingZones, currencyRates, componentTypes, seasons, tariffTypes } }
POST /v2/admin/tariffstariffs:createTělo: TariffInput201 { tariff: Tariff }
GET /v2/admin/tariffs/:tariffIdtariffs:readTělo/dotaz: žádné200 { tariff: Tariff, lookups }
PATCH /v2/admin/tariffs/:tariffIdtariffs:updateTělo: úplné TariffInput200 { tariff: Tariff }
PUT /v2/admin/tariffs/:tariffId/componentstariffs:componentsTělo: { components: TariffComponentInput[0..256] }200 { tariff: Tariff, components: TariffComponent[] }
DELETE /v2/admin/tariffs/:tariffIdtariffs:deleteTělo: žádné204 empty; odkazy na záznamy nabíjení vracejí 409 TARIFF_CONFLICT
GET /v2/admin/tariffs/:tariffId/market-pricestariffs:readDotaz: povinné startsAt, nezáporné časové razítko Unix200 { items: { id, value, currencyId, startsAt, endsAt, startsAtIso, endsAtIso, intervalMinutes }[], truncated: boolean }; nejvýše 10 000 řádků
GET /v2/admin/chargers/:chargerId/tariff-assignmentschargers:tariff-assignments + tariffs:readTělo/dotaz: žádné200 { items: TariffAssignment[], tariffs: Tariff[] }
POST /v2/admin/chargers/:chargerId/tariff-assignmentschargers:tariff-assignments + tariffs:assignTělo: TariffAssignmentCreateInput; bez connectorId nebo connectorId=0 platí pro všechny konektory201 { assignments: TariffAssignment[] }
PATCH /v2/admin/chargers/:chargerId/tariff-assignments/:assignmentIdchargers:tariff-assignments + tariffs:assignTělo: TariffAssignmentUpdateInput; konektor je povinný a nesmí být 0200 { assignment: TariffAssignment }
DELETE /v2/admin/chargers/:chargerId/tariff-assignments/:assignmentIdchargers:tariff-assignments + tariffs:assignTělo: žádné204 empty

TariffAssignment obsahuje id, chargerId, connectorId, bezpečný souhrn tarifu/měny, createdAt a updatedAt.

Endpointy nabíjecích profilů

Metoda a cestaRozsahPožadavekÚspěšná odpověď
GET /v2/admin/charging-profileschargingProfiles:readTělo/dotaz: žádné200 { items: ChargingProfile[], lookups { locations, purposes, kinds, recurrencyKinds, rateUnits, allowedRateUnits } }
POST /v2/admin/charging-profileschargingProfiles:createTělo: ChargingProfileCreate201 { profile: ChargingProfile }
GET /v2/admin/charging-profiles/:profileIdchargingProfiles:readTělo/dotaz: žádné200 { profile: ChargingProfile, lookups, isEditBlocked: boolean, usage { simpleChargingSchedule, smartSchedule, chargePoolChargepoint, isUsed } }
PATCH /v2/admin/charging-profiles/:profileIdchargingProfiles:updateTělo: úplné ChargingProfileInput200 { profile: ChargingProfile, ocppSync: OcppCommandResult[] }
PUT /v2/admin/charging-profiles/:profileId/schedulechargingProfiles:updateTělo: ChargingScheduleInput200 { profile: ChargingProfile, schedule: SchedulePeriod[], ocppSync: OcppCommandResult[] }
DELETE /v2/admin/charging-profiles/:profileIdchargingProfiles:deleteTělo: žádné204 empty pouze poté, co všechny přiřazené nabíječky přijmou vymazání a stav se znovu ověří; jinak 409 a profil zůstává
GET /v2/admin/chargers/:chargerId/profile-assignmentschargers:profile-assignments + chargingProfiles:readTělo/dotaz: žádné200 { items: ProfileAssignment[], profiles: ChargingProfile[] }
POST /v2/admin/chargers/:chargerId/profile-assignmentschargers:profile-assignments + chargingProfiles:assignTělo: ProfileAssignmentInput201 { assignment: ProfileAssignment, ocpp: OcppCommandResult }
PATCH /v2/admin/chargers/:chargerId/profile-assignments/:assignmentIdchargers:profile-assignments + chargingProfiles:assignTělo: ProfileAssignmentInput200 { assignment: ProfileAssignment, ocpp: OcppCommandResult }
DELETE /v2/admin/chargers/:chargerId/profile-assignments/:assignmentIdchargers:profile-assignments + chargingProfiles:assignTělo: žádné204 empty po synchronizovaném vymazání

ProfileAssignment obsahuje ID přiřazení, ID nabíječky/konektoru a bezpečný souhrn profilu. Objekty výsledků OCPP zpřístupňují stabilní informace o požadavku/stavu a nikdy přihlašovací údaje.

Endpointy uživatelů, RFID, přístupu, limitů a místních uživatelů

Metoda a cestaRozsahPožadavekÚspěšná odpověď
GET /v2/admin/usersusers:readDotaz: cursor? odpovídající stavu (members: kladné číslo; invitations: ověřené neprůhledné i2.*; all: číselné pokračování starších členů nebo ověřené neprůhledné složené a2.*), limit?=50 (1..100), status?="all", "members", or "invitations"; volitelná hlavička X-Admin-User-Search (max. 100)200 { items: User[], invitations: Invitation[], chargers: ChargerSummary[], page { nextCursor, memberNextCursor, invitationNextCursor, limit } }; pozvánky se stránkují a načítají stejným normalizovaným e-mailovým výrazem, takže starší odlišná velikost písmen či mezery nemohou skrýt řádky; kurzory jsou vázány na pracovní prostor a filtr hledání, neobsahují čitelnou e-mailovou adresu a musí se vracet beze změny; kurzory all posouvají proudy členů a pozvánek nezávisle
POST /v2/admin/usersusers:createTělo: UserCreate; zákazník musí být registrovaný201 { user: User }; neznámý e-mail vrací tělo 404 RESOURCE_NOT_FOUND, které neprozrazuje existenci prostředků, a má používat pozvánky
POST /v2/admin/users/invitationsusers:invitations + users:access; také users:rfid, je-li předáno rfidTělo: InvitationInput200 or 201 { result }; výsledek připojení je { kind:"attached", user, accessChanged, rfidChanged }; čekající výsledek je { kind:"invited", email, name, maskedRfid, chargerIds, createdCount, emailSent, emailRetryReady, alreadyInvited }
POST /v2/admin/users/invitations/resendusers:invitationsTělo: { email: email }200 { result: { targetedChargers, emailSent, emailRetryReady } }; vynucuje se globální čekací doba příjemce
DELETE /v2/admin/users/invitationsusers:invitationsTělo: { email: email }204 empty
GET /v2/admin/users/:userIdusers:read + reports:readTělo/dotaz: žádné200 { user: UserDetail, sessions: UserSession[], totals { count, energyWh, durationSeconds }, window, limitTypes, chargers }; nejvýše 200 relací za 90 dní
PATCH /v2/admin/users/:userIdusers:updateTělo: { name: string(1..255) }200 { user: User }
DELETE /v2/admin/users/:userIdusers:deleteTělo: žádné204 empty
GET /v2/admin/users/:userId/vehiclesusers:readDotaz: číselné cursor?, limit?=50 (1..100)200 { items: Vehicle[], page { nextCursor, limit } }; DTO vozidla obsahuje bezpečná pole poskytovatele/stavu/modelu/telemetrie
GET /v2/admin/users/:userId/rfidsusers:readTělo/dotaz: žádné200 { items: RFID[] }; UID jsou maskována
POST /v2/admin/users/:userId/rfidsusers:rfidTělo: { uid: string(1..36), name?: string or null }201 { rfid: RFID }; nezpracované UID se nevrací
PATCH /v2/admin/users/:userId/rfids/:rfidIdusers:rfidTělo: { name: string or null }200 { rfid: RFID }
DELETE /v2/admin/users/:userId/rfids/:rfidIdusers:rfidTělo: žádné204 empty
GET /v2/admin/users/:userId/accessusers:readTělo/dotaz: žádné200 { access: Access }
PUT /v2/admin/users/:userId/accessusers:accessTělo: AccessInput200 { access: Access }
DELETE /v2/admin/users/:userId/access/:accessIdusers:accessTělo: žádné204 empty
GET /v2/admin/users/:userId/limitsusers:readTělo/dotaz: žádné200 { items: Limit[] }
POST /v2/admin/users/:userId/limitsusers:limitsTělo: LimitCreate201 { limit: Limit }
PATCH /v2/admin/users/:userId/limits/:limitIdusers:limitsTělo: LimitPatch, alespoň jedna vlastnost200 { limit: Limit }
DELETE /v2/admin/users/:userId/limits/:limitIdusers:limitsTělo: žádné204 empty
GET /v2/admin/chargers/:chargerId/local-userschargers:read + users:readTělo/dotaz: žádné200 { charger: ChargerSummary, items: LocalUser[], invitations: { email }[], availableMembers: [] }; API záměrně vynechává široký adresář dostupných členů portálu
POST /v2/admin/chargers/:chargerId/local-userschargers:local-users + users:accessTělo: { customerId: positive integer, expiresAt?: RFC3339 or null }201 { localUser: LocalUserMutation }
POST /v2/admin/chargers/:chargerId/local-users/invitationschargers:local-users + users:invitations + users:accessTělo: { email: email }200 or 201 { result }; existující zákazník: { invited:false, localUser: LocalUserMutation }; pozvánka: { invited:true, alreadyInvited, emailSent, emailRetryReady }
DELETE /v2/admin/chargers/:chargerId/local-users/invitationschargers:local-users + users:invitationsTělo: { email: email }204 empty
PATCH /v2/admin/chargers/:chargerId/local-users/:localUserIdchargers:local-users + users:accessTělo: { expiresAt: RFC3339 or null }200 { localUser: LocalUserUpdate }
DELETE /v2/admin/chargers/:chargerId/local-users/:localUserIdchargers:local-users + users:accessTělo: žádné204 empty

Systémový uživatel Tagless je před těmito operacemi chráněn. Selhání e-mailových pozvánek vrací bezpečný stav doručení bez odhalení údajů SMTP; volající může opakovat pokus, když je emailRetryReady true.

Binární odpovědi

Dvě skupiny endpointů při úspěchu nevracejí JSON:

EndpointTyp obsahuDůležité hlavičky
QR nabíječkyimage/pngCache-Control: no-store, Content-Disposition: inline, X-Content-Type-Options: nosniff
Export přehledutext/csv; charset=utf-8 nebo application/pdfCache-Control: private, no-store, Content-Disposition: attachment, X-Content-Type-Options: nosniff

Chyby binárních endpointů jsou stále JSON.