Kontrakt odpowiedzi i błędów API administracyjnego
Ten plik uzupełnia kontrakt odpowiedzi dla każdego punktu końcowego w Dokumentacji punktów końcowych. Treść pomyślnej odpowiedzi znajdziesz w wierszu punktu końcowego, a wszystkie wspólne i specyficzne treści niepowodzeń w tabelach poniżej. Domyślnie błędy używają kilku struktur zgodności; wywołujący mogą wybrać jedno uniwersalne opakowanie.
Opcjonalne ustrukturyzowane opakowanie błędu
Wyślij ten nagłówek żądania do dowolnego punktu końcowego:
X-Error-Format: envelope
Porównanie wartości usuwa skrajne spacje i nie rozróżnia wielkości liter. Przy tej dokładnej wartości każda odpowiedź JSON ze statusem 400 lub wyższym jest konwertowana do:
ErrorEnvelope = {
error: {
code: string,
message: string,
details: Record<string, unknown>,
requestId: string
}
}
Przykład konwersji domyślnej treści walidacji:
{
"error": {
"code": "VALIDATION_FAILED",
"message": "Invalid request",
"details": {
"fields": {
"name": ["String must contain at least 1 character(s)"]
}
},
"requestId": "integration-42"
}
}
Reguły konwersji są dokładne:
validationErrorsstaje siędetails.fields, acodestaje sięVALIDATION_FAILED, nawet jeśli domyślna treść zawierała również kod domenowy.- Domyślne pole
codenajwyższego poziomu jest zachowywane, gdy nie ma pól walidacji. - Pozostałe właściwości najwyższego poziomu, poza
error,message,validationErrorsicode, są przenoszone dodetails; na przykładlimiteksportu raportu staje siędetails.limit. - Pole tekstowe
errornajwyższego poziomu staje sięmessage. Jeśli go nie ma, używany jest domyślny komunikat dla statusu. - Kody zastępcze to
AUTH_REQUIRED(401),PERMISSION_DENIED(403),RESOURCE_NOT_FOUND(404),CONFLICT(409),VALIDATION_FAILED(422i inne niesklasyfikowane4xx),RATE_LIMITED(429),EXTERNAL_PROVIDER_FAILED(502) iINTERNAL_ERROR(inne5xx, w tym503). requestIdto dokładny nagłówek odpowiedziX-Request-Id. Identyfikator żądania podany przez wywołującego jest używany tylko wtedy, gdy po usunięciu skrajnych spacji pasuje do[A-Za-z0-9._:-]{1,128}; w przeciwnym razie serwer generuje UUID.
Ta transformacja nie zmienia statusu ani nagłówków niezwiązanych z treścią. Dotyczy też powtórzeń idempotentnych według nagłówka X-Error-Format żądania powtórzenia. Pomyślne odpowiedzi binarne pozostają binarne; ich błędy JSON są opakowywane. Pozostałe tabele pokazują domyślne treści; zastosowanie powyższych reguł daje drugą możliwą treść odpowiedzi dla każdego wiersza.
Oznaczenia odpowiedzi
ValidationError = {
validationErrors: Record<string, string[]>,
code?: string
}
CodedError = {
error: string,
code: string,
// a route may add fields explicitly listed below
}
PlainError = { error: string }
error i tekst komunikatu walidacji mają charakter opisowy, a nie stanowią stabilnego kryterium programowego. Opieraj decyzje na code, jeśli występuje. Walidacja żądania zwraca 422 ValidationError; walidacja całego obiektu może dać { "validationErrors": {} }, gdy nie wskazano pojedynczego pola. Nieprawidłowy JSON i nieoczekiwane awarie zwracają globalne 500 PlainError pokazane poniżej.
Wszystkie przykłady JSON pokazują dokładną strukturę treści. Tekst przedstawiony jako <message> to zwrócony komunikat walidacji lub operacji i jest ciągiem JSON, a nie dosłowną wartością w nawiasach ostrych.
Kolejność przetwarzania żądań
Żądania są przetwarzane w następującej kolejności:
- konfiguracja i uwierzytelnianie tokena obszaru roboczego;
- polityka dostawcy i limity częstotliwości tokena/obszaru roboczego;
- filtrowanie bieżących uprawnień do funkcji;
- dla każdej operacji zmieniającej dane — walidacja i rezerwacja klucza idempotencji;
- sprawdzenie zakresów uprawnień punktu końcowego, walidacja żądania i żądana operacja.
W konsekwencji operacja zmieniająca dane z prawidłowym tokenem, ale niewystarczającymi zakresami uprawnień, nadal musi przesłać Idempotency-Key. Zakończoną odpowiedź operacji 403, 404, 409 lub 422 można odtworzyć dla tego samego klucza i żądania.
Odpowiedzi uwierzytelniania, polityk i ograniczania częstotliwości żądań
Te odpowiedzi mogą wystąpić w każdym zarejestrowanym punkcie końcowym /v2/admin przed przetwarzaniem właściwym dla punktu końcowego.
| Status | Kiedy | Dokładna treść | Istotne nagłówki |
|---|---|---|---|
401 | Brakujący, powielony, połączony przecinkami token obszaru roboczego, token z innym schematem niż Bearer, niepoprawnie sformatowany, nieznany, wygasły, cofnięty lub w inny sposób nieprawidłowy | { "error": "Unauthorized", "code": "INVALID_WORKSPACE_TOKEN" } | WWW-Authenticate: Bearer, Cache-Control: no-store |
404 | Token jest prawidłowy, ale dostawca jego obszaru roboczego nie ma adminApiEnabled | { "error": "Not Found" } | Cache-Control: no-store |
429 | Wyczerpano pulę żądań tokena lub obszaru roboczego | { "error": "Too many attempts. Please try again later." } | Retry-After: <seconds> |
503 | Uwierzytelnianie tokenem obszaru roboczego jest tymczasowo niedostępne | { "error": "Admin API workspace-token configuration is unavailable", "code": "WORKSPACE_API_CONFIG_UNAVAILABLE" } | — |
503 | Niepowodzenie pobierania polityki dostawcy lub autoryzacji bieżących uprawnień do funkcji | { "error": "Workspace authorization is temporarily unavailable", "code": "WORKSPACE_AUTHORIZATION_UNAVAILABLE" } | — |
Dostęp do API jest zawarty w każdym planie. Wyłączenie ustawienia adminApiEnabled u dostawcy obszaru roboczego powoduje zwrócenie 404; utrata dodatkowego uprawnienia do funkcji usuwa tylko powiązane zakresy. Wynikowa odmowa dostępu do zakresu używa odpowiedzi poniżej, a nie procedury odświeżania tokena.
Błędy zakresu uprawnień, idempotencji, parsowania, własności i nieoczekiwane awarie
| Dotyczy | Status | Dokładna treść | Nagłówki/uwagi |
|---|---|---|---|
| Każda ścieżka po uwierzytelnieniu | 403 | { "error": "Insufficient workspace-token scope", "code": "INSUFFICIENT_SCOPE" } | Zwracane, gdy brakuje któregokolwiek wymaganego zakresu uprawnień. |
| Każda operacja zmieniająca dane | 400 | { "error": "Idempotency-Key is required for this operation", "code": "IDEMPOTENCY_KEY_REQUIRED" } | Nie podano klucza. |
| Każda operacja zmieniająca dane | 400 | { "error": "Exactly one Idempotency-Key is required", "code": "INVALID_IDEMPOTENCY_KEY" } | Powielony nagłówek lub wartości połączone przecinkiem. |
| Każda operacja zmieniająca dane | 400 | { "error": "Idempotency-Key must contain 1 to 255 visible characters", "code": "INVALID_IDEMPOTENCY_KEY" } | Puste, zbyt długie lub zawierające znak sterujący. |
| Każda operacja zmieniająca dane | 409 | { "error": "Idempotency-Key was already used with a different request", "code": "IDEMPOTENCY_CONFLICT" } | Ten sam token/metoda/ścieżka/klucz, ale inny URL lub treść. |
| Każda operacja zmieniająca dane | 409 | { "error": "Request is already processing", "code": "IDEMPOTENT_REQUEST_PROCESSING" } | Retry-After: 5. |
| Każda operacja zmieniająca dane | 409 | { "error": "Previous request outcome is unknown; verify its effects before attempting the operation again", "code": "IDEMPOTENCY_OUTCOME_UNKNOWN" } | Wygasła poprzednia rezerwacja przetwarzania, połączenie zostało zamknięte lub żądanie zakończyło się kodem 5xx. |
| Każda operacja zmieniająca dane | 503 | { "error": "Idempotency storage unavailable", "code": "IDEMPOTENCY_UNAVAILABLE" } | API nie może sprawdzić lub zapisać rekordu idempotencji. |
| Dowolny punkt końcowy z nieprawidłowym schematem zapytania, treści lub ścieżki | 422 | { "validationErrors": { "<field>": ["<message>"] } } | Może wystąpić wiele pól lub komunikatów. Wywołujący nie mogą podawać cpoId; obszar roboczy zawsze pochodzi z tokena. |
| Dowolny brak zagnieżdżonego zasobu obszaru roboczego lub identyfikator z innego obszaru roboczego | 404 | { "error": "Workspace resource not found", "code": "RESOURCE_NOT_FOUND" } | Stosowane konsekwentnie, chyba że tabela poniżej stanowi inaczej. |
| Dowolny punkt końcowy z nieoczekiwanym błędem | 500 | { "error": "Something went wrong" } | W przypadku operacji zmieniających dane późniejsze ponowienie tego samego klucza daje 409 IDEMPOTENCY_OUTCOME_UNKNOWN. |
Identyfikatory zasobów w ścieżce muszą być dodatnimi liczbami. Niedodatnie lub nieliczbowe :siteId, :chargerId, :portId, :tariffId, :profileId, :assignmentId, :userId, :rfidId, :accessId, :limitId lub :localUserId zwraca 422 ValidationError, a nie 400.
Błędy lokalizacji i zarządzania mocą
| Punkty końcowe | Status | Dokładna treść |
|---|---|---|
| Tworzenie/aktualizacja lokalizacji; walidacja pól obszaru roboczego | 422 | { "validationErrors": { "<field>": ["<message>"] } } |
DELETE /v2/admin/sites/:siteId, gdy lokalizacja ma zależności | 409 | { "error": "<message>", "code": "SITE_NOT_EMPTY" } |
GET /v2/admin/sites/geocode nieprawidłowe znormalizowane wyszukiwanie | 400 | { "error": "<message>", "code": "INVALID_GEOCODE_QUERY" } |
| To samo, zapełniona ograniczona kolejka dostawcy | 429 | { "error": "<message>", "code": "GEOCODING_BUSY" }; zawiera Retry-After, gdy geokoder je dostarczy |
| To samo, przekroczenie czasu/awaria dostawcy lub nieoczekiwany błąd geokodera | 502 | { "error": "<message>", "code": "GEOCODING_UNAVAILABLE" }; nieoczekiwany błąd używa Address search is temporarily unavailable |
PUT /v2/admin/sites/:siteId/power-management nieprawidłowa konfiguracja topologii/domeny | 422 | { "error": "<message>", "code": "INVALID_POWER_MANAGEMENT_CONFIGURATION" } |
| To samo, odmowa OCPP/przekroczenie czasu, wyścig współbieżnych operacji lub konflikt uzgadniania | 409 | { "error": "<message>", "code": "POWER_MANAGEMENT_CONFLICT" } |
Błędy ładowarek
mapChargerErrors() jest używane przy tworzeniu/aktualizacji ładowarki, danych uwierzytelniających, ustawieniach złącza, publicznym udostępnianiu, rozwiązywaniu danych QR, zmianie/ponownym wczytywaniu konfiguracji, uruchamianiu aktualizacji oprogramowania układowego, wszystkich czterech podstawowych poleceniach i żądaniu harmonogramu zbiorczego.
| Punkty końcowe | Status | Dokładna treść |
|---|---|---|
| Dowolna powyższa operacja z błędem walidacji reguł domenowych | 422 | { "validationErrors": { "<field>": ["<message>"] } } |
| Dowolna powyższa operacja z konfliktem stanu, unikalności, trybu offline/OCPP, rozliczeń, trybu bez identyfikatora, złącza lub gotowości | 409 | { "error": "<message>", "code": "CHARGER_CONFLICT" } |
GET /chargers/:chargerId/sessions, nieprawidłowy domyślny lub jawnie podany zakres czasu | 422 | { "validationErrors": { "from": ["from must be before or equal to to"] } } lub { "validationErrors": { "from": ["Session range cannot exceed 90 days"] } } |
Zwykłe operacje odczytu zwracają tylko wspólne odpowiedzi 401/403/404/429/500/503 oraz 422 dla walidacji zapytania lub ścieżki. Usuwanie ładowarki może zwrócić wspólne 500 PlainError, jeśli usunięcie nie powiedzie się bez bardziej szczegółowej odpowiedzi błędu.
Błędy raportów
| Punkty końcowe | Status | Dokładna treść |
|---|---|---|
Zakres danych/eksportu, w którym from >= to | 422 | { "validationErrors": { "range": ["from must be earlier than to"] } } |
| Zakres danych/eksportu przekracza 90 dni | 422 | { "validationErrors": { "range": ["Report ranges cannot exceed 90 days"] } } |
| Nieprawidłowy nieprzezroczysty kursor danych/pomiarów | 422 | { "validationErrors": { "cursor": ["<message>"] } } |
GET /reports/export, wynik przekracza 2000 wierszy | 422 | { "error": "<message>", "code": "REPORT_EXPORT_ROW_LIMIT", "limit": 2000 } |
POST /reports/send, brak zapisanego harmonogramu | 409 | { "error": "A workspace report schedule must be saved before sending", "code": "REPORT_SCHEDULE_REQUIRED" } |
| To samo, system pocztowy odrzuca lub ulega awarii | 502 | { "error": "Report delivery failed", "code": "REPORT_DELIVERY_FAILED" } |
| Brak należącego do obszaru zasobu harmonogramu/pomiarów | 404 | wspólna treść RESOURCE_NOT_FOUND |
Pomyślny eksport jest binarny; wszystkie błędy eksportu pozostają w JSON.
Błędy taryf
| Punkty końcowe | Status | Dokładna treść |
|---|---|---|
| Walidacja reguł domenowych tworzenia/aktualizacji/składników/ceny rynkowej/przypisania | 422 | { "validationErrors": { "<field>": ["<message>"] } } |
| Konflikt usuwania taryfy lub stanu/zależności/unikalności przypisania | 409 | { "error": "<message>", "code": "TARIFF_CONFLICT" } |
| Brak należącej do obszaru taryfy, strefy rynkowej, ładowarki, złącza, przypisania taryfy lub innego zagnieżdżonego zasobu | 404 | wspólna treść RESOURCE_NOT_FOUND |
Błędy profili ładowania
| Punkty końcowe | Status | Dokładna treść |
|---|---|---|
| Walidacja reguł domenowych tworzenia/aktualizacji/harmonogramu/przypisania | 422 | { "validationErrors": { "<field>": ["<message>"] } } |
| Profil jest używany w chronionym zastosowaniu | 409 | { "error": "<message>", "code": "CHARGING_PROFILE_IN_USE" } |
| Konflikt synchronizacji OCPP, przypisania, współbieżności lub inny konflikt profilu | 409 | { "error": "<message>", "code": "CHARGING_PROFILE_CONFLICT" } |
| Brak należącego do obszaru profilu, ładowarki, złącza, przypisania lub innego zagnieżdżonego zasobu | 404 | wspólna treść RESOURCE_NOT_FOUND |
Błędy domeny użytkowników
Błędy walidacji użytkownika wskazujące pole używają ValidationError i code; inne błędy użytkownika używają CodedError. Wszystkie przypadki brakujących zasobów używają wspólnej odpowiedzi RESOURCE_NOT_FOUND, która nie ujawnia istnienia zasobu.
| Status | Kod(y) | Treść |
|---|---|---|
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" }; zawiera 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 może również zwrócić wspólne 403 INSUFFICIENT_SCOPE po sparsowaniu treści, jeśli brakuje users:access albo podano RFID i brakuje users:rfid. Punkty końcowe użytkowników lokalnych wymieniają każdy wymagany zakres w Dokumentacji punktów końcowych.
Kody błędów użytkownika obowiązują następująco:
| Grupa punktów końcowych | Kody domeny użytkowników inne niż 404, dodatkowe wobec wspólnych odpowiedzi |
|---|---|
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) |
| Szczegóły użytkownika, pojazdy i odczyty RFID/dostępu/limitów | brak kodu domenowego innego niż 404 |
| Tworzenie RFID | CUSTOMER_CONTRACT_MISSING, RFID_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409); INVALID_RFID (422) |
| Aktualizacja/usuwanie RFID | TAGLESS_USER_PROTECTED (409) |
| Zastąpienie dostępu | TAGLESS_USER_PROTECTED (409); NO_CHARGERS_AVAILABLE (422) |
| Cofnięcie dostępu | TAGLESS_USER_PROTECTED (409) |
| Tworzenie/aktualizacja limitu | TAGLESS_USER_PROTECTED, LIMIT_ALREADY_EXISTS (409); INVALID_LIMIT_TYPE, INVALID_LIMIT_VALUE (422) |
| Usuwanie limitu | TAGLESS_USER_PROTECTED (409) |
| Tworzenie zaproszenia do obszaru roboczego | CUSTOMER_CONTRACT_MISSING, INVITATION_EMAIL_IN_USE, RFID_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409); INVALID_EMAIL/INVALID_RFID (422); INVITATION_RESEND_THROTTLED (429), gdy obowiązuje odstęp między wysyłkami |
| Ponowne wysyłanie zaproszenia do obszaru roboczego | INVALID_EMAIL (422), INVITATION_RESEND_THROTTLED (429) |
| Anulowanie zaproszenia do obszaru roboczego | INVALID_EMAIL (422) |
| Tworzenie lokalnego użytkownika ładowarki dla istniejącego klienta | LOCAL_USER_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409) |
| Zaproszenie lokalnego użytkownika ładowarki | LOCAL_USER_ALREADY_EXISTS, INVITATION_EMAIL_IN_USE, TAGLESS_USER_PROTECTED (409); INVALID_EMAIL (422); INVITATION_RESEND_THROTTLED (429), gdy obowiązuje odstęp między wysyłkami |
| Anulowanie zaproszenia użytkownika lokalnego | INVALID_EMAIL (422) |
| Aktualizacja/usuwanie użytkownika lokalnego | TAGLESS_USER_PROTECTED (409) |
Wszystkie wyniki dotyczące własności i brakujących zasobów w tych grupach, w tym niezarejestrowany adres e-mail w POST /users, używają wspólnej treści 404 RESOURCE_NOT_FOUND.
Odpowiedzi bez treści i odpowiedzi na powtórzenia
Pomyślna odpowiedź 204 nie ma treści. Dotyczy to każdej udokumentowanej operacji usunięcia, przy której wymieniono 204 empty. Zakończone powtórzenie idempotentne ustawia Idempotency-Replayed: true i używa zapisanego statusu oraz treści; dla 204 odpowiedź HTTP nadal nie ma treści. API nigdy nie zwraca obiektu JSON potwierdzającego powodzenie dla udokumentowanej operacji 204.