Errori
Envelope di errore, mappa degli status HTTP, catalogo completo dei codici e uso del traceId con il supporto.
Tutte le risposte di errore delle API di Blu Pantheon condividono lo stesso formato, indipendentemente
dal servizio e dallo status HTTP. Il campo code è l'unico valore su cui basare la logica applicativa:
title e message sono destinati alle persone e possono cambiare senza preavviso.
Envelope di errore
{
"code": "INVALID_CREDENTIALS",
"title": "Credenziali non valide",
"message": "Email o password non corretti. Dopo 5 tentativi falliti l'account viene bloccato temporaneamente.",
"traceId": "01J8ZQ3K5V6X7Y8Z9A0B1C2D3E",
"details": []
}Campi dell'envelope
| Parametro | Tipo | Obblig. | Default | Descrizione |
|---|---|---|---|---|
code | string | Sì | — | Codice stabile in MAIUSCOLO_CON_UNDERSCORE. È il solo campo su cui costruire logica applicativa e messaggi tradotti lato client. |
title | string | Sì | — | Titolo breve leggibile, adatto a essere mostrato come intestazione di un avviso. Localizzato in base all’header Accept-Language. |
message | string | Sì | — | Descrizione estesa del problema e, quando possibile, dell’azione correttiva. Non parsarla: il testo può cambiare. |
traceId | string | Sì | — | Identificativo univoco della richiesta in formato ULID. Da citare sempre nelle segnalazioni al supporto. |
details | object[] | No | [] | Elenco di errori puntuali. Valorizzato soprattutto per gli errori di validazione e di permessi mancanti. |
details[].field | string | No | — | Percorso del campo che ha causato l’errore, con notazione a punti per gli oggetti annidati. |
details[].code | string | No | — | Codice specifico della singola violazione, ad esempio REQUIRED o TOO_SHORT. |
details[].message | string | No | — | Descrizione della singola violazione, adatta a essere mostrata accanto al campo di un modulo. |
Non basare la logica sui messaggi
Controllare message con confronti di stringa rende l'integrazione fragile: i testi sono localizzati e
vengono riformulati nel tempo. Usa sempre code e, per la validazione, details[].code.
Mappa degli status HTTP
| Status | Significato | Ritentabile |
|---|---|---|
400 Bad Request | Richiesta malformata o parametri non validi | No, correggi la richiesta |
401 Unauthorized | Credenziale assente, scaduta o non valida | Dopo aver rinnovato la credenziale |
402 Payment Required | Abbonamento sospeso o pagamento non riuscito | Dopo la regolarizzazione |
403 Forbidden | Credenziale valida ma priva dei permessi necessari | No, servono permessi diversi |
404 Not Found | Risorsa inesistente o non visibile al tenant corrente | No |
405 Method Not Allowed | Metodo HTTP non supportato sul path | No |
409 Conflict | Conflitto con lo stato attuale della risorsa | Solo dopo aver risolto il conflitto |
410 Gone | Endpoint dismesso dopo la data indicata in Sunset | No, migra alla nuova versione |
413 Payload Too Large | Body o file oltre la dimensione massima consentita | No |
415 Unsupported Media Type | Content-Type non supportato | No |
422 Unprocessable Entity | Sintassi corretta ma regola di business violata | No |
423 Locked | Risorsa o account temporaneamente bloccato | Dopo la scadenza del blocco |
429 Too Many Requests | Limite di chiamate superato | Sì, rispettando Retry-After |
500 Internal Server Error | Errore non previsto lato piattaforma | Sì, con backoff |
502 Bad Gateway | Errore di un servizio a monte | Sì, con backoff |
503 Service Unavailable | Servizio temporaneamente non disponibile o in manutenzione | Sì, con backoff |
504 Gateway Timeout | Timeout di un servizio a monte | Sì, con backoff, verificando prima l'idempotenza |
Catalogo dei codici
Autenticazione
| Codice | Status | Significato | Rimedio |
|---|---|---|---|
INVALID_CREDENTIALS | 401 | Email o password non corretti | Verifica le credenziali; non distinguere il motivo nell'interfaccia |
TOKEN_EXPIRED | 401 | Access token scaduto | Esegui il refresh e ritenta una sola volta |
TOKEN_INVALID | 401 | Token malformato o firma non verificabile | Rifai il login; controlla di non troncare il token |
REFRESH_TOKEN_REUSED | 401 | Refresh token già utilizzato | Tutte le sessioni sono state revocate: richiedi un nuovo login |
MISSING_AUTHORIZATION_HEADER | 401 | Header Authorization assente | Aggiungi l'header; verifica i redirect del client HTTP |
INVALID_TOKEN_FORMAT | 401 | Valore non nel formato Bearer <token> | Applica un trim e rimuovi prefissi duplicati |
MFA_REQUIRED | 401 | Autenticazione a più fattori necessaria | Completa la sfida su /auth/mfa/verify |
MFA_CODE_INVALID | 401 | Codice a più fattori errato | Richiedi un nuovo codice; attenzione al drift dell'orologio TOTP |
MFA_TOKEN_EXPIRED | 401 | mfaToken scaduto dopo 5 minuti | Ripeti il login dall'inizio |
ACCOUNT_LOCKED | 423 | Account bloccato per troppi tentativi falliti | Attendi la scadenza del blocco o contatta un amministratore |
ACCOUNT_DISABLED | 403 | Utente disattivato dall'amministratore | Richiedi la riattivazione |
API_KEY_REVOKED | 401 | Chiave API revocata | Genera una nuova chiave e aggiorna il secret manager |
API_KEY_EXPIRED | 401 | Chiave API a termine scaduta | Genera una nuova chiave |
SIGNATURE_MISMATCH | 401 | Firma HMAC non corrispondente | Verifica stringa canonica, body non riserializzato e segreto |
TIMESTAMP_SKEW | 401 | Timestamp fuori dalla tolleranza di 300 secondi | Sincronizza l'orologio del server via NTP |
TENANT_SELECTION_REQUIRED | 409 | L'utente appartiene a più tenant | Ripeti il login indicando tenantSlug |
Autorizzazione
| Codice | Status | Significato | Rimedio |
|---|---|---|---|
FORBIDDEN | 403 | Operazione non consentita nel contesto corrente | Verifica ruolo e ambito della credenziale |
INSUFFICIENT_PERMISSIONS | 403 | Mancano permessi specifici | Aggiungi gli scope elencati in details al ruolo o alla chiave |
TENANT_MISMATCH | 403 | La risorsa appartiene a un altro tenant | Usa una credenziale del tenant corretto |
SCOPE_NOT_GRANTED | 403 | Lo scope richiesto non è stato assegnato alla chiave API | Rigenera la chiave con gli scope necessari |
IP_NOT_ALLOWED | 403 | Indirizzo IP fuori dalla allowlist del tenant | Aggiungi l'IP di uscita nella configurazione di sicurezza |
Validazione
| Codice | Status | Significato | Rimedio |
|---|---|---|---|
VALIDATION_ERROR | 400 | Uno o più campi non superano la validazione | Correggi i campi elencati in details |
INVALID_EMAIL | 400 | Formato dell'indirizzo email non valido | Normalizza e valida l'indirizzo prima dell'invio |
INVALID_PHONE_NUMBER | 400 | Numero di telefono non valido in formato E.164 | Usa il formato internazionale con prefisso |
PASSWORD_TOO_WEAK | 400 | Password non conforme ai criteri del tenant | Applica i requisiti minimi indicati in details |
INVALID_CURSOR | 400 | Cursore scaduto, malformato o incoerente con i filtri | Riparti dalla prima pagina |
INVALID_DATE_RANGE | 400 | Intervallo temporale incoerente o troppo ampio | Riduci la finestra richiesta |
UNSUPPORTED_FILE_TYPE | 415 | Tipo di file non ammesso per l'upload | Converti il file in un formato supportato |
FILE_TOO_LARGE | 413 | File oltre la dimensione massima | Riduci o suddividi il file |
MISSING_REQUIRED_FIELD | 400 | Campo obbligatorio assente dal body | Aggiungi il campo indicato in details |
Risorse
| Codice | Status | Significato | Rimedio |
|---|---|---|---|
USER_NOT_FOUND | 404 | Utente inesistente o non visibile | Verifica l'identificativo e il tenant della credenziale |
TENANT_NOT_FOUND | 404 | Tenant inesistente | Verifica lo slug o l'identificativo |
PROJECT_NOT_FOUND | 404 | Progetto inesistente | Verifica projectId |
SESSION_NOT_FOUND | 404 | Sessione inesistente o già archiviata | Verifica l'identificativo e la finestra di conservazione |
CLIENT_NOT_FOUND | 404 | Cliente inesistente | Verifica clientId |
DATA_STORE_NOT_FOUND | 404 | Knowledge base inesistente | Verifica storeId |
DOCUMENT_NOT_FOUND | 404 | Documento inesistente o eliminato | Ricarica l'elenco dei documenti |
BOOKING_NOT_FOUND | 404 | Prenotazione inesistente o annullata | Verifica bookingId |
INVOICE_NOT_FOUND | 404 | Fattura inesistente | Verifica l'identificativo del documento |
API_KEY_NOT_FOUND | 404 | Chiave API inesistente | Ricarica l'elenco delle chiavi dalla Console |
Conflitti e stato
| Codice | Status | Significato | Rimedio |
|---|---|---|---|
EMAIL_ALREADY_EXISTS | 409 | Esiste già un utente con quell'email nel tenant | Recupera l'utente esistente o usa un altro indirizzo |
DUPLICATE_REQUEST | 409 | Idempotency-Key già usata con un body diverso | Genera una nuova chiave per una richiesta diversa |
RESOURCE_CONFLICT | 409 | Modifica concorrente sulla stessa risorsa | Rileggi la risorsa e ritenta l'operazione |
SESSION_ALREADY_CLOSED | 409 | La sessione è già stata chiusa | Nessuna azione necessaria |
BOOKING_SLOT_UNAVAILABLE | 409 | Lo slot è stato occupato nel frattempo | Rileggi la disponibilità e proponi un nuovo orario |
INVALID_STATE_TRANSITION | 422 | Transizione di stato non ammessa | Verifica lo stato corrente prima dell'operazione |
HANDOVER_ALREADY_ACTIVE | 409 | Un passaggio a operatore è già in corso | Riprendi la conversazione esistente |
Limiti e quote
| Codice | Status | Significato | Rimedio |
|---|---|---|---|
RATE_LIMITED | 429 | Limite di chiamate superato | Attendi i secondi indicati in Retry-After |
QUOTA_EXCEEDED | 429 | Quota mensile del piano esaurita | Attendi il rinnovo del ciclo o aumenta il piano |
PLAN_LIMIT_REACHED | 403 | Limite strutturale del piano raggiunto (utenti, progetti, storage) | Aggiorna il piano o libera risorse |
CONCURRENCY_LIMIT | 429 | Troppe richieste contemporanee dalla stessa credenziale | Riduci il parallelismo |
STORAGE_LIMIT_REACHED | 403 | Spazio della knowledge base esaurito | Elimina documenti o aumenta lo spazio |
Fatturazione
| Codice | Status | Significato | Rimedio |
|---|---|---|---|
PAYMENT_REQUIRED | 402 | Pagamento non riuscito, servizio limitato | Aggiorna il metodo di pagamento nella Console |
SUBSCRIPTION_INACTIVE | 402 | Abbonamento sospeso, scaduto o annullato | Riattiva l'abbonamento |
TRIAL_EXPIRED | 402 | Periodo di prova terminato | Attiva un piano a pagamento |
INVALID_BILLING_PROFILE | 422 | Dati di fatturazione incompleti o non validi | Completa partita IVA, codice SDI o PEC |
PAYMENT_METHOD_DECLINED | 402 | Metodo di pagamento rifiutato dall'emittente | Usa un altro metodo di pagamento |
Sistema
| Codice | Status | Significato | Rimedio |
|---|---|---|---|
INTERNAL_ERROR | 500 | Errore non previsto lato piattaforma | Ritenta con backoff; se persiste segnala il traceId |
SERVICE_UNAVAILABLE | 503 | Servizio temporaneamente non disponibile | Ritenta con backoff; se persiste apri una richiesta |
UPSTREAM_TIMEOUT | 504 | Timeout di un servizio a monte | Ritenta con backoff verificando l'idempotenza |
MAINTENANCE_MODE | 503 | Manutenzione pianificata in corso | Attendi la fine della finestra comunicata |
ENDPOINT_REMOVED | 410 | Endpoint dismesso | Migra alla versione indicata nella documentazione |
FEATURE_NOT_ENABLED | 403 | Funzionalità non abilitata per il tenant | Richiedi l'attivazione al tuo referente commerciale |
Il catalogo esteso con le note operative per gli amministratori è disponibile in Codici di errore.
Errori di validazione
Quando code vale VALIDATION_ERROR, l'array details contiene una voce per ogni campo non valido.
È il formato pensato per essere mappato direttamente sui campi di un modulo.
{
"code": "VALIDATION_ERROR",
"title": "Dati non validi",
"message": "La richiesta contiene 3 campi non validi.",
"traceId": "01J8ZQ3K5V6X7Y8Z9A0B1C2D3E",
"details": [
{
"field": "email",
"code": "INVALID_FORMAT",
"message": "Indirizzo email non valido."
},
{
"field": "password",
"code": "TOO_SHORT",
"message": "La password deve contenere almeno 12 caratteri."
},
{
"field": "profile.phoneNumber",
"code": "INVALID_FORMAT",
"message": "Il numero deve essere in formato E.164, ad esempio +390212345678."
}
]
}Gestione lato client:
interface ApiError {
code: string;
title: string;
message: string;
traceId: string;
details?: { field?: string; code?: string; message?: string }[];
}
export function toFieldErrors(error: ApiError): Record<string, string> {
if (error.code !== 'VALIDATION_ERROR') return {};
return Object.fromEntries(
(error.details ?? [])
.filter((d) => Boolean(d.field))
.map((d) => [d.field as string, d.message ?? 'Valore non valido']),
);
}Codici di dettaglio ricorrenti
I valori più frequenti di details[].code sono REQUIRED, INVALID_FORMAT, TOO_SHORT, TOO_LONG,
OUT_OF_RANGE, NOT_UNIQUE e UNSUPPORTED_VALUE. Sono stabili e possono essere usati per generare
messaggi tradotti nella lingua della tua applicazione.
Il traceId
Ogni richiesta riceve un traceId in formato ULID, presente sia nell'envelope di errore sia
nell'header X-BP-Trace-Id di tutte le risposte, anche quelle di successo.
X-BP-Trace-Id: 01J8ZQ3K5V6X7Y8Z9A0B1C2D3ERegistralo sempre
Includi il traceId in ogni riga di log relativa a una chiamata API, sia in caso di successo sia in
caso di errore. Senza di esso una segnalazione richiede molto più tempo per essere analizzata.
Non mostrarlo ai clienti finali
Il traceId è un dato di diagnostica destinato agli sviluppatori. In un'interfaccia rivolta agli utenti
finali mostra un messaggio comprensibile e riporta il codice solo in un'area tecnica o in un tooltip.
Citalo nelle segnalazioni
Quando apri una richiesta al supporto indica: traceId, code, timestamp UTC della chiamata, metodo e
path, ambiente e identificativo della credenziale usata (solo il prefisso, mai il segreto).
Non inviare mai credenziali al supporto
Nelle segnalazioni non allegare chiavi API complete, token, password o segreti HMAC. Il prefisso della
chiave (bp_live_xxxx) e il traceId sono sufficienti per identificare la richiesta.
Il traceId viene conservato nei log della piattaforma per 30 giorni: segnala gli incidenti entro
questa finestra per consentire l'analisi puntuale della richiesta.