Problèmes d'API
Erreurs et solutions pour les intégrations utilisant l'API REST DPD Label Print.
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érification | Attendu |
|---|---|
| Nom de l'en-tête | Authorization (avec A majuscule) |
| Préfixe de la valeur | Bearer (avec un espace après Bearer) |
| Source du jeton | Champ 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émentaires | Supprimer 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 ?
- Vérifiez que vous appelez la bonne URL d'environnement (dev, staging ou production)
- Vérifiez que votre compte est actif — contactez le support DPD
- 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 :
emailest requis pour toutes les destinations hors CH/LI (sauf GB)phoneest requis pour les destinations GB (format international :+44...)houseNumberest requis pour les destinations NLstateCodeest 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 :
| Format | Valeur | Cas 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 :
- Essayez de fournir à la fois
zipCodeetcity— l'API se rabat sur le code postal si l'adresse complète ne peut pas être géocodée - Supprimez les filtres de service ou de type pour élargir la recherche
- Définissez
hideClosed: falsepour 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 :
- Vérifiez le numéro de colis dans la réponse de création d'expédition (
success[].parcelNumber) - Attendez quelques minutes après la création de l'expédition pour que le suivi devienne disponible
- 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.