Aller au contenu principal

Problèmes d'API

Erreurs et solutions pour les intégrations utilisant l'API REST DPD Label Print.

remarque

Si vous utilisez Online Label Print ou l'application Label Print plutôt que l'API, consultez Login Issues, File Import Issues ou Printer Issues.


Authentification

HTTP 401 Unauthorized

{
"status": 401,
"error": "Unauthorized",
"message": "JWT token is missing or invalid"
}

Liste de contrôle :

VérificationAttendu
Nom de l'en-têteAuthorization (avec A majuscule)
Préfixe de la valeurBearer (avec un espace après Bearer)
Source du jetonChamp token de la réponse de /api/v1/login
Jeton non expiréVérifier expireAt via /api/v1/login-extended
Pas de caractères supplémentairesSupprimer les espaces avant/après le jeton

HTTP 401 — Jeton expiré

Les jetons ont une durée de vie (TTL) limitée configurée sur le serveur. Une fois expirés, chaque requête retourne 401.

Solution : Se reconnecter :

curl -X POST "https://label-print-shipments.dpd.ch/api/v1/login" \
-H "Content-Type: application/json" \
-d '{"username": "votre_utilisateur", "password": "votre_mdp"}'

Prévention — renouveler proactivement avant expiration :

// Enregistrer la date d'expiration depuis /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;
}

Le jeton expire trop vite

Cause : La durée de vie (TTL) du jeton est configurée côté serveur.

Solution : Contactez votre responsable de compte DPD pour ajuster la durée de vie (TTL) du jeton pour votre compte. En attendant, mettez en place une logique de renouvellement qui se reconnecte avant l'expiration.


HTTP 400 — Nom d'utilisateur ou mot de passe manquant

{
"status": 400,
"errors": [{ "field": "username", "message": "must not be blank" }]
}

Solution : Assurez-vous que les champs username et password sont tous deux présents et non vides dans le corps de la requête.


HTTP 403 — Forbidden (login-extended)

{
"status": 403,
"message": "Auto-login context is missing"
}

Cause : /api/v1/login-extended nécessite un contexte de connexion automatique qui n'est pas configuré pour votre compte.

Solution : Utilisez /api/v1/login à la place, ou contactez votre responsable de compte DPD pour activer la connexion étendue pour votre compte.


Identifiants corrects mais toujours 401 ?

  1. Vérifiez que vous appelez la bonne URL d'environnement (dev, staging ou production)
  2. Vérifiez que votre compte est actif — contactez le support DPD
  3. Vérifiez si votre adresse IP doit être autorisée (liste blanche) pour l'accès API

Expéditions

400 Bad Request — erreur de validation

Cause : Un champ obligatoire est absent ou échoue à la validation.

Solution : Vérifiez le tableau fieldErrors dans la réponse — c'est une liste plate, une entrée par violation, chacune avec son propre path, code et message (le même code peut apparaître à plusieurs path, p. ex. à la fois sender.email et 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." }
]
}

Exigences courantes par champ :

  • email est requis pour toutes les destinations hors CH/LI (sauf GB)
  • phone est requis pour les destinations GB (format international : +44...)
  • houseNumber est requis pour les destinations NL
  • stateCode est requis pour les destinations US/CA

207 Multi-Status — échec partiel d'un lot

Cause : Dans une requête par lot, certaines expéditions ont réussi et d'autres ont échoué.

Solution : Vérifiez le tableau failed dans la réponse pour obtenir les fieldErrors de chaque élément. Utilisez l'identificationNumber de chaque entrée (reprend la valeur fournie par le client, lorsque l'élément d'entrée en avait une) pour relier un échec à l'élément d'entrée. Le tableau success contient les expéditions créées avec leurs numéros de colis et leurs étiquettes. Si en revanche tous les éléments ont échoué, la réponse est toujours 400 Bad Request — quelle que soit la cause, y compris une panne du moteur de routage, qui reste signalée par élément via errorCode: SHP-ROUTING-ENGINE-UNAVAILABLE.


Étiquettes

Étiquettes dans la réponse API

Une création d'expédition réussie retourne chaque étiquette sous forme de chaîne PDF encodée en Base64 dans success[].label.

{
"success": [
{
"id": 1,
"parcelNumber": "05305000123456",
"label": "JVBERi0xLjQKJeLjz9MK..."
}
]
}

Décoder et enregistrer l'étiquette

Shell :

echo "JVBERi0xLjQK..." | base64 --decode > label.pdf

JavaScript (navigateur) :

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);

Choisir le bon format d'étiquette

Définissez printOptions.paperSize dans votre requête d'expédition :

FormatValeurCas d'utilisation
A4"A4"Imprimantes de bureau standard. Jusqu'à 4 étiquettes par feuille — contrôlez la position avec startPosition (UPPER_LEFT, UPPER_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT)
Thermique / A6"A6"Imprimantes d'étiquettes thermiques directes (Zebra, Citizen, etc.)
"printOptions": {
"paperSize": "A6"
}

Plusieurs étiquettes sur une feuille A4

Lors de l'impression de plusieurs expéditions, regroupez-les sur des feuilles A4 pour économiser du papier :

[
{ ..., "printOptions": { "paperSize": "A4", "startPosition": "UPPER_LEFT" } },
{ ..., "printOptions": { "paperSize": "A4", "startPosition": "UPPER_RIGHT" } },
{ ..., "printOptions": { "paperSize": "A4", "startPosition": "BOTTOM_LEFT" } },
{ ..., "printOptions": { "paperSize": "A4", "startPosition": "BOTTOM_RIGHT" } }
]

Étiquette vide, blanche ou corrompue

Cause 1 : printOptions.paperSize ne correspond pas à votre imprimante.

Solution : Définissez paperSize explicitement — "A4" pour une feuille complète (avec startPosition), "A6" pour les imprimantes d'étiquettes thermiques.

Cause 2 : Erreur de décodage Base64 — espaces ou sauts de ligne superflus dans la chaîne.

Solution : Supprimez tous les espaces avant de décoder :

const cleanBase64 = base64String.replace(/\s+/g, '');

Cause 3 : Compatibilité du lecteur PDF.

Solution : Essayez d'ouvrir le PDF dans un autre lecteur. Les étiquettes sont des fichiers PDF 1.4+ valides.

Cause 4 : Incompatibilité de la résolution (DPI) de l'imprimante thermique.

Solution : Configurez votre imprimante à 203 ou 300 DPI (consultez le manuel de votre imprimante). Le format d'étiquette est conçu pour les imprimantes thermiques DPD standard.


Points de collecte

Résultats vides lors d'une recherche par adresse

Cause : Aucun point de collecte trouvé dans le rayon de recherche par défaut de 5 km, ou l'adresse n'a pas pu être résolue.

Solution :

  1. Essayez de fournir à la fois zipCode et city — l'API se rabat sur le code postal si l'adresse complète ne peut pas être géocodée
  2. Supprimez les filtres de service ou de type pour élargir la recherche
  3. Définissez hideClosed: false pour inclure les points de collecte temporairement fermés

404 Not Found pour un identifiant de point de collecte

Cause : L'identifiant du point de collecte n'existe pas ou n'est plus actif.

Solution : Relancez une recherche par adresse ou par coordonnées pour obtenir les identifiants de points de collecte actuels. Les identifiants de points de collecte peuvent changer lorsque des points ferment ou rouvrent.


Suivi

404 Not Found pour un numéro de colis

Cause : Les données de suivi ne sont pas encore disponibles ou le numéro de colis est incorrect.

Solution :

  1. Vérifiez le numéro de colis dans la réponse de création d'expédition (success[].parcelNumber)
  2. Attendez quelques minutes après la création de l'expédition pour que le suivi devienne disponible
  3. Vérifiez que le format du numéro de colis est correct (ex. 05305000123456)

Demandes d'enlèvement et ordres de collecte

pickupDate rejeté

Cause : La date est dans le passé ou mal formatée.

Solution : Utilisez le format yyyy-MM-dd et assurez-vous que la date correspond au minimum à demain dans le fuseau horaire européen.


Général

Erreurs HTTPS / SSL

Tous les appels API doivent utiliser HTTPS. Les certificats auto-signés ne sont pas acceptés en production.

Limitation de débit (429 Too Many Requests)

Mettez en place un repli exponentiel (exponential backoff) dans votre application. Envisagez de mettre en cache les données des points de collecte (qui changent rarement) afin de réduire le nombre d'appels API.