Chaque mission de transport produit des documents : procès-verbaux (PV) d’inspection au départ et à l’arrivée, PV signé, bons de livraison, factures. Ce guide explique comment les lister, suivre leur statut de validation, repérer ceux qui doivent encore être signés, et joindre vos propres pièces.
Seuls les documents à visibilité client sont exposés par l’API. Les documents internes (pièces convoyeur, justificatifs RH, etc.) ne sont jamais renvoyés, quel que soit votre scope.
Tous les endpoints de ce guide sont scopés au groupe de votre clé API. Une mission qui n’appartient pas à votre groupe renvoie 404 (jamais 403). Les requêtes GET exigent le scope transports:read ; l’ajout de documents (POST) exige transports:write.

Lister les documents d’une mission

GET /transports/{id}/documents
Renvoie la liste des documents visibles client de la mission. Chaque entrée décrit un document (PV, bon, facture…) avec son lien de téléchargement et son statut de validation.
id
string
requis
Identifiant de la mission (offer_id).
is_retour
boolean
Filtre les documents rattachés à la jambe retour de la mission (aller-retour). Omettez ce paramètre pour récupérer tous les documents.
curl -s "https://api.myexpressdriver.com/v1/transports/-O9xAbCdEf/documents" \
  -H "X-Api-Key: med_live_xxxxxxxxxxxxxxxxxxxx"
Réponse 200
{
  "data": [
    {
      "key": "PV_DEPART",
      "label": "PV d'inspection au départ",
      "url": "https://storage.myexpressdriver.com/docs/...pv-depart.pdf",
      "status": "accepted",
      "is_retour": false,
      "file_name": "pv-depart.pdf",
      "created_at": "2026-07-01T08:42:00Z"
    },
    {
      "key": "PV_ARRIVEE_SIGNE",
      "label": "PV d'inspection à l'arrivée (signé)",
      "url": "https://storage.myexpressdriver.com/docs/...pv-arrivee-signe.pdf",
      "status": "waiting",
      "is_retour": false,
      "file_name": "pv-arrivee-signe.pdf",
      "created_at": "2026-07-01T18:10:00Z"
    }
  ]
}

Champs d’un document

key
string | null
Clé technique stable du document (document_key). Utilisez-la pour identifier un type de document (PV de départ, PV signé, bon, facture…) plutôt que le label, qui est un libellé d’affichage.
label
string | null
Libellé lisible du document, destiné à l’affichage.
url
string | null
Lien de téléchargement du fichier (PDF généralement). Peut être null tant que le document n’a pas encore été produit.
status
string | null
Statut de validation du document. Voir le tableau ci-dessous.
is_retour
boolean
true si le document concerne la jambe retour de la mission.
file_name
string | null
Nom de fichier d’origine.
created_at
string | null
Date de dépôt du document (ISO 8601).

Statuts d’un document

statusSens
waitingDocument en attente de validation (déposé, pas encore vérifié).
acceptedDocument validé.
refusedDocument refusé — le motif de refus n’est pas exposé par l’API.
nullStatut non applicable (document informatif, sans cycle de validation).
Branchez votre logique métier sur key et status, pas sur label. Le label est un texte d’affichage susceptible d’évoluer, tandis que key et status sont des valeurs stables.

Documents à signer

GET /transports/{id}/signable-documents
Renvoie uniquement les documents qui nécessitent une signature (typiquement les PV à faire contresigner). Utile pour piloter un rappel ou un flux de signature côté client.
id
string
requis
Identifiant de la mission (offer_id).
curl -s "https://api.myexpressdriver.com/v1/transports/-O9xAbCdEf/signable-documents" \
  -H "X-Api-Key: med_live_xxxxxxxxxxxxxxxxxxxx"
Réponse 200
{
  "data": [
    {
      "key": "PV_ARRIVEE",
      "label": "PV d'inspection à l'arrivée",
      "url": "https://storage.myexpressdriver.com/docs/...pv-arrivee.pdf",
      "status": "waiting",
      "is_retour": false,
      "file_name": "pv-arrivee.pdf",
      "created_at": "2026-07-01T18:05:00Z"
    }
  ]
}
La structure de chaque entrée est identique à celle de GET /transports/{id}/documents (voir Champs d’un document). Cet endpoint applique simplement un filtre supplémentaire sur les documents qui attendent une signature.

Récupérer le PV signé

Le PV signé est exposé comme tout autre document, via GET /transports/{id}/documents. Pour le récupérer :
1

Listez les documents de la mission

Appelez GET /transports/{id}/documents et repérez l’entrée dont la key correspond au PV signé.
2

Vérifiez le statut

Attendez que status vaille accepted pour être sûr que le PV signé est finalisé et validé.
3

Téléchargez le fichier

Suivez l’url de l’entrée pour récupérer le PDF.
Node.js
const res = await fetch(
  "https://api.myexpressdriver.com/v1/transports/-O9xAbCdEf/documents",
  { headers: { "X-Api-Key": process.env.MED_API_KEY } }
);
const { data } = await res.json();

// On cible le PV signé qui a été validé.
const pvSigne = data.find(
  (doc) => doc.key === "PV_ARRIVEE_SIGNE" && doc.status === "accepted"
);

if (pvSigne?.url) {
  console.log("PV signé disponible :", pvSigne.url);
} else {
  console.log("PV signé pas encore validé.");
}
Plutôt que d’interroger l’endpoint en boucle (polling), abonnez-vous aux webhooks document.added et document.accepted. Vous serez notifié dès que le PV signé est déposé puis validé. Voir Vue d’ensemble des webhooks.

Joindre un document à une mission

POST /transports/{id}/documents
Attache un ou plusieurs documents à la mission. Chaque document est décrit par un name (libellé) et un link (URL HTTPS publiquement accessible depuis laquelle MED récupère le fichier).
id
string
requis
Identifiant de la mission (offer_id).
documents
array
requis
Tableau d’au moins un document. Chaque élément contient :
L’ajout de documents est une opération mutante : pensez à fournir un en-tête Idempotency-Key pour la rendre rejouable sans doublon. Voir Idempotence.
curl -s -X POST "https://api.myexpressdriver.com/v1/transports/-O9xAbCdEf/documents" \
  -H "X-Api-Key: med_live_xxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 7f3c2b7a-9d4e-4a1b-8c2f-0e6d5a4b3c2d" \
  -d '{
    "documents": [
      {
        "name": "Bon de commande client",
        "link": "https://files.exemple.fr/bons/bc-2026-0042.pdf"
      },
      {
        "name": "Mandat de transport",
        "link": "https://files.exemple.fr/mandats/mandat-0042.pdf"
      }
    ]
  }'

Réponse 207 Multi-Status

L’endpoint renvoie 207 Multi-Status : chaque document est traité indépendamment, et la réponse détaille le résultat document par document. Un document peut échouer (lien injoignable, format invalide…) sans faire échouer les autres.
Réponse 207
{
  "data": [
    { "name": "Bon de commande client", "success": true, "error": null },
    {
      "name": "Mandat de transport",
      "success": false,
      "error": "Le lien n'a pas pu être téléchargé."
    }
  ]
}
data
array
Résultat par document, dans l’ordre de la requête.
Comme la réponse est un 207, le code HTTP ne reflète pas le succès de chaque document : inspectez toujours le champ success de chaque entrée du tableau data, et rejouez sélectivement les documents en échec.

Erreurs

Comme partout dans l’API, les erreurs suivent la RFC 9457 (application/problem+json).
CodeCause
401Clé API manquante, invalide, révoquée ou expirée.
403Scope requis absent (transports:read pour lire, transports:write pour ajouter).
404Mission introuvable ou hors du groupe de votre clé.
422Corps invalide (ex. documents vide, link non HTTPS).
502Échec d’un service amont lors de l’attachement.
Exemple 422
{
  "type": "about:blank",
  "title": "Unprocessable Entity",
  "status": 422,
  "detail": "documents must contain at least one item.",
  "errors": [{ "field": "documents", "error": "min_items" }]
}

Étapes suivantes

Suivi en temps réel

Positions GPS du convoyeur et étapes planifiées avec ETA.

Webhooks

Recevez document.added, document.accepted et document.rejected en temps réel.