Passa al contenuto principale

Problemi API

Errori e soluzioni per le integrazioni che utilizzano l'API REST di DPD Label Print.

note

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:

VerificaAtteso
Nome intestazioneAuthorization (con A maiuscola)
Prefisso del valoreBearer (con uno spazio dopo Bearer)
Origine del tokenCampo token dalla risposta di /api/v1/login
Token non scadutoVerificare expireAt via /api/v1/login-extended
Nessun carattere extraRimuovere 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?

  1. Verificare di chiamare l'URL dell'ambiente corretto (dev, staging o produzione)
  2. Verificare che il proprio account sia attivo — contattare il supporto DPD
  3. 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 NL
  • stateCode è 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:

FormatoValoreCaso 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:

  1. Provare a fornire sia zipCode sia city — l'API ricade sul codice postale se l'indirizzo completo non può essere geocodificato
  2. Rimuovere i filtri di servizio/tipo per ampliare la ricerca
  3. Impostare hideClosed: false per 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:

  1. Verificare il numero di pacco dalla risposta di creazione della spedizione (success[].parcelNumber)
  2. Attendere qualche minuto dopo la creazione della spedizione affinché il tracciamento diventi disponibile
  3. 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.