Problemi API
Errori e soluzioni per le integrazioni che utilizzano l'API REST di DPD Label Print.
Se utilizzate Online Label Print o l'app Label Print anziché l'API, consultate Login Issues, File Import Issues o Printer Issues.
Autenticazione
HTTP 401 Unauthorized
{
"status": 401,
"error": "Unauthorized",
"message": "JWT token is missing or invalid"
}
Lista di controllo:
| Verifica | Atteso |
|---|---|
| Nome intestazione | Authorization (con A maiuscola) |
| Prefisso del valore | Bearer (con uno spazio dopo Bearer) |
| Origine del token | Campo token dalla risposta di /api/v1/login |
| Token non scaduto | Verificare expireAt via /api/v1/login-extended |
| Nessun carattere extra | Rimuovere gli spazi prima/dopo la stringa del token |
HTTP 401 — Token scaduto
I token hanno un TTL finito configurato sul server. Una volta scaduti, ogni richiesta restituisce 401.
Soluzione: Effettuare nuovamente l'accesso:
curl -X POST "https://label-print-shipments.dpd.ch/api/v1/login" \
-H "Content-Type: application/json" \
-d '{"username": "your_user", "password": "your_pass"}'
Prevenzione — rinnovare proattivamente prima della scadenza:
// Store expiry time from /login-extended
const tokenExpiry = new Date(loginResponse.expireAt);
async function getValidToken() {
const fiveMinuteBuffer = 5 * 60 * 1000;
if (Date.now() > tokenExpiry.getTime() - fiveMinuteBuffer) {
await reAuthenticate();
}
return currentToken;
}
Il token scade troppo rapidamente
Causa: Il TTL del token è configurato lato server.
Soluzione: Contattare il proprio referente DPD per regolare il TTL del token per il proprio account. Nel frattempo, implementare una logica di rinnovo del token che effettui nuovamente l'accesso prima della scadenza.
HTTP 400 — Username o password mancante
{
"status": 400,
"errors": [{ "field": "username", "message": "must not be blank" }]
}
Soluzione: Assicurarsi che sia username sia password siano presenti e non vuoti nel corpo della richiesta.
HTTP 403 — Forbidden (login-extended)
{
"status": 403,
"message": "Auto-login context is missing"
}
Causa: /api/v1/login-extended richiede un contesto di accesso automatico che non è configurato per il vostro account.
Soluzione: Usare /api/v1/login al suo posto, oppure contattare il vostro referente DPD per abilitare l'accesso esteso per il vostro account.
Credenziali corrette ma ancora 401?
- Verificare di chiamare l'URL dell'ambiente corretto (dev, staging o produzione)
- Verificare che il proprio account sia attivo — contattare il supporto DPD
- Verificare se il proprio indirizzo IP deve essere autorizzato (whitelist) per l'accesso API
Spedizioni
400 Bad Request — errore di validazione
Causa: Un campo obbligatorio è assente o non supera la validazione.
Soluzione: Verificare l'array fieldErrors nella risposta — è un elenco piatto, una voce per violazione, ognuna con il proprio path, code e message (lo stesso code può comparire a più path, ad es. sia sender.email che receiver.email):
{
"fieldErrors": [
{ "path": "receiver.email", "code": "SHP-VAL-EMAIL-REQUIRED", "message": "Email address is required." },
{ "path": "receiver.countryCode", "code": "SHP-VAL-COUNTRYCODE-ALLOWED-CHARACTERS", "message": "Country code contains invalid characters." }
]
}
Requisiti comuni dei campi:
emailè obbligatorio per tutte le destinazioni non-CH/LI (eccetto GB)phoneè obbligatorio per le destinazioni GB (formato internazionale:+44...)houseNumberè obbligatorio per le destinazioni NLstateCodeè obbligatorio per le destinazioni US/CA
207 Multi-Status — fallimento parziale del batch
Causa: In una richiesta batch alcune spedizioni sono riuscite e altre sono fallite.
Soluzione: Verificare l'array failed nella risposta per i fieldErrors di ogni elemento. Usare l'identificationNumber di ogni voce (riprende il valore fornito dal client, quando l'elemento di input ne aveva uno) per ricollegare un errore all'elemento di input. L'array success contiene le spedizioni create con i relativi numeri di pacco ed etichette. Se invece tutti gli elementi sono falliti, la risposta è sempre 400 Bad Request — indipendentemente dalla causa, anche in caso di guasto del motore di instradamento, che viene comunque segnalato per singolo elemento tramite errorCode: SHP-ROUTING-ENGINE-UNAVAILABLE.
Etichette
Etichette nella risposta API
Una creazione di spedizione riuscita restituisce ogni etichetta come stringa PDF codificato in Base64 nel campo success[].label.
{
"success": [
{
"id": 1,
"parcelNumber": "05305000123456",
"label": "JVBERi0xLjQKJeLjz9MK..."
}
]
}
Decodificare e salvare l'etichetta
Shell:
echo "JVBERi0xLjQK..." | base64 --decode > label.pdf
JavaScript (browser):
function downloadLabel(base64Label, parcelNumber) {
const bytes = atob(base64Label);
const array = new Uint8Array(bytes.length);
for (let i = 0; i < bytes.length; i++) array[i] = bytes.charCodeAt(i);
const blob = new Blob([array], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `label-${parcelNumber}.pdf`;
a.click();
URL.revokeObjectURL(url);
}
Java:
byte[] pdfBytes = Base64.getDecoder().decode(labelBase64);
Files.write(Path.of("label-" + parcelNumber + ".pdf"), pdfBytes);
Scegliere il formato etichetta corretto
Impostare printOptions.paperSize nella richiesta di spedizione:
| Formato | Valore | Caso d'uso |
|---|---|---|
| A4 | "A4" | Stampanti da ufficio standard. Fino a 4 etichette per foglio — controllare la posizione con startPosition (UPPER_LEFT, UPPER_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT) |
| Termico / A6 | "A6" | Stampanti per etichette termiche dirette (Zebra, Citizen, ecc.) |
"printOptions": {
"paperSize": "A6"
}
Più etichette su un unico foglio A4
Quando si stampano più spedizioni, raggrupparle su fogli A4 per risparmiare carta:
[
{ ..., "printOptions": { "paperSize": "A4", "startPosition": "UPPER_LEFT" } },
{ ..., "printOptions": { "paperSize": "A4", "startPosition": "UPPER_RIGHT" } },
{ ..., "printOptions": { "paperSize": "A4", "startPosition": "BOTTOM_LEFT" } },
{ ..., "printOptions": { "paperSize": "A4", "startPosition": "BOTTOM_RIGHT" } }
]
Etichetta vuota, bianca o danneggiata
Causa 1: Discrepanza tra printOptions.paperSize e la vostra stampante.
Soluzione: Impostare paperSize esplicitamente — "A4" per il foglio intero (con startPosition), "A6" per le stampanti per etichette termiche.
Causa 2: Errore di decodifica Base64 — spazi o interruzioni di riga superflui nella stringa.
Soluzione: Rimuovere tutti gli spazi prima della decodifica:
const cleanBase64 = base64String.replace(/\s+/g, '');
Causa 3: Compatibilità del visualizzatore PDF.
Soluzione: Provare ad aprire il PDF in un altro visualizzatore. Le etichette sono file PDF 1.4+ validi.
Causa 4: DPI della stampante termica non compatibile.
Soluzione: Configurare la stampante a 203 o 300 DPI (consultare il manuale della stampante). Il formato dell'etichetta è progettato per le stampanti termiche DPD standard.
Punti di ritiro
Risultati vuoti nella ricerca per indirizzo
Causa: Nessun punto trovato entro il raggio di ricerca predefinito di 5 km, oppure l'indirizzo non è stato risolto.
Soluzione:
- Provare a fornire sia
zipCodesiacity— l'API ricade sul codice postale se l'indirizzo completo non può essere geocodificato - Rimuovere i filtri di servizio/tipo per ampliare la ricerca
- Impostare
hideClosed: falseper includere i punti eventualmente chiusi temporaneamente
404 Not Found per l'ID del punto di ritiro
Causa: L'ID del punto non esiste o non è più attivo.
Soluzione: Effettuare nuovamente la ricerca per indirizzo o coordinate per ottenere gli ID dei punti attuali. Gli ID dei punti di ritiro possono cambiare quando i punti chiudono o riaprono.
Tracciamento
404 Not Found per numero di pacco
Causa: I dati di tracciamento non sono ancora disponibili oppure il numero di pacco è errato.
Soluzione:
- Verificare il numero di pacco dalla risposta di creazione della spedizione (
success[].parcelNumber) - Attendere qualche minuto dopo la creazione della spedizione affinché il tracciamento diventi disponibile
- Verificare che il formato del numero di pacco sia corretto (es.
05305000123456)
Richieste di ritiro e ordini di ritiro
pickupDate rifiutato
Causa: La data è nel passato o è formattata in modo errato.
Soluzione: Usare il formato yyyy-MM-dd e assicurarsi che la data sia almeno quella di domani nel fuso orario europeo.
Generale
Errori HTTPS / SSL
Tutte le chiamate API devono usare HTTPS. I certificati autofirmati non sono accettati in produzione.
Limitazione delle richieste (429 Too Many Requests)
Implementare un backoff esponenziale nella propria applicazione. Considerare la memorizzazione nella cache dei dati dei punti di ritiro (che cambiano di rado) per ridurre le chiamate API.