Kontrakt odpovědí a chyb administračního API
Tento soubor doplňuje kontrakt odpovědí pro každý endpoint v Referenci endpointů. Úspěšné tělo najdete v řádku endpointu a všechna sdílená či specifická neúspěšná těla v tabulkách níže. Ve výchozím stavu mají chyby několik kompatibilních tvarů; volající může zvolit jednu univerzální obálku.
Volitelná strukturovaná obálka chyb
Na libovolný endpoint odešlete tuto hlavičku požadavku:
X-Error-Format: envelope
Hodnota se porovnává po oříznutí mezer bez rozlišení velikosti písmen. Při této přesné hodnotě se každá odpověď JSON se stavem 400 nebo vyšším převede na:
ErrorEnvelope = {
error: {
code: string,
message: string,
details: Record<string, unknown>,
requestId: string
}
}
Příklad převodu výchozího validačního těla:
{
"error": {
"code": "VALIDATION_FAILED",
"message": "Invalid request",
"details": {
"fields": {
"name": ["String must contain at least 1 character(s)"]
}
},
"requestId": "integration-42"
}
}
Pravidla převodu jsou přesná:
validationErrorsse změní nadetails.fieldsacodenaVALIDATION_FAILED, i když výchozí tělo mělo také doménový kód.- Výchozí
codena nejvyšší úrovni zůstane zachováno, pokud nejsou žádná validační pole. - Ostatní vlastnosti nejvyšší úrovně kromě
error,message,validationErrorsacodese přesunou dodetails; napříkladlimitexportu přehledu se změní nadetails.limit. - Řetězcové
errorna nejvyšší úrovni se změní namessage. Pokud chybí, použije se náhradní text podle stavu. - Náhradní kódy jsou
AUTH_REQUIRED(401),PERMISSION_DENIED(403),RESOURCE_NOT_FOUND(404),CONFLICT(409),VALIDATION_FAILED(422a další nezařazené4xx),RATE_LIMITED(429),EXTERNAL_PROVIDER_FAILED(502) aINTERNAL_ERROR(ostatní5xxvčetně503). requestIdje přesná hlavička odpovědiX-Request-Id. ID požadavku dodané volajícím se použije jen tehdy, odpovídá-li po oříznutí[A-Za-z0-9._:-]{1,128}; jinak server vygeneruje UUID.
Tento převod nemění stav ani hlavičky nesouvisející s tělem. Platí také pro idempotentní přehrání podle hlavičky X-Error-Format opakovaného požadavku. Binární úspěšné odpovědi zůstávají binární; jejich chyby JSON se zabalí do obálky. Další tabulky uvádějí výchozí těla; použitím pravidel výše získáte druhé možné tělo odpovědi pro každý řádek.
Zápis odpovědí
ValidationError = {
validationErrors: Record<string, string[]>,
code?: string
}
CodedError = {
error: string,
code: string,
// a route may add fields explicitly listed below
}
PlainError = { error: string }
error a text ověřovací zprávy jsou popisné, nikoli stabilní programové rozlišovače. Větvení provádějte podle code, je-li přítomno. Ověření požadavku vrací 422 ValidationError; ověření celého objektu může vytvořit { "validationErrors": {} }, pokud není určeno jednotlivé pole. Neplatný JSON a neočekávaná selhání vracejí globální 500 PlainError uvedené níže.
Všechny příklady JSON jsou přesné tvary těla. Text uvedený jako <message> je vrácená validační nebo provozní zpráva a jde o JSON řetězec, nikoli doslovnou hodnotu v lomených závorkách.
Pořadí zpracování požadavku
Požadavky se zpracovávají v tomto pořadí:
- konfigurace a ověřování tokenu pracovního prostoru;
- pravidla hostitele a limity požadavků tokenu/pracovního prostoru;
- filtrování aktuálních nároků;
- pro každou změnu ověření/získání idempotence;
- kontroly rozsahů endpointu, ověření požadavku a požadovaná operace.
I změna s platným tokenem a nedostatečným rozsahem musí poslat Idempotency-Key. Dokončenou odpověď změny 403, 404, 409 nebo 422 lze přehrát pro stejný klíč a požadavek.
Odpovědi ověření, pravidel a omezení požadavků
Tyto odpovědi se mohou objevit na každém registrovaném endpointu /v2/admin před jeho specifickým zpracováním.
| Stav | Kdy | Přesné tělo | Relevantní hlavičky |
|---|---|---|---|
401 | Chybějící, duplicitní, čárkou spojený, jiný než Bearer, chybný, neznámý, prošlý, zrušený nebo jinak neplatný token prostoru | { "error": "Unauthorized", "code": "INVALID_WORKSPACE_TOKEN" } | WWW-Authenticate: Bearer, Cache-Control: no-store |
404 | Token je platný, ale hostitel jeho pracovního prostoru nemá adminApiEnabled | { "error": "Not Found" } | Cache-Control: no-store |
429 | Limit požadavků pro token nebo pracovní prostor je vyčerpán | { "error": "Too many attempts. Please try again later." } | Retry-After: <seconds> |
503 | Ověřování tokenem pracovního prostoru je dočasně nedostupné | { "error": "Admin API workspace-token configuration is unavailable", "code": "WORKSPACE_API_CONFIG_UNAVAILABLE" } | — |
503 | Selže vyhledání pravidel hostitele nebo ověření aktuálního nároku | { "error": "Workspace authorization is temporarily unavailable", "code": "WORKSPACE_AUTHORIZATION_UNAVAILABLE" } | — |
Přístup API je v každém balíčku. Vypnutí nastavení adminApiEnabled u hostitele vrací 404; ztráta dalšího funkčního nároku odebere jen dotčené rozsahy. Odmítnutí rozsahu používá níže uvedenou odpověď, nikoli obnovení tokenu.
Rozsah, idempotence, parsování, vlastnictví a neočekávaná selhání
| Platí pro | Stav | Přesné tělo | Hlavičky/poznámky |
|---|---|---|---|
| Každá route po ověření | 403 | { "error": "Insufficient workspace-token scope", "code": "INSUFFICIENT_SCOPE" } | Vrací se, pokud chybí kterýkoli požadovaný rozsah. |
| Každá změna | 400 | { "error": "Idempotency-Key is required for this operation", "code": "IDEMPOTENCY_KEY_REQUIRED" } | Klíč nebyl zadán. |
| Každá změna | 400 | { "error": "Exactly one Idempotency-Key is required", "code": "INVALID_IDEMPOTENCY_KEY" } | Duplicitní hlavička nebo hodnoty spojené čárkou. |
| Každá změna | 400 | { "error": "Idempotency-Key must contain 1 to 255 visible characters", "code": "INVALID_IDEMPOTENCY_KEY" } | Prázdné, příliš dlouhé nebo se řídicím znakem. |
| Každá změna | 409 | { "error": "Idempotency-Key was already used with a different request", "code": "IDEMPOTENCY_CONFLICT" } | Stejný token/metoda/cesta/klíč, jiná URL nebo tělo. |
| Každá změna | 409 | { "error": "Request is already processing", "code": "IDEMPOTENT_REQUEST_PROCESSING" } | Retry-After: 5. |
| Každá změna | 409 | { "error": "Previous request outcome is unknown; verify its effects before attempting the operation again", "code": "IDEMPOTENCY_OUTCOME_UNKNOWN" } | Předchozí pronájem zpracování vypršel, připojení se uzavřelo nebo požadavek skončil chybou 5xx. |
| Každá změna | 503 | { "error": "Idempotency storage unavailable", "code": "IDEMPOTENCY_UNAVAILABLE" } | API nemůže zkontrolovat nebo uložit záznam idempotence. |
| Libovolný endpoint s neplatným schématem dotazu/těla/cesty | 422 | { "validationErrors": { "<field>": ["<message>"] } } | Může být více polí i zpráv. Volající nesmí zadat cpoId; prostor vždy pochází z tokenu. |
| Chybějící vnořený zdroj pracovního prostoru nebo ID jiného prostoru | 404 | { "error": "Workspace resource not found", "code": "RESOURCE_NOT_FOUND" } | Používá se jednotně, pokud tabulka níže neuvádí jinak. |
| Libovolný endpoint s neočekávanou chybou | 500 | { "error": "Something went wrong" } | U změn pozdější opakování stejného klíče vrací 409 IDEMPOTENCY_OUTCOME_UNKNOWN. |
ID prostředků v cestě musí být kladná čísla. Nekladné nebo nečíselné :siteId, :chargerId, :portId, :tariffId, :profileId, :assignmentId, :userId, :rfidId, :accessId, :limitId nebo :localUserId vrací 422 ValidationError, nikoli 400.
Chyby lokalit a řízení výkonu
| Endpointy | Stav | Přesné tělo |
|---|---|---|
| Vytvoření/aktualizace lokality; ověření polí pracovního prostoru | 422 | { "validationErrors": { "<field>": ["<message>"] } } |
DELETE /v2/admin/sites/:siteId, pokud má lokalita závislosti | 409 | { "error": "<message>", "code": "SITE_NOT_EMPTY" } |
GET /v2/admin/sites/geocode neplatné normalizované hledání | 400 | { "error": "<message>", "code": "INVALID_GEOCODE_QUERY" } |
| Totéž, omezená fronta poskytovatele je plná | 429 | { "error": "<message>", "code": "GEOCODING_BUSY" }; zahrnuje Retry-After, pokud jej poskytne geokodér |
| Totéž, časový limit/selhání poskytovatele nebo neočekávaná chyba geokodéru | 502 | { "error": "<message>", "code": "GEOCODING_UNAVAILABLE" }; neočekávaná chyba používá Address search is temporarily unavailable |
PUT /v2/admin/sites/:siteId/power-management neplatná topologie/doménová konfigurace | 422 | { "error": "<message>", "code": "INVALID_POWER_MANAGEMENT_CONFIGURATION" } |
| Totéž, odmítnutí OCPP/časový limit, souběh nebo konflikt sjednocení stavu | 409 | { "error": "<message>", "code": "POWER_MANAGEMENT_CONFLICT" } |
Chyby nabíječek
mapChargerErrors() se používá při vytváření/aktualizaci nabíječky, přihlašovacích údajích, nastavení konektorů, veřejném zveřejnění, rozlišení obsahu QR, změně/znovunačtení konfigurace, spuštění firmwaru, všech čtyřech základních příkazech a požadavku na složený rozvrh.
| Endpointy | Stav | Přesné tělo |
|---|---|---|
| Kterákoli výše uvedená operace s doménovou validační chybou | 422 | { "validationErrors": { "<field>": ["<message>"] } } |
| Kterákoli výše uvedená operace s konfliktem stavu, jedinečnosti, offline/OCPP, účtování, Tagless, konektoru nebo připravenosti | 409 | { "error": "<message>", "code": "CHARGER_CONFLICT" } |
GET /chargers/:chargerId/sessions, neplatný výchozí/výslovný časový rozsah | 422 | { "validationErrors": { "from": ["from must be before or equal to to"] } } nebo { "validationErrors": { "from": ["Session range cannot exceed 90 days"] } } |
Běžné operace čtení vracejí pouze sdílené odpovědi 401/403/404/429/500/503 a ověření dotazu/cesty 422. Smazání nabíječky může vrátit sdílenou chybu 500 PlainError, pokud selže bez konkrétnější chybové odpovědi.
Chyby přehledů
| Endpointy | Stav | Přesné tělo |
|---|---|---|
Období dat/exportu s from >= to | 422 | { "validationErrors": { "range": ["from must be earlier than to"] } } |
| Období dat/exportu přes 90 dní | 422 | { "validationErrors": { "range": ["Report ranges cannot exceed 90 days"] } } |
| Neplatný neprůhledný kurzor dat/měření | 422 | { "validationErrors": { "cursor": ["<message>"] } } |
GET /reports/export, výsledek přesahuje 2 000 řádků | 422 | { "error": "<message>", "code": "REPORT_EXPORT_ROW_LIMIT", "limit": 2000 } |
POST /reports/send, žádný uložený rozvrh | 409 | { "error": "A workspace report schedule must be saved before sending", "code": "REPORT_SCHEDULE_REQUIRED" } |
| Totéž, poštovní služba odmítne/selže | 502 | { "error": "Report delivery failed", "code": "REPORT_DELIVERY_FAILED" } |
| Vlastněný prostředek rozvrhu/měření neexistuje | 404 | sdílené tělo RESOURCE_NOT_FOUND |
Úspěšný export je binární; všechny chyby exportu zůstávají JSON.
Chyby tarifů
| Endpointy | Stav | Přesné tělo |
|---|---|---|
| Doménová validace vytvoření/aktualizace/složek/tržních cen/přiřazení | 422 | { "validationErrors": { "<field>": ["<message>"] } } |
| Konflikt stavu/závislosti/jedinečnosti při smazání nebo přiřazení tarifu | 409 | { "error": "<message>", "code": "TARIFF_CONFLICT" } |
| Tarif, nabídková zóna, nabíječka, konektor, přiřazení tarifu nebo jiný vnořený objekt nepatří vlastníkovi | 404 | sdílené tělo RESOURCE_NOT_FOUND |
Chyby nabíjecích profilů
| Endpointy | Stav | Přesné tělo |
|---|---|---|
| Doménová validace vytvoření/aktualizace/rozvrhu/přiřazení | 422 | { "validationErrors": { "<field>": ["<message>"] } } |
| Na profil odkazuje chráněné použití | 409 | { "error": "<message>", "code": "CHARGING_PROFILE_IN_USE" } |
| Konflikt synchronizace OCPP, přiřazení, souběhu nebo profilu | 409 | { "error": "<message>", "code": "CHARGING_PROFILE_CONFLICT" } |
| Profil, nabíječka, konektor, přiřazení nebo jiný vnořený objekt nepatří vlastníkovi | 404 | sdílené tělo RESOURCE_NOT_FOUND |
Chyby uživatelské domény
Chyby ověření uživatele určující pole používají ValidationError a code; ostatní chyby uživatele používají CodedError. Všechny případy chybějícího prostředku používají sdílenou odpověď RESOURCE_NOT_FOUND, která neprozrazuje existenci prostředků.
| Stav | Kódy | Tělo |
|---|---|---|
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" }; zahrnuje 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 může po parsování těla také vrátit sdílené 403 INSUFFICIENT_SCOPE, pokud chybí users:access, nebo pokud bylo předáno RFID a chybí users:rfid. Endpointy místních uživatelů uvádějí každý požadovaný rozsah v Referenci endpointů.
Chybové kódy uživatelů se používají takto:
| Skupina endpointů | Doménové kódy uživatelů jiné než 404 nad rámec společných odpovědí |
|---|---|
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) |
| Čtení podrobností uživatele, vozidel, RFID/přístupu/limitů | žádný doménový kód odlišný od 404 |
| Vytvoření RFID | CUSTOMER_CONTRACT_MISSING, RFID_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409); INVALID_RFID (422) |
| Aktualizace/smazání RFID | TAGLESS_USER_PROTECTED (409) |
| Nahrazení přístupu | TAGLESS_USER_PROTECTED (409); NO_CHARGERS_AVAILABLE (422) |
| Odebrání přístupu | TAGLESS_USER_PROTECTED (409) |
| Vytvoření/aktualizace limitu | TAGLESS_USER_PROTECTED, LIMIT_ALREADY_EXISTS (409); INVALID_LIMIT_TYPE, INVALID_LIMIT_VALUE (422) |
| Smazání limitu | TAGLESS_USER_PROTECTED (409) |
| Vytvoření pozvánky do pracovního prostoru | CUSTOMER_CONTRACT_MISSING, INVITATION_EMAIL_IN_USE, RFID_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409); INVALID_EMAIL/INVALID_RFID (422); INVITATION_RESEND_THROTTLED (429), pokud platí čekací doba doručení |
| Opětovné odeslání pozvánky do pracovního prostoru | INVALID_EMAIL (422), INVITATION_RESEND_THROTTLED (429) |
| Zrušení pozvánky do pracovního prostoru | INVALID_EMAIL (422) |
| Vytvoření místního uživatele nabíječky pro existujícího zákazníka | LOCAL_USER_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409) |
| Pozvání místního uživatele nabíječky | LOCAL_USER_ALREADY_EXISTS, INVITATION_EMAIL_IN_USE, TAGLESS_USER_PROTECTED (409); INVALID_EMAIL (422); INVITATION_RESEND_THROTTLED (429), pokud platí čekací doba doručení |
| Zrušení pozvání místního uživatele | INVALID_EMAIL (422) |
| Aktualizace/smazání místního uživatele | TAGLESS_USER_PROTECTED (409) |
Všechny výsledky vlastnictví a chybějících zdrojů v těchto skupinách, včetně neregistrovaného e-mailu na POST /users, používají společné tělo 404 RESOURCE_NOT_FOUND.
Odpovědi bez těla a opakované odpovědi
Úspěšná odpověď 204 nemá tělo. Platí to pro každé dokumentované mazání uvádějící 204 empty. Dokončené idempotentní opakování nastaví Idempotency-Replayed: true a použije uložený stav a tělo; u 204 zůstává HTTP odpověď bez těla. API nikdy nevrací úspěšný JSON objekt pro dokumentovanou operaci 204.