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:
validationErrorswird zudetails.fieldsundcodezuVALIDATION_FAILED, auch wenn der Standard-Body einen fachlichen Code hatte.- Ein standardmäßiges
codeauf oberster Ebene bleibt erhalten, wenn keine Validierungsfelder vorhanden sind. - Andere Eigenschaften oberster Ebene außer
error,message,validationErrorsundcodewerden nachdetailsverschoben; beim Berichtsexport wird beispielsweiselimitzudetails.limit. - Ein
errorals Zeichenfolge auf oberster Ebene wird zumessage. Fehlt es, wird der Ersatztext des Status verwendet. - Ersatzcodes sind
AUTH_REQUIRED(401),PERMISSION_DENIED(403),RESOURCE_NOT_FOUND(404),CONFLICT(409),VALIDATION_FAILED(422und andere nicht klassifizierte4xx),RATE_LIMITED(429),EXTERNAL_PROVIDER_FAILED(502) undINTERNAL_ERROR(andere5xx, einschließlich503). requestIdist der exakte AntwortheaderX-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:
- Workspace-Token-Konfiguration und Authentifizierung;
- Host-Richtlinie und Token-/Workspace-Anfragelimits;
- Filterung aktueller Funktionsberechtigungen;
- bei jeder Änderung Idempotenzprüfung/-reservierung;
- 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.
| Status | Wann | Exakter Body | Relevante Header |
|---|---|---|---|
401 | Fehlendes, 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 |
404 | Das Token ist gültig, aber der Workspace-Host hat kein adminApiEnabled | { "error": "Not Found" } | Cache-Control: no-store |
429 | Anfragekontingent des Tokens oder Workspaces ist erschöpft | { "error": "Too many attempts. Please try again later." } | Retry-After: <seconds> |
503 | Workspace-Token-Authentifizierung vorübergehend nicht verfügbar | { "error": "Admin API workspace-token configuration is unavailable", "code": "WORKSPACE_API_CONFIG_UNAVAILABLE" } | — |
503 | Abfrage 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ür | Status | Exakter Body | Header/Hinweise |
|---|---|---|---|
| Jede Route nach der Authentifizierung | 403 | { "error": "Insufficient workspace-token scope", "code": "INSUFFICIENT_SCOPE" } | Wird geliefert, wenn ein erforderlicher Scope fehlt. |
| Jede Änderung | 400 | { "error": "Idempotency-Key is required for this operation", "code": "IDEMPOTENCY_KEY_REQUIRED" } | Kein Schlüssel angegeben. |
| Jede Änderung | 400 | { "error": "Exactly one Idempotency-Key is required", "code": "INVALID_IDEMPOTENCY_KEY" } | Doppelter oder mit Komma zusammengefasster Header. |
| Jede Änderung | 400 | { "error": "Idempotency-Key must contain 1 to 255 visible characters", "code": "INVALID_IDEMPOTENCY_KEY" } | Leer, zu lang oder mit Steuerzeichen. |
| Jede Änderung | 409 | { "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 Änderung | 409 | { "error": "Request is already processing", "code": "IDEMPOTENT_REQUEST_PROCESSING" } | Retry-After: 5. |
| Jede Änderung | 409 | { "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 Änderung | 503 | { "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 Pfadschema | 422 | { "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 Workspaces | 404 | { "error": "Workspace resource not found", "code": "RESOURCE_NOT_FOUND" } | Wird durchgehend verwendet, sofern eine Tabelle unten nichts anderes angibt. |
| Jeder Endpunkt mit unerwartetem Fehler | 500 | { "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
| Endpunkte | Status | Exakter Body |
|---|---|---|
| Standort erstellen/aktualisieren; Workspace-Feldvalidierung | 422 | { "validationErrors": { "<field>": ["<message>"] } } |
DELETE /v2/admin/sites/:siteId, wenn der Standort Abhängigkeiten hat | 409 | { "error": "<message>", "code": "SITE_NOT_EMPTY" } |
GET /v2/admin/sites/geocode ungültige normalisierte Suche | 400 | { "error": "<message>", "code": "INVALID_GEOCODE_QUERY" } |
| Dasselbe, begrenzte Anbieterwarteschlange voll | 429 | { "error": "<message>", "code": "GEOCODING_BUSY" }; enthält Retry-After, falls vom Geocoder geliefert |
| Dasselbe, Anbieterzeitüberschreitung/-fehler oder unerwarteter Geocoder-Fehler | 502 | { "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 Konfiguration | 422 | { "error": "<message>", "code": "INVALID_POWER_MANAGEMENT_CONFIGURATION" } |
| Dasselbe, OCPP-Ablehnung/Zeitüberschreitung, Konkurrenz- oder Abgleichkonflikt | 409 | { "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.
| Endpunkte | Status | Exakter Body |
|---|---|---|
| Jeder oben genannte Vorgang mit fachlichem Validierungsfehler | 422 | { "validationErrors": { "<field>": ["<message>"] } } |
| Jeder oben genannte Vorgang mit Konflikt bei Status, Eindeutigkeit, Offline/OCPP, Abrechnung, Tagless, Anschluss oder Betriebsbereitschaft | 409 | { "error": "<message>", "code": "CHARGER_CONFLICT" } |
GET /chargers/:chargerId/sessions, ungültiger standardmäßiger/ausdrücklicher Zeitraum | 422 | { "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
| Endpunkte | Status | Exakter Body |
|---|---|---|
Daten-/Exportzeitraum mit from >= to | 422 | { "validationErrors": { "range": ["from must be earlier than to"] } } |
| Daten-/Exportzeitraum über 90 Tage | 422 | { "validationErrors": { "range": ["Report ranges cannot exceed 90 days"] } } |
| Ungültiger opaker Cursor für Daten/Messungen | 422 | { "validationErrors": { "cursor": ["<message>"] } } |
GET /reports/export, Ergebnis über 2.000 Zeilen | 422 | { "error": "<message>", "code": "REPORT_EXPORT_ROW_LIMIT", "limit": 2000 } |
POST /reports/send, kein gespeicherter Zeitplan | 409 | { "error": "A workspace report schedule must be saved before sending", "code": "REPORT_SCHEDULE_REQUIRED" } |
| Dasselbe, Mailversand abgelehnt/fehlgeschlagen | 502 | { "error": "Report delivery failed", "code": "REPORT_DELIVERY_FAILED" } |
| Eigene Ressource für Zeitplan/Messungen fehlt | 404 | gemeinsamer Body RESOURCE_NOT_FOUND |
Ein erfolgreicher Export ist binär; alle Exportfehler bleiben JSON.
Tariffehler
| Endpunkte | Status | Exakter Body |
|---|---|---|
| Fachliche Validierung für Erstellung/Aktualisierung/Komponenten/Marktpreise/Zuweisung | 422 | { "validationErrors": { "<field>": ["<message>"] } } |
| Konflikt bei Status, Abhängigkeit oder Eindeutigkeit einer Tariflöschung oder -zuweisung | 409 | { "error": "<message>", "code": "TARIFF_CONFLICT" } |
| Fehlender Tarif, Gebotszone, Ladegerät, Anschluss, Tarifzuweisung oder andere nicht zum Workspace gehörende Ressource | 404 | gemeinsamer Body RESOURCE_NOT_FOUND |
Ladeprofilfehler
| Endpunkte | Status | Exakter Body |
|---|---|---|
| Fachliche Validierung für Erstellung/Aktualisierung/Zeitplan/Zuweisung | 422 | { "validationErrors": { "<field>": ["<message>"] } } |
| Das Profil wird von einer geschützten Verwendung referenziert | 409 | { "error": "<message>", "code": "CHARGING_PROFILE_IN_USE" } |
| Konflikt bei OCPP-Synchronisierung, Zuweisung, Gleichzeitigkeit oder anderem Profilzustand | 409 | { "error": "<message>", "code": "CHARGING_PROFILE_CONFLICT" } |
| Fehlendes Profil, Ladegerät, Anschluss, Zuweisung oder andere nicht zum Workspace gehörende Ressource | 404 | gemeinsamer 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.
| Status | Code(s) | Body |
|---|---|---|
400 | INVALID_USER_CURSOR | { "validationErrors": { "cursor": ["The user-list cursor is invalid for the selected status"] }, "code": "INVALID_USER_CURSOR" } |
409 | USER_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>" } |
422 | INVALID_EMAIL, INVALID_RFID, INVALID_LIMIT_TYPE, INVALID_LIMIT_VALUE | { "validationErrors": { "<field>": ["<message>"] }, "code": "<listed code>" } |
422 | NO_CHARGERS_AVAILABLE | { "error": "No chargers are available", "code": "NO_CHARGERS_AVAILABLE" } |
429 | INVITATION_RESEND_THROTTLED | { "error": "Invitation resend is temporarily unavailable", "code": "INVITATION_RESEND_THROTTLED" }; enthält Retry-After |
503 | USER_CURSOR_UNAVAILABLE | { "error": "User pagination is temporarily unavailable", "code": "USER_CURSOR_UNAVAILABLE" } |
404 | RESOURCE_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:
| Endpunktgruppe | Benutzerbezogene Codes außer 404 zusätzlich zu gemeinsamen Antworten |
|---|---|
GET /users | INVALID_USER_CURSOR (400), USER_CURSOR_UNAVAILABLE (503) |
POST /users | USER_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409) |
PATCH /users/:userId | TAGLESS_USER_PROTECTED (409) |
DELETE /users/:userId | TAGLESS_USER_PROTECTED, PROTECTED_WORKSPACE_USER, USER_RELATED_DATA (409) |
| Benutzerdetails, Fahrzeuge, RFID-/Zugriffs-/Grenzabfragen | kein fachlicher Code außer 404 |
| RFID anlegen | CUSTOMER_CONTRACT_MISSING, RFID_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409); INVALID_RFID (422) |
| RFID aktualisieren/löschen | TAGLESS_USER_PROTECTED (409) |
| Zugriff ersetzen | TAGLESS_USER_PROTECTED (409); NO_CHARGERS_AVAILABLE (422) |
| Zugriff widerrufen | TAGLESS_USER_PROTECTED (409) |
| Grenze erstellen/aktualisieren | TAGLESS_USER_PROTECTED, LIMIT_ALREADY_EXISTS (409); INVALID_LIMIT_TYPE, INVALID_LIMIT_VALUE (422) |
| Grenze löschen | TAGLESS_USER_PROTECTED (409) |
| Workspace-Einladung erstellen | CUSTOMER_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 senden | INVALID_EMAIL (422), INVITATION_RESEND_THROTTLED (429) |
| Workspace-Einladung widerrufen | INVALID_EMAIL (422) |
| Lokalen Ladegerätebenutzer für bestehenden Kunden anlegen | LOCAL_USER_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409) |
| Einladung eines lokalen Ladegerätebenutzers | LOCAL_USER_ALREADY_EXISTS, INVITATION_EMAIL_IN_USE, TAGLESS_USER_PROTECTED (409); INVALID_EMAIL (422); INVITATION_RESEND_THROTTLED (429) bei Zustellwartezeit |
| Lokale Benutzereinladung widerrufen | INVALID_EMAIL (422) |
| Lokalen Benutzer aktualisieren/löschen | TAGLESS_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.