Risposte ed errori

Contratto di risposte ed errori dell’API di amministrazione

Questo file completa il contratto delle risposte per ogni endpoint in Riferimento degli endpoint. Leggi la riga dell'endpoint per il corpo di successo e le tabelle seguenti per tutti i corpi di errore comuni o specifici dell'endpoint. Per impostazione predefinita, gli errori usano diverse strutture di compatibilità; i chiamanti possono scegliere un'unica struttura universale.

Struttura di errore facoltativa

Invia questa intestazione di richiesta a qualsiasi endpoint:

X-Error-Format: envelope

Il confronto del valore ignora gli spazi iniziali e finali e non distingue tra maiuscole e minuscole. Con quel valore esatto, ogni risposta JSON con stato pari o superiore a 400 viene convertita in:

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

Esempio di conversione di un corpo di validazione predefinito:

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

Le regole di conversione sono esatte:

  • validationErrors diventa details.fields e code diventa VALIDATION_FAILED, anche quando il corpo predefinito conteneva già un codice di dominio.
  • Il valore code predefinito al livello principale viene mantenuto quando non sono presenti campi di validazione.
  • Le altre proprietà di primo livello, escluse error, message, validationErrors e code, vengono spostate in details; ad esempio, l'esportazione dei report limit diventa details.limit.
  • Un campo error di tipo stringa al livello principale diventa message. Se non esiste, viene usato il messaggio predefinito per lo stato.
  • I codici di ripiego sono AUTH_REQUIRED (401), PERMISSION_DENIED (403), RESOURCE_NOT_FOUND (404), CONFLICT (409), VALIDATION_FAILED (422 e altri 4xx non classificati), RATE_LIMITED (429), EXTERNAL_PROVIDER_FAILED (502) e INTERNAL_ERROR (altri 5xx, incluso 503).
  • requestId è l'esatta intestazione di risposta X-Request-Id. Un ID di richiesta fornito dal chiamante viene usato solo se, dopo la rimozione degli spazi iniziali e finali, corrisponde a [A-Za-z0-9._:-]{1,128}; altrimenti il server genera un UUID.

Questa trasformazione non modifica lo stato né le intestazioni non relative al corpo. Si applica anche alle riproduzioni idempotenti in base all'intestazione X-Error-Format della richiesta di riproduzione. Le risposte binarie di successo rimangono binarie; i loro errori JSON vengono racchiusi nella struttura. Le tabelle rimanenti mostrano i corpi predefiniti; applicando le regole precedenti si ottiene l'altro possibile corpo di risposta per ogni riga.

Notazione delle risposte

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

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

PlainError = { error: string }

error e il testo dei messaggi di convalida sono descrittivi, non discriminatori programmatici stabili. Basa le diramazioni su code, se presente. La convalida delle richieste restituisce 422 ValidationError; la convalida di un intero oggetto può produrre { "validationErrors": {} } quando non viene identificato un singolo campo. JSON non valido ed errori imprevisti restituiscono il 500 PlainError globale mostrato di seguito.

Tutti gli esempi JSON mostrano le strutture esatte del corpo. Il testo rappresentato da <message> è il messaggio di validazione o dell’operazione restituito ed è una stringa JSON, non un valore letterale tra parentesi angolari.

Ordine di elaborazione delle richieste

Le richieste vengono elaborate in questo ordine:

  1. configurazione e autenticazione dei token dello spazio di lavoro;
  2. criteri dell'host e limiti di frequenza del token/spazio di lavoro;
  3. filtro delle abilitazioni correnti;
  4. per ogni operazione di modifica, convalida/acquisizione dell'idempotenza;
  5. controlli degli ambiti dell'endpoint, convalida della richiesta e operazione richiesta.

Di conseguenza, anche una mutazione con un token valido ma con ambiti insufficienti deve inviare Idempotency-Key. Una risposta completata a una mutazione 403, 404, 409 o 422 può essere ripetuta per la stessa chiave e richiesta.

Risposte di autenticazione, criteri e limitazione delle richieste

Queste risposte possono verificarsi su ogni endpoint /v2/admin registrato prima dell'elaborazione specifica dell'endpoint.

StatoQuandoCorpo esattoIntestazioni pertinenti
401Token dello spazio di lavoro mancante, duplicato, unito con virgole, non Bearer, con formato errato, sconosciuto, scaduto, revocato o comunque non valido{ "error": "Unauthorized", "code": "INVALID_WORKSPACE_TOKEN" }WWW-Authenticate: Bearer, Cache-Control: no-store
404Il token è valido, ma l'host del suo spazio di lavoro non dispone di adminApiEnabled{ "error": "Not Found" }Cache-Control: no-store
429La quota delle richieste per token o per spazio di lavoro è esaurita{ "error": "Too many attempts. Please try again later." }Retry-After: <seconds>
503L'autenticazione con token dello spazio di lavoro è temporaneamente indisponibile{ "error": "Admin API workspace-token configuration is unavailable", "code": "WORKSPACE_API_CONFIG_UNAVAILABLE" }—
503La ricerca dei criteri dell'host o l'autorizzazione delle abilitazioni correnti non riesce{ "error": "Workspace authorization is temporarily unavailable", "code": "WORKSPACE_AUTHORIZATION_UNAVAILABLE" }—

L’accesso API è incluso in ogni piano. Disabilitare l’impostazione adminApiEnabled dell’host dello spazio di lavoro restituisce 404; perdere un diritto aggiuntivo a una funzione rimuove solo gli ambiti interessati. Il conseguente rifiuto dell’ambito usa la risposta seguente, non una procedura di aggiornamento del token.

Errori relativi ad ambiti, idempotenza, analisi, proprietà ed errori imprevisti

Si applica aStatoCorpo esattoIntestazioni/note
Ogni percorso dopo l’autenticazione403{ "error": "Insufficient workspace-token scope", "code": "INSUFFICIENT_SCOPE" }Restituito quando manca un qualsiasi ambito richiesto.
Ogni mutazione400{ "error": "Idempotency-Key is required for this operation", "code": "IDEMPOTENCY_KEY_REQUIRED" }Nessuna chiave fornita.
Ogni mutazione400{ "error": "Exactly one Idempotency-Key is required", "code": "INVALID_IDEMPOTENCY_KEY" }Intestazione duplicata o valori uniti da virgole.
Ogni mutazione400{ "error": "Idempotency-Key must contain 1 to 255 visible characters", "code": "INVALID_IDEMPOTENCY_KEY" }Vuoto, troppo lungo o contenente un carattere di controllo.
Ogni mutazione409{ "error": "Idempotency-Key was already used with a different request", "code": "IDEMPOTENCY_CONFLICT" }Stesso token/metodo/percorso/chiave, URL o corpo diverso.
Ogni mutazione409{ "error": "Request is already processing", "code": "IDEMPOTENT_REQUEST_PROCESSING" }Retry-After: 5.
Ogni mutazione409{ "error": "Previous request outcome is unknown; verify its effects before attempting the operation again", "code": "IDEMPOTENCY_OUTCOME_UNKNOWN" }Il periodo di riserva dell'elaborazione precedente è scaduto, la connessione si è chiusa oppure la richiesta si è conclusa con 5xx.
Ogni mutazione503{ "error": "Idempotency storage unavailable", "code": "IDEMPOTENCY_UNAVAILABLE" }L'API non può controllare o salvare la registrazione di idempotenza.
Qualsiasi endpoint con schema di query, corpo o percorso non valido422{ "validationErrors": { "<field>": ["<message>"] } }Possono essere presenti più campi/messaggi. I chiamanti non possono fornire cpoId; lo spazio di lavoro deriva sempre dal token.
Qualsiasi risorsa annidata mancante nello spazio di lavoro o ID di un altro spazio di lavoro404{ "error": "Workspace resource not found", "code": "RESOURCE_NOT_FOUND" }Usato in modo coerente, salvo diversa indicazione in una tabella seguente.
Qualsiasi endpoint con un errore imprevisto500{ "error": "Something went wrong" }Per le operazioni di modifica, un nuovo tentativo successivo con la stessa chiave restituisce 409 IDEMPOTENCY_OUTCOME_UNKNOWN.

Gli ID delle risorse nel percorso devono essere numeri positivi. Un valore :siteId, :chargerId, :portId, :tariffId, :profileId, :assignmentId, :userId, :rfidId, :accessId, :limitId o :localUserId non positivo o non numerico restituisce 422 ValidationError, non 400.

Errori dei siti e della gestione della potenza

EndpointStatoCorpo esatto
Creazione/aggiornamento del sito; convalida dei campi dello spazio di lavoro422{ "validationErrors": { "<field>": ["<message>"] } }
DELETE /v2/admin/sites/:siteId quando il sito ha dipendenze409{ "error": "<message>", "code": "SITE_NOT_EMPTY" }
GET /v2/admin/sites/geocode ricerca normalizzata non valida400{ "error": "<message>", "code": "INVALID_GEOCODE_QUERY" }
Come sopra, coda limitata del fornitore piena429{ "error": "<message>", "code": "GEOCODING_BUSY" }; include Retry-After se fornito dal geocodificatore
Come sopra, timeout/errore del fornitore o errore imprevisto del geocodificatore502{ "error": "<message>", "code": "GEOCODING_UNAVAILABLE" }; un errore imprevisto usa Address search is temporarily unavailable
PUT /v2/admin/sites/:siteId/power-management configurazione della topologia/del dominio non valida422{ "error": "<message>", "code": "INVALID_POWER_MANAGEMENT_CONFIGURATION" }
Come sopra, rifiuto/timeout OCPP, modifica concorrente o conflitto di riconciliazione409{ "error": "<message>", "code": "POWER_MANAGEMENT_CONFLICT" }

Errori dei caricatori

mapChargerErrors() viene usato per creazione/aggiornamento dei caricatori, credenziali, impostazioni dei connettori, pubblicazione nell'elenco pubblico, risoluzione dei dati del codice QR, modifica/ricaricamento della configurazione, avvio del firmware, tutti e quattro i comandi di base e richiesta della pianificazione composita.

EndpointStatoCorpo esatto
Qualsiasi operazione precedente con errore di validazione delle regole di dominio422{ "validationErrors": { "<field>": ["<message>"] } }
Qualsiasi operazione precedente con conflitto di stato, unicità, offline/OCPP, fatturazione, modalità senza tag, connettore o disponibilità alla ricarica409{ "error": "<message>", "code": "CHARGER_CONFLICT" }
GET /chargers/:chargerId/sessions, intervallo di tempo predefinito/esplicito non valido422{ "validationErrors": { "from": ["from must be before or equal to to"] } } o { "validationErrors": { "from": ["Session range cannot exceed 90 days"] } }

Le semplici operazioni di lettura restituiscono solo le risposte comuni 401/403/404/429/500/503 e 422 per la convalida della query o del percorso. L'eliminazione di un caricatore può restituire la risposta comune 500 PlainError se non riesce senza una risposta di errore più specifica.

Errori dei report

EndpointStatoCorpo esatto
Intervallo di dati/esportazione in cui from >= to422{ "validationErrors": { "range": ["from must be earlier than to"] } }
Intervallo di dati/esportazione superiore a 90 giorni422{ "validationErrors": { "range": ["Report ranges cannot exceed 90 days"] } }
Cursore opaco non valido per dati/misurazioni422{ "validationErrors": { "cursor": ["<message>"] } }
GET /reports/export, il risultato supera 2.000 righe422{ "error": "<message>", "code": "REPORT_EXPORT_ROW_LIMIT", "limit": 2000 }
POST /reports/send, nessuna pianificazione salvata409{ "error": "A workspace report schedule must be saved before sending", "code": "REPORT_SCHEDULE_REQUIRED" }
Come sopra, il servizio email rifiuta l'invio o non riesce a eseguirlo502{ "error": "Report delivery failed", "code": "REPORT_DELIVERY_FAILED" }
Risorsa di proprietà relativa a pianificazione/misurazioni assente404corpo comune RESOURCE_NOT_FOUND

L'esportazione riuscita è binaria; tutti gli errori di esportazione rimangono JSON.

Errori delle tariffe

EndpointStatoCorpo esatto
Validazione di dominio per creazione/aggiornamento/componenti/prezzo di mercato/assegnazione422{ "validationErrors": { "<field>": ["<message>"] } }
Conflitto di stato, dipendenze o unicità nell'eliminazione o nell'assegnazione della tariffa409{ "error": "<message>", "code": "TARIFF_CONFLICT" }
Tariffa, zona di mercato, caricatore, connettore, assegnazione della tariffa o altra risorsa annidata non appartenente al contesto di proprietà404corpo comune RESOURCE_NOT_FOUND

Errori dei profili di ricarica

EndpointStatoCorpo esatto
Validazione di dominio per creazione/aggiornamento/programmazione/assegnazione422{ "validationErrors": { "<field>": ["<message>"] } }
Il profilo è richiamato da un utilizzo protetto409{ "error": "<message>", "code": "CHARGING_PROFILE_IN_USE" }
Conflitto di sincronizzazione OCPP, assegnazione, concorrenza o altro conflitto del profilo409{ "error": "<message>", "code": "CHARGING_PROFILE_CONFLICT" }
Profilo, caricatore, connettore, assegnazione o altra risorsa annidata non appartenente al contesto di proprietà404corpo comune RESOURCE_NOT_FOUND

Errori del dominio utenti

Gli errori di convalida degli utenti che identificano un campo usano ValidationError insieme a code; gli altri errori degli utenti usano CodedError. Tutti i casi di risorse mancanti usano la risposta comune RESOURCE_NOT_FOUND, che non consente l'enumerazione delle risorse.

StatoCodice/iCorpo
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" }; include 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 può anche restituire la risposta comune 403 INSUFFICIENT_SCOPE dopo l'analisi del corpo se manca users:access, oppure se è stato fornito un RFID e manca users:rfid. Gli endpoint degli utenti locali elencano tutti gli ambiti richiesti in Riferimento degli endpoint.

I codici di errore degli utenti si applicano come segue:

Famiglia di endpointCodici del dominio utenti diversi da 404, oltre alle risposte comuni
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)
Lettura dei dettagli degli utenti, dei veicoli e di RFID/accessi/limitinessun codice di dominio diverso da 404
Creazione RFIDCUSTOMER_CONTRACT_MISSING, RFID_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409); INVALID_RFID (422)
Aggiornamento/eliminazione RFIDTAGLESS_USER_PROTECTED (409)
Sostituzione degli accessiTAGLESS_USER_PROTECTED (409); NO_CHARGERS_AVAILABLE (422)
Revoca dell’accessoTAGLESS_USER_PROTECTED (409)
Creazione/aggiornamento del limiteTAGLESS_USER_PROTECTED, LIMIT_ALREADY_EXISTS (409); INVALID_LIMIT_TYPE, INVALID_LIMIT_VALUE (422)
Eliminazione del limiteTAGLESS_USER_PROTECTED (409)
Creazione dell'invito nello spazio di lavoroCUSTOMER_CONTRACT_MISSING, INVITATION_EMAIL_IN_USE, RFID_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409); INVALID_EMAIL/INVALID_RFID (422); INVITATION_RESEND_THROTTLED (429) quando si applica l'intervallo minimo tra le consegne
Nuovo invio dell'invito nello spazio di lavoroINVALID_EMAIL (422), INVITATION_RESEND_THROTTLED (429)
Annullamento dell'invito nello spazio di lavoroINVALID_EMAIL (422)
Creazione di un utente locale del caricatore per un cliente esistenteLOCAL_USER_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409)
Invito di un utente locale del caricatoreLOCAL_USER_ALREADY_EXISTS, INVITATION_EMAIL_IN_USE, TAGLESS_USER_PROTECTED (409); INVALID_EMAIL (422); INVITATION_RESEND_THROTTLED (429) quando si applica l'intervallo minimo tra le consegne
Annullamento dell'invito di un utente localeINVALID_EMAIL (422)
Aggiornamento/eliminazione di un utente localeTAGLESS_USER_PROTECTED (409)

Tutti gli esiti relativi a proprietà e risorse mancanti in queste famiglie, inclusa un’e-mail non registrata su POST /users, usano il corpo comune 404 RESOURCE_NOT_FOUND.

Risposte senza corpo e risposte riprodotte

Una risposta 204 riuscita non ha corpo. Questo vale per ogni eliminazione documentata che indica 204 empty. Una ripetizione idempotente completata imposta Idempotency-Replayed: true e usa lo stato e il corpo salvati; per 204, la risposta HTTP rimane senza corpo. L’API non restituisce mai un oggetto JSON di successo per un’operazione 204 documentata.