Antworten und Fehler

Antwort- und Fehlervertrag der Admin-API

Diese Datei vervollständigt den Antwortvertrag jedes Endpunkts unter Endpunktreferenz. Die Endpunktzeile beschreibt den Erfolgs-Body, die folgenden Tabellen alle gemeinsamen und spezifischen Fehler-Bodys. Standardmäßig gibt es mehrere kompatible Fehlerformen; Aufrufer können einen einheitlichen Umschlag wählen.

Optionaler strukturierter Fehlerumschlag

Senden Sie diesen Anfrageheader an einen beliebigen Endpunkt:

X-Error-Format: envelope

Der Vergleich wird getrimmt und ignoriert Groß-/Kleinschreibung. Bei genau diesem Wert wird jede JSON-Antwort mit Status ab 400 umgewandelt in:

ErrorEnvelope = {
  error: {
    code: string,
    message: string,
    details: Record<string, unknown>,
    requestId: string
  }
}

Beispiel für die Umwandlung eines Standard-Validierungs-Bodys:

{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "Invalid request",
    "details": {
      "fields": {
        "name": ["String must contain at least 1 character(s)"]
      }
    },
    "requestId": "integration-42"
  }
}

Die Umrechnungsregeln sind exakt:

  • validationErrors wird zu details.fields und code zu VALIDATION_FAILED, auch wenn der Standard-Body einen fachlichen Code hatte.
  • Ein standardmäßiges code auf oberster Ebene bleibt erhalten, wenn keine Validierungsfelder vorhanden sind.
  • Andere Eigenschaften oberster Ebene außer error, message, validationErrors und code werden nach details verschoben; beim Berichtsexport wird beispielsweise limit zu details.limit.
  • Ein error als Zeichenfolge auf oberster Ebene wird zu message. Fehlt es, wird der Ersatztext des Status verwendet.
  • Ersatzcodes sind AUTH_REQUIRED (401), PERMISSION_DENIED (403), RESOURCE_NOT_FOUND (404), CONFLICT (409), VALIDATION_FAILED (422 und andere nicht klassifizierte 4xx), RATE_LIMITED (429), EXTERNAL_PROVIDER_FAILED (502) und INTERNAL_ERROR (andere 5xx, einschließlich 503).
  • requestId ist der exakte Antwortheader X-Request-Id. Eine vom Aufrufer angegebene Anfrage-ID gilt nur, wenn sie nach Trimmen [A-Za-z0-9._:-]{1,128} entspricht; sonst erzeugt der Server eine UUID.

Die Umwandlung verändert weder Status noch andere Header. Sie gilt auch für idempotente Wiederholungen gemäß deren X-Error-Format-Anfrageheader. Binäre Erfolge bleiben binär, ihre JSON-Fehler erhalten den Umschlag. Die übrigen Tabellen zeigen Standard-Bodys; die Regeln oben ergeben für jede Zeile die andere mögliche Antwortform.

Schreibweise von Antworten

ValidationError = {
  validationErrors: Record<string, string[]>,
  code?: string
}

CodedError = {
  error: string,
  code: string,
  // a route may add fields explicitly listed below
}

PlainError = { error: string }

error und der Validierungsmeldungstext dienen der Beschreibung, nicht als stabile programmatische Unterscheidungsmerkmale. Verzweigen Sie nach code, falls vorhanden. Anfragevalidierung liefert 422 ValidationError; Objektvalidierung kann ohne bestimmtes Feld { "validationErrors": {} } erzeugen. Ungültiges JSON und unerwartete Fehler liefern das globale 500 PlainError unten.

Alle JSON-Beispiele zeigen die exakte Body-Struktur. Als <message> angezeigter Text ist die zurückgegebene Validierungs- oder Vorgangsmeldung und eine JSON-Zeichenfolge, kein wörtlicher Wert in spitzen Klammern.

Reihenfolge der Anfrageverarbeitung

Anfragen werden in dieser Reihenfolge verarbeitet:

  1. Workspace-Token-Konfiguration und Authentifizierung;
  2. Host-Richtlinie und Token-/Workspace-Anfragelimits;
  3. Filterung aktueller Funktionsberechtigungen;
  4. bei jeder Änderung Idempotenzprüfung/-reservierung;
  5. Endpunkt-Scope-Prüfungen, Anfragevalidierung und angeforderter Vorgang.

Daher muss auch eine Änderung mit gültigem, aber unzureichend berechtigtem Token Idempotency-Key senden. Eine abgeschlossene Änderungsantwort mit 403, 404, 409 oder 422 kann für denselben Schlüssel und dieselbe Anfrage wiederholt werden.

Antworten zu Authentifizierung, Richtlinien und Anfragelimits

Diese Antworten können an jedem registrierten /v2/admin-Endpunkt vor der endpunktspezifischen Verarbeitung auftreten.

StatusWannExakter BodyRelevante Header
401Fehlendes, doppeltes, kommaverknüpftes, nicht als Bearer angegebenes, fehlerhaftes, unbekanntes, abgelaufenes, widerrufenes oder anderweitig ungültiges Workspace-Token{ "error": "Unauthorized", "code": "INVALID_WORKSPACE_TOKEN" }WWW-Authenticate: Bearer, Cache-Control: no-store
404Das Token ist gültig, aber der Workspace-Host hat kein adminApiEnabled{ "error": "Not Found" }Cache-Control: no-store
429Anfragekontingent des Tokens oder Workspaces ist erschöpft{ "error": "Too many attempts. Please try again later." }Retry-After: <seconds>
503Workspace-Token-Authentifizierung vorübergehend nicht verfügbar{ "error": "Admin API workspace-token configuration is unavailable", "code": "WORKSPACE_API_CONFIG_UNAVAILABLE" }—
503Abfrage der Host-Richtlinie oder Prüfung aktueller Berechtigungen schlägt fehl{ "error": "Workspace authorization is temporarily unavailable", "code": "WORKSPACE_AUTHORIZATION_UNAVAILABLE" }—

API-Zugriff ist in jedem Paket enthalten. Wird die Host-Einstellung adminApiEnabled deaktiviert, liefert der Workspace 404; entfällt eine zusätzliche Funktionsberechtigung, werden nur die betroffenen Scopes entfernt. Die daraus folgende Scope-Verweigerung verwendet die folgende Antwort und keinen Token-Aktualisierungsablauf.

Fehler bei Scope, Idempotenz, Parsing, Besitzrechten und unerwarteten Zuständen

Gilt fürStatusExakter BodyHeader/Hinweise
Jede Route nach der Authentifizierung403{ "error": "Insufficient workspace-token scope", "code": "INSUFFICIENT_SCOPE" }Wird geliefert, wenn ein erforderlicher Scope fehlt.
Jede Änderung400{ "error": "Idempotency-Key is required for this operation", "code": "IDEMPOTENCY_KEY_REQUIRED" }Kein Schlüssel angegeben.
Jede Änderung400{ "error": "Exactly one Idempotency-Key is required", "code": "INVALID_IDEMPOTENCY_KEY" }Doppelter oder mit Komma zusammengefasster Header.
Jede Änderung400{ "error": "Idempotency-Key must contain 1 to 255 visible characters", "code": "INVALID_IDEMPOTENCY_KEY" }Leer, zu lang oder mit Steuerzeichen.
Jede Änderung409{ "error": "Idempotency-Key was already used with a different request", "code": "IDEMPOTENCY_CONFLICT" }Gleiches Token/Methode/Pfad/Schlüssel, andere URL oder anderer Body.
Jede Änderung409{ "error": "Request is already processing", "code": "IDEMPOTENT_REQUEST_PROCESSING" }Retry-After: 5.
Jede Änderung409{ "error": "Previous request outcome is unknown; verify its effects before attempting the operation again", "code": "IDEMPOTENCY_OUTCOME_UNKNOWN" }Vorige Verarbeitungssperre abgelaufen, Verbindung geschlossen oder Anfrage mit 5xx beendet.
Jede Änderung503{ "error": "Idempotency storage unavailable", "code": "IDEMPOTENCY_UNAVAILABLE" }Die API kann den Idempotenzdatensatz nicht prüfen oder speichern.
Jeder Endpunkt mit ungültigem Query-, Body- oder Pfadschema422{ "validationErrors": { "<field>": ["<message>"] } }Mehrere Felder oder Meldungen können vorkommen. Aufrufer dürfen cpoId nicht angeben; der Workspace stammt immer aus dem Token.
Jede fehlende verschachtelte Workspace-Ressource oder ID eines anderen Workspaces404{ "error": "Workspace resource not found", "code": "RESOURCE_NOT_FOUND" }Wird durchgehend verwendet, sofern eine Tabelle unten nichts anderes angibt.
Jeder Endpunkt mit unerwartetem Fehler500{ "error": "Something went wrong" }Bei Änderungen liefert ein späterer Versuch mit demselben Schlüssel 409 IDEMPOTENCY_OUTCOME_UNKNOWN.

Ressourcenpfad-IDs müssen positiv sein. Ein nicht positives oder nicht numerisches :siteId, :chargerId, :portId, :tariffId, :profileId, :assignmentId, :userId, :rfidId, :accessId, :limitId oder :localUserId liefert 422 ValidationError, nicht 400.

Standort- und Leistungsmanagement-Fehler

EndpunkteStatusExakter Body
Standort erstellen/aktualisieren; Workspace-Feldvalidierung422{ "validationErrors": { "<field>": ["<message>"] } }
DELETE /v2/admin/sites/:siteId, wenn der Standort Abhängigkeiten hat409{ "error": "<message>", "code": "SITE_NOT_EMPTY" }
GET /v2/admin/sites/geocode ungültige normalisierte Suche400{ "error": "<message>", "code": "INVALID_GEOCODE_QUERY" }
Dasselbe, begrenzte Anbieterwarteschlange voll429{ "error": "<message>", "code": "GEOCODING_BUSY" }; enthält Retry-After, falls vom Geocoder geliefert
Dasselbe, Anbieterzeitüberschreitung/-fehler oder unerwarteter Geocoder-Fehler502{ "error": "<message>", "code": "GEOCODING_UNAVAILABLE" }; ein unerwarteter Fehler verwendet Address search is temporarily unavailable
PUT /v2/admin/sites/:siteId/power-management ungültige Topologie/fachliche Konfiguration422{ "error": "<message>", "code": "INVALID_POWER_MANAGEMENT_CONFIGURATION" }
Dasselbe, OCPP-Ablehnung/Zeitüberschreitung, Konkurrenz- oder Abgleichkonflikt409{ "error": "<message>", "code": "POWER_MANAGEMENT_CONFLICT" }

Ladegerätefehler

mapChargerErrors() wird für Geräteerstellung/-änderung, Zugangsdaten, Anschlüsse, öffentliche Listung, QR-Auflösung, Konfigurationsänderung/-neuladen, Firmwarestart, alle vier Basisbefehle und kombinierte Zeitplananfragen verwendet.

EndpunkteStatusExakter Body
Jeder oben genannte Vorgang mit fachlichem Validierungsfehler422{ "validationErrors": { "<field>": ["<message>"] } }
Jeder oben genannte Vorgang mit Konflikt bei Status, Eindeutigkeit, Offline/OCPP, Abrechnung, Tagless, Anschluss oder Betriebsbereitschaft409{ "error": "<message>", "code": "CHARGER_CONFLICT" }
GET /chargers/:chargerId/sessions, ungültiger standardmäßiger/ausdrücklicher Zeitraum422{ "validationErrors": { "from": ["from must be before or equal to to"] } } oder { "validationErrors": { "from": ["Session range cannot exceed 90 days"] } }

Reine Lesevorgänge liefern nur gemeinsame 401/403/404/429/500/503-Antworten sowie 422-Validierung für Query und Pfad. Die Gerätelöschung kann das gemeinsame 500 PlainError liefern, falls sie ohne spezifischere Fehlerantwort scheitert.

Berichtsfehler

EndpunkteStatusExakter Body
Daten-/Exportzeitraum mit from >= to422{ "validationErrors": { "range": ["from must be earlier than to"] } }
Daten-/Exportzeitraum über 90 Tage422{ "validationErrors": { "range": ["Report ranges cannot exceed 90 days"] } }
Ungültiger opaker Cursor für Daten/Messungen422{ "validationErrors": { "cursor": ["<message>"] } }
GET /reports/export, Ergebnis über 2.000 Zeilen422{ "error": "<message>", "code": "REPORT_EXPORT_ROW_LIMIT", "limit": 2000 }
POST /reports/send, kein gespeicherter Zeitplan409{ "error": "A workspace report schedule must be saved before sending", "code": "REPORT_SCHEDULE_REQUIRED" }
Dasselbe, Mailversand abgelehnt/fehlgeschlagen502{ "error": "Report delivery failed", "code": "REPORT_DELIVERY_FAILED" }
Eigene Ressource für Zeitplan/Messungen fehlt404gemeinsamer Body RESOURCE_NOT_FOUND

Ein erfolgreicher Export ist binär; alle Exportfehler bleiben JSON.

Tariffehler

EndpunkteStatusExakter Body
Fachliche Validierung für Erstellung/Aktualisierung/Komponenten/Marktpreise/Zuweisung422{ "validationErrors": { "<field>": ["<message>"] } }
Konflikt bei Status, Abhängigkeit oder Eindeutigkeit einer Tariflöschung oder -zuweisung409{ "error": "<message>", "code": "TARIFF_CONFLICT" }
Fehlender Tarif, Gebotszone, Ladegerät, Anschluss, Tarifzuweisung oder andere nicht zum Workspace gehörende Ressource404gemeinsamer Body RESOURCE_NOT_FOUND

Ladeprofilfehler

EndpunkteStatusExakter Body
Fachliche Validierung für Erstellung/Aktualisierung/Zeitplan/Zuweisung422{ "validationErrors": { "<field>": ["<message>"] } }
Das Profil wird von einer geschützten Verwendung referenziert409{ "error": "<message>", "code": "CHARGING_PROFILE_IN_USE" }
Konflikt bei OCPP-Synchronisierung, Zuweisung, Gleichzeitigkeit oder anderem Profilzustand409{ "error": "<message>", "code": "CHARGING_PROFILE_CONFLICT" }
Fehlendes Profil, Ladegerät, Anschluss, Zuweisung oder andere nicht zum Workspace gehörende Ressource404gemeinsamer Body RESOURCE_NOT_FOUND

Fachliche Benutzerfehler

Benutzer-Validierungsfehler mit Feldbezug verwenden ValidationError und code; andere Benutzerfehler CodedError. Fehlende Ressourcen verwenden immer die gemeinsame nicht auskunftgebende RESOURCE_NOT_FOUND-Antwort.

StatusCode(s)Body
400INVALID_USER_CURSOR{ "validationErrors": { "cursor": ["The user-list cursor is invalid for the selected status"] }, "code": "INVALID_USER_CURSOR" }
409USER_ALREADY_EXISTS, CUSTOMER_CONTRACT_MISSING, INVITATION_EMAIL_IN_USE, RFID_ALREADY_EXISTS, ACCESS_ALREADY_EXISTS, ACCESS_ALL_ALREADY_EXISTS, LIMIT_ALREADY_EXISTS, LOCAL_USER_ALREADY_EXISTS, PROTECTED_WORKSPACE_USER, TAGLESS_USER_PROTECTED, USER_RELATED_DATA{ "error": "<message>", "code": "<listed code>" }
422INVALID_EMAIL, INVALID_RFID, INVALID_LIMIT_TYPE, INVALID_LIMIT_VALUE{ "validationErrors": { "<field>": ["<message>"] }, "code": "<listed code>" }
422NO_CHARGERS_AVAILABLE{ "error": "No chargers are available", "code": "NO_CHARGERS_AVAILABLE" }
429INVITATION_RESEND_THROTTLED{ "error": "Invitation resend is temporarily unavailable", "code": "INVITATION_RESEND_THROTTLED" }; enthält Retry-After
503USER_CURSOR_UNAVAILABLE{ "error": "User pagination is temporarily unavailable", "code": "USER_CURSOR_UNAVAILABLE" }
404RESOURCE_NOT_FOUND{ "error": "Workspace resource not found", "code": "RESOURCE_NOT_FOUND" }

POST /users/invitations kann nach dem Body-Parsing auch das gemeinsame 403 INSUFFICIENT_SCOPE liefern, wenn users:access fehlt oder bei übergebenem RFID users:rfid fehlt. Lokale Benutzerendpunkte nennen alle erforderlichen Scopes unter Endpunktreferenz.

Die Benutzerfehlercodes gelten wie folgt:

EndpunktgruppeBenutzerbezogene Codes außer 404 zusätzlich zu gemeinsamen Antworten
GET /usersINVALID_USER_CURSOR (400), USER_CURSOR_UNAVAILABLE (503)
POST /usersUSER_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409)
PATCH /users/:userIdTAGLESS_USER_PROTECTED (409)
DELETE /users/:userIdTAGLESS_USER_PROTECTED, PROTECTED_WORKSPACE_USER, USER_RELATED_DATA (409)
Benutzerdetails, Fahrzeuge, RFID-/Zugriffs-/Grenzabfragenkein fachlicher Code außer 404
RFID anlegenCUSTOMER_CONTRACT_MISSING, RFID_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409); INVALID_RFID (422)
RFID aktualisieren/löschenTAGLESS_USER_PROTECTED (409)
Zugriff ersetzenTAGLESS_USER_PROTECTED (409); NO_CHARGERS_AVAILABLE (422)
Zugriff widerrufenTAGLESS_USER_PROTECTED (409)
Grenze erstellen/aktualisierenTAGLESS_USER_PROTECTED, LIMIT_ALREADY_EXISTS (409); INVALID_LIMIT_TYPE, INVALID_LIMIT_VALUE (422)
Grenze löschenTAGLESS_USER_PROTECTED (409)
Workspace-Einladung erstellenCUSTOMER_CONTRACT_MISSING, INVITATION_EMAIL_IN_USE, RFID_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409); INVALID_EMAIL/INVALID_RFID (422); INVITATION_RESEND_THROTTLED (429) bei Zustellwartezeit
Workspace-Einladung erneut sendenINVALID_EMAIL (422), INVITATION_RESEND_THROTTLED (429)
Workspace-Einladung widerrufenINVALID_EMAIL (422)
Lokalen Ladegerätebenutzer für bestehenden Kunden anlegenLOCAL_USER_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409)
Einladung eines lokalen LadegerätebenutzersLOCAL_USER_ALREADY_EXISTS, INVITATION_EMAIL_IN_USE, TAGLESS_USER_PROTECTED (409); INVALID_EMAIL (422); INVITATION_RESEND_THROTTLED (429) bei Zustellwartezeit
Lokale Benutzereinladung widerrufenINVALID_EMAIL (422)
Lokalen Benutzer aktualisieren/löschenTAGLESS_USER_PROTECTED (409)

Alle Ergebnisse zu Besitzrechten oder fehlenden Ressourcen in diesen Gruppen, auch eine nicht registrierte E-Mail bei POST /users, verwenden den gemeinsamen Body 404 RESOURCE_NOT_FOUND.

Antworten ohne Body und Wiederholungsantworten

Eine erfolgreiche 204-Antwort hat keinen Antwortinhalt. Dies gilt für alle dokumentierten Löschvorgänge, die 204 empty aufführen. Eine abgeschlossene idempotente Wiederholung setzt Idempotency-Replayed: true und verwendet den gespeicherten Status und Inhalt; bei 204 bleibt die HTTP-Antwort ohne Inhalt. Bei einem dokumentierten 204-Vorgang liefert die API niemals ein JSON-Erfolgsobjekt.