La création d’une mission est l’opération centrale de l’API Transport. Un seul appel POST /transports planifie un transport de véhicule, le rend visible côté convoyeurs, et déclenche l’événement webhook transport.created.
POST https://api.myexpressdriver.com/v1/transports
La mission créée porte le statut public scheduled : elle est planifiée et en attente d’attribution d’un convoyeur. Vous suivrez ensuite sa progression via les statuts assigned, in_transit, awaiting_documents, under_review puis completed.

Prérequis

Clé API

Une clé portant le scope transports:write, envoyée dans l’en-tête X-Api-Key: med_live_....

Adresses d'enlèvement et de livraison

Les champs pickup et delivery sont requis, avec au minimum une adresse.

Facturation

Le bloc billing est requis (raison sociale, e-mail, adresse).

Clé d'idempotence

Recommandée : un Idempotency-Key unique pour éviter toute double création.

Les champs du corps de la requête

Le corps est un objet JSON. Trois champs sont requis : pickup, delivery et billing. Tous les autres sont optionnels.

Champs racine

type
string
Type de transport. Valeurs usuelles : livraison, restitution, conciergerie. En l’absence de valeur, le transport est traité comme une livraison standard.
plateau
boolean
défaut:"false"
Indique un transport sur plateau (camion porte-véhicule) plutôt qu’en roulant. Impacte la tarification.
fuel_refunded
boolean
défaut:"false"
Indique que le carburant est remboursé au convoyeur sur cette mission.
wgarage
boolean
défaut:"false"
Véhicule circulant sous plaques W garage (immatriculation provisoire professionnelle).
options
string[]
Liste des clés d’options à appliquer à la mission (ex. lavage, plein de carburant). Les clés disponibles dépendent de la grille de votre groupe.
description
string
Note libre attachée à la mission (consignes particulières, référence interne).

car — le véhicule

car
object
Caractéristiques du véhicule transporté.
Dans le contrat OpenAPI, l’objet véhicule est nommé vehicle et accepte aussi type, vin, brand et model. car est l’alias documenté côté guide ; les deux pointent vers le même objet véhicule. Préférez vehicle si vous générez votre client directement depuis l’OpenAPI.

pickup — point d’enlèvement

pickup
object
requis
Lieu, créneau et contact pour l’enlèvement du véhicule.

delivery — point de livraison

delivery
object
requis
Lieu, créneau et contact pour la livraison du véhicule. Mêmes propriétés que pickup.

billing — facturation

billing
object
requis
Informations de facturation simplifiées de la mission.

return_trip — aller-retour

return_trip
boolean | object
Décrit la jambe retour d’un transport aller-retour. Omettez ce champ (ou passez false) pour un aller simple.
Le retour n’a pas d’adresse de départ à renseigner. Il part automatiquement du lieu de livraison de l’aller (le convoyeur repart de là où il vient de livrer). Vous ne précisez donc que la destination du retour via return_trip.delivery — jamais un point de départ.

Exemple — aller simple

curl -s -X POST "https://api.myexpressdriver.com/v1/transports" \
  -H "X-Api-Key: med_live_a1b2c3d4e5f6" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "type": "livraison",
    "plateau": false,
    "fuel_refunded": false,
    "wgarage": false,
    "car": {
      "registration": "AB-123-CD",
      "electric": false
    },
    "pickup": {
      "need_appointment": false,
      "date": "2026-07-01",
      "start_time": "08:00",
      "end_time": "12:00",
      "address": "10 Rue de Rivoli, 75004 Paris",
      "contact": {
        "name": "Jean Dupont",
        "phone": "+33600000000",
        "mail": "jean.dupont@garage-demo.fr"
      }
    },
    "delivery": {
      "need_appointment": true,
      "date": "2026-07-01",
      "start_time": "14:00",
      "end_time": "18:00",
      "address": "1 Place Bellecour, 69002 Lyon",
      "contact": {
        "name": "Marie Martin",
        "phone": "+33611111111",
        "mail": "marie.martin@concession-lyon.fr"
      }
    },
    "billing": {
      "company_name": "Garage Demo SARL",
      "address": "5 Avenue des Champs, 75008 Paris",
      "email": "compta@garage-demo.fr",
      "siret": "12345678901234"
    },
    "options": []
  }'

Exemple — aller-retour

Pour un aller-retour, ajoutez le bloc return_trip avec le véhicule et le point de livraison du retour.
curl -s -X POST "https://api.myexpressdriver.com/v1/transports" \
  -H "X-Api-Key: med_live_a1b2c3d4e5f6" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "type": "restitution",
    "plateau": false,
    "car": {
      "registration": "AB-123-CD",
      "electric": true
    },
    "pickup": {
      "need_appointment": false,
      "date": "2026-07-01",
      "start_time": "08:00",
      "end_time": "12:00",
      "address": "10 Rue de Rivoli, 75004 Paris",
      "contact": {
        "name": "Jean Dupont",
        "phone": "+33600000000",
        "mail": "jean.dupont@garage-demo.fr"
      }
    },
    "delivery": {
      "need_appointment": true,
      "date": "2026-07-01",
      "start_time": "14:00",
      "end_time": "18:00",
      "address": "1 Place Bellecour, 69002 Lyon",
      "contact": {
        "name": "Marie Martin",
        "phone": "+33611111111",
        "mail": "marie.martin@concession-lyon.fr"
      }
    },
    "billing": {
      "company_name": "Garage Demo SARL",
      "address": "5 Avenue des Champs, 75008 Paris",
      "email": "compta@garage-demo.fr",
      "siret": "12345678901234"
    },
    "options": [],
    "return_trip": {
      "car": {
        "registration": "AB-123-CD",
        "electric": true
      },
      "delivery": {
        "need_appointment": false,
        "date": "2026-07-03",
        "start_time": "09:00",
        "end_time": "13:00",
        "address": "10 Rue de Rivoli, 75004 Paris",
        "contact": {
          "name": "Jean Dupont",
          "phone": "+33600000000",
          "mail": "jean.dupont@garage-demo.fr"
        }
      }
    }
  }'

Réponse 201 Created

En cas de succès, l’API renvoie 201 avec l’identifiant de la mission, sa référence métier, son statut et le prix calculé.
{
  "id": "-O9xAbCdEf",
  "transport_id": "M-54321",
  "status": "scheduled",
  "price": {
    "amount_ht": 180.5,
    "currency": "EUR"
  },
  "pickup":   { "address": "10 Rue de Rivoli, 75004 Paris, France", "lat": 48.8557, "lng": 2.3589, "place_id": "ChIJ7Qq9bF9u5kcRYJSMaMOCCwQ" },
  "delivery": { "address": "Place Bellecour, 69002 Lyon, France",   "lat": 45.7578, "lng": 4.8320, "place_id": "ChIJ65aN5w7q9EcR_HhwT2N0gJg" },
  "return_trip": null
}
id
string
Identifiant technique de la mission (offer_id). À utiliser dans tous les appels ultérieurs : GET /transports/{id}, suivi GPS, documents, etc.
transport_id
string
Référence métier lisible de la mission (ex. M-54321).
status
string
Statut public de la mission. À la création, vaut toujours scheduled.
price
object | null
Tarif calculé pour la mission. Le montant exposé est le HT facturé (amount_ht), dans la devise currency (EUR).
pickup
object
Adresse d’enlèvement résolue (géocodée) effectivement enregistrée : address normalisée, lat, lng, place_id. Contrôlez-la pour vérifier que le point retenu est bien celui visé.
delivery
object
Adresse de livraison résolue, même structure que pickup.
return_trip
object | null
Pour un aller-retour : adresses résolues pickup (= livraison de l’aller) et delivery (destination du retour). null sur un aller simple.
Conservez l’id renvoyé : c’est lui qui identifie la mission pour le suivi, la modification des dates, les options et l’annulation.

Idempotence

La création de mission est l’opération la plus sensible aux doublons : un appel qui échoue côté réseau peut avoir réussi côté serveur. Pour vous protéger, envoyez systématiquement un en-tête Idempotency-Key (par exemple un UUID v4 que vous générez).
Idempotency-Key: 1f3c2b7a-9d4e-4a1b-8c2f-0e6d5a4b3c2d
Exécutée normalement. La réponse est mise en cache et associée à la clé.
La réponse en cache est rejouée à l’identique, avec l’en-tête Idempotent-Replayed: true. Une seule mission est créée.
L’API renvoie 409 Conflict : la clé a déjà servi pour une requête différente.
Les réponses 5xx ne sont pas mises en cache : le verrou est libéré, vous pouvez réessayer en toute sécurité avec la même clé.
Utilisez une clé d’idempotence distincte par mission à créer. Les clés sont conservées 24 h.

Erreurs

Les erreurs suivent la RFC 9457 (Content-Type: application/problem+json).
CodeCauseÀ faire
401Clé API manquante, invalide ou révoquéeVérifier l’en-tête X-Api-Key.
403Scope transports:write absentDemander une clé avec le bon scope.
409Idempotency-Key réutilisée (corps ≠)Utiliser une nouvelle clé ou renvoyer le même corps.
422Validation : champ requis manquantLire le tableau errors[] du corps.
429Limite de débit atteinteBack-off et respecter l’en-tête Retry-After.
502Échec d’un service amont (création/tarif)Réessayer (l’idempotence rend la reprise sûre).
Exemple de 422 lorsqu’un champ requis manque :
{
  "type": "about:blank",
  "title": "Unprocessable Entity",
  "status": 422,
  "detail": "billing is required.",
  "errors": [
    { "field": "billing", "error": "required" }
  ]
}
Branchez votre logique sur status (et title), pas sur le texte de detail, qui peut évoluer.

Étapes suivantes

Suivre une mission

Récupérer le détail, les positions GPS et l’ETA du convoyeur.

Modifier les dates

Ajuster les créneaux d’enlèvement et de livraison, par jambe.

Recevoir les événements

S’abonner aux webhooks signés (transport.created, transport.status_changed…).