curl --request POST \
--url https://sandbox.myexpressdriver.com/v1/transports/{id}/duplicate \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <api-key>' \
--data '
{
"dates": {
"enlevement-aller": {
"date": "2026-09-22",
"start_time": "08:00",
"end_time": "12:00"
},
"livraison-aller": {
"date": "2026-09-23",
"start_time": "14:00",
"end_time": "18:00"
}
},
"options": {
"aller": [
"PV papier - 10"
],
"retour": []
},
"documents": {
"copy": [
"3f1c9a2e-7b44-4c1d-9e0a-5d2b8c6f1a23"
]
}
}
'import requests
url = "https://sandbox.myexpressdriver.com/v1/transports/{id}/duplicate"
payload = {
"dates": {
"enlevement-aller": {
"date": "2026-09-22",
"start_time": "08:00",
"end_time": "12:00"
},
"livraison-aller": {
"date": "2026-09-23",
"start_time": "14:00",
"end_time": "18:00"
}
},
"options": {
"aller": ["PV papier - 10"],
"retour": []
},
"documents": { "copy": ["3f1c9a2e-7b44-4c1d-9e0a-5d2b8c6f1a23"] }
}
headers = {
"X-Api-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Api-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
dates: {
'enlevement-aller': {date: '2026-09-22', start_time: '08:00', end_time: '12:00'},
'livraison-aller': {date: '2026-09-23', start_time: '14:00', end_time: '18:00'}
},
options: {aller: ['PV papier - 10'], retour: []},
documents: {copy: ['3f1c9a2e-7b44-4c1d-9e0a-5d2b8c6f1a23']}
})
};
fetch('https://sandbox.myexpressdriver.com/v1/transports/{id}/duplicate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://sandbox.myexpressdriver.com/v1/transports/{id}/duplicate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'dates' => [
'enlevement-aller' => [
'date' => '2026-09-22',
'start_time' => '08:00',
'end_time' => '12:00'
],
'livraison-aller' => [
'date' => '2026-09-23',
'start_time' => '14:00',
'end_time' => '18:00'
]
],
'options' => [
'aller' => [
'PV papier - 10'
],
'retour' => [
]
],
'documents' => [
'copy' => [
'3f1c9a2e-7b44-4c1d-9e0a-5d2b8c6f1a23'
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Api-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://sandbox.myexpressdriver.com/v1/transports/{id}/duplicate"
payload := strings.NewReader("{\n \"dates\": {\n \"enlevement-aller\": {\n \"date\": \"2026-09-22\",\n \"start_time\": \"08:00\",\n \"end_time\": \"12:00\"\n },\n \"livraison-aller\": {\n \"date\": \"2026-09-23\",\n \"start_time\": \"14:00\",\n \"end_time\": \"18:00\"\n }\n },\n \"options\": {\n \"aller\": [\n \"PV papier - 10\"\n ],\n \"retour\": []\n },\n \"documents\": {\n \"copy\": [\n \"3f1c9a2e-7b44-4c1d-9e0a-5d2b8c6f1a23\"\n ]\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Api-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://sandbox.myexpressdriver.com/v1/transports/{id}/duplicate")
.header("X-Api-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"dates\": {\n \"enlevement-aller\": {\n \"date\": \"2026-09-22\",\n \"start_time\": \"08:00\",\n \"end_time\": \"12:00\"\n },\n \"livraison-aller\": {\n \"date\": \"2026-09-23\",\n \"start_time\": \"14:00\",\n \"end_time\": \"18:00\"\n }\n },\n \"options\": {\n \"aller\": [\n \"PV papier - 10\"\n ],\n \"retour\": []\n },\n \"documents\": {\n \"copy\": [\n \"3f1c9a2e-7b44-4c1d-9e0a-5d2b8c6f1a23\"\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sandbox.myexpressdriver.com/v1/transports/{id}/duplicate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Api-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"dates\": {\n \"enlevement-aller\": {\n \"date\": \"2026-09-22\",\n \"start_time\": \"08:00\",\n \"end_time\": \"12:00\"\n },\n \"livraison-aller\": {\n \"date\": \"2026-09-23\",\n \"start_time\": \"14:00\",\n \"end_time\": \"18:00\"\n }\n },\n \"options\": {\n \"aller\": [\n \"PV papier - 10\"\n ],\n \"retour\": []\n },\n \"documents\": {\n \"copy\": [\n \"3f1c9a2e-7b44-4c1d-9e0a-5d2b8c6f1a23\"\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"options": {
"aller": [
"<string>"
],
"retour": [
"<string>"
]
},
"transport_id": "M-58121",
"status": "scheduled",
"price": {
"amount_ht": 123,
"currency": "EUR",
"express": true
},
"return_trip": {
"price": {
"amount_ht": 123,
"currency": "EUR",
"express": true
}
},
"duplicated_from": {
"id": "<string>",
"transport_id": "M-58120"
},
"documents": {
"copied": 123,
"failed": [
{
"name": "<string>",
"error": "<string>"
}
]
},
"warnings": [
"<string>"
]
}Dupliquer la mission
Crée une nouvelle mission à partir d’une mission existante : même trajet, véhicule, contacts et consignes, options conservées à la demande, documents recopiés côté serveur. Les dates sont obligatoires pour chaque jambe (aller, et retour si la source en a un) ; le prix est recalculé sur la grille de votre groupe, majoration express comprise si l’enlèvement est proche.
Une mission ne se duplique qu’une seule fois : une seconde tentative
renvoie 409 avec l’extension duplicated_to. Utilisez
POST /transports/{id}/duplicate/preview pour obtenir le prix et le nombre
de documents recopiés sans rien créer.
Émet transport.created (avec duplicated_from) pour la mission créée et
transport.duplicated (avec duplicated_to) pour la source.
curl --request POST \
--url https://sandbox.myexpressdriver.com/v1/transports/{id}/duplicate \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <api-key>' \
--data '
{
"dates": {
"enlevement-aller": {
"date": "2026-09-22",
"start_time": "08:00",
"end_time": "12:00"
},
"livraison-aller": {
"date": "2026-09-23",
"start_time": "14:00",
"end_time": "18:00"
}
},
"options": {
"aller": [
"PV papier - 10"
],
"retour": []
},
"documents": {
"copy": [
"3f1c9a2e-7b44-4c1d-9e0a-5d2b8c6f1a23"
]
}
}
'import requests
url = "https://sandbox.myexpressdriver.com/v1/transports/{id}/duplicate"
payload = {
"dates": {
"enlevement-aller": {
"date": "2026-09-22",
"start_time": "08:00",
"end_time": "12:00"
},
"livraison-aller": {
"date": "2026-09-23",
"start_time": "14:00",
"end_time": "18:00"
}
},
"options": {
"aller": ["PV papier - 10"],
"retour": []
},
"documents": { "copy": ["3f1c9a2e-7b44-4c1d-9e0a-5d2b8c6f1a23"] }
}
headers = {
"X-Api-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Api-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
dates: {
'enlevement-aller': {date: '2026-09-22', start_time: '08:00', end_time: '12:00'},
'livraison-aller': {date: '2026-09-23', start_time: '14:00', end_time: '18:00'}
},
options: {aller: ['PV papier - 10'], retour: []},
documents: {copy: ['3f1c9a2e-7b44-4c1d-9e0a-5d2b8c6f1a23']}
})
};
fetch('https://sandbox.myexpressdriver.com/v1/transports/{id}/duplicate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://sandbox.myexpressdriver.com/v1/transports/{id}/duplicate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'dates' => [
'enlevement-aller' => [
'date' => '2026-09-22',
'start_time' => '08:00',
'end_time' => '12:00'
],
'livraison-aller' => [
'date' => '2026-09-23',
'start_time' => '14:00',
'end_time' => '18:00'
]
],
'options' => [
'aller' => [
'PV papier - 10'
],
'retour' => [
]
],
'documents' => [
'copy' => [
'3f1c9a2e-7b44-4c1d-9e0a-5d2b8c6f1a23'
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Api-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://sandbox.myexpressdriver.com/v1/transports/{id}/duplicate"
payload := strings.NewReader("{\n \"dates\": {\n \"enlevement-aller\": {\n \"date\": \"2026-09-22\",\n \"start_time\": \"08:00\",\n \"end_time\": \"12:00\"\n },\n \"livraison-aller\": {\n \"date\": \"2026-09-23\",\n \"start_time\": \"14:00\",\n \"end_time\": \"18:00\"\n }\n },\n \"options\": {\n \"aller\": [\n \"PV papier - 10\"\n ],\n \"retour\": []\n },\n \"documents\": {\n \"copy\": [\n \"3f1c9a2e-7b44-4c1d-9e0a-5d2b8c6f1a23\"\n ]\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Api-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://sandbox.myexpressdriver.com/v1/transports/{id}/duplicate")
.header("X-Api-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"dates\": {\n \"enlevement-aller\": {\n \"date\": \"2026-09-22\",\n \"start_time\": \"08:00\",\n \"end_time\": \"12:00\"\n },\n \"livraison-aller\": {\n \"date\": \"2026-09-23\",\n \"start_time\": \"14:00\",\n \"end_time\": \"18:00\"\n }\n },\n \"options\": {\n \"aller\": [\n \"PV papier - 10\"\n ],\n \"retour\": []\n },\n \"documents\": {\n \"copy\": [\n \"3f1c9a2e-7b44-4c1d-9e0a-5d2b8c6f1a23\"\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sandbox.myexpressdriver.com/v1/transports/{id}/duplicate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Api-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"dates\": {\n \"enlevement-aller\": {\n \"date\": \"2026-09-22\",\n \"start_time\": \"08:00\",\n \"end_time\": \"12:00\"\n },\n \"livraison-aller\": {\n \"date\": \"2026-09-23\",\n \"start_time\": \"14:00\",\n \"end_time\": \"18:00\"\n }\n },\n \"options\": {\n \"aller\": [\n \"PV papier - 10\"\n ],\n \"retour\": []\n },\n \"documents\": {\n \"copy\": [\n \"3f1c9a2e-7b44-4c1d-9e0a-5d2b8c6f1a23\"\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"options": {
"aller": [
"<string>"
],
"retour": [
"<string>"
]
},
"transport_id": "M-58121",
"status": "scheduled",
"price": {
"amount_ht": 123,
"currency": "EUR",
"express": true
},
"return_trip": {
"price": {
"amount_ht": 123,
"currency": "EUR",
"express": true
}
},
"duplicated_from": {
"id": "<string>",
"transport_id": "M-58120"
},
"documents": {
"copied": 123,
"failed": [
{
"name": "<string>",
"error": "<string>"
}
]
},
"warnings": [
"<string>"
]
}Autorisations
Clé API liée à un groupe (med_live_… en production, med_test_… en test).
Fournie en clair une seule fois à la création depuis le profil client.
En-têtes
Clé d'idempotence fournie par le client (un UUID v4 par opération), conservée
24 h. Recommandée sur toutes les créations. Rejouer la même clé avec un
corps identique sur la même route renvoie la réponse en cache
(Idempotent-Replayed: true). L'empreinte couvre la méthode, le chemin
(donc la mission visée) et le corps : la même clé pour une autre requête
renvoie 409 idempotency_key_reused. Requête identique encore en
traitement : 409 request_in_progress avec Retry-After.
Les réponses 5xx, 404 et 422 documents_failed ne sont pas mémorisées :
un nouvel essai avec la même clé et le même corps est retraité.
Après un 502 (code: relay_timeout), une erreur réseau ou un 5xx,
réessayez avec la même clé et le même corps : la requête est
relancée, et une mission créée malgré l'erreur vous est renvoyée (201,
Idempotent-Replayed: true) au lieu d'être créée une seconde fois.
Exception : si la réponse porte outcome_unknown: true, ne réessayez pas,
vérifiez d'abord (GET /transports). Seuls la création de mission et le
dépôt de documents sont dédoublonnés ainsi ; sans clé, un nouvel essai peut
créer un doublon.
"1f3c2b7a-9d4e-4a1b-8c2f-0e6d5a4b3c2d"
Paramètres de chemin
Identifiant de la mission (offer_id).
Corps
Une entrée par jambe existante : enlevement-aller, livraison-aller,
et, si la source a un retour, enlevement-retour, livraison-retour.
Toutes obligatoires, dans le futur, ordonnées, et au-delà du délai
minimal de commande (sinon 422 too_early avec min_date).
Show child attributes
Show child attributes
Par jambe : soit un tableau des options de la source à conserver
(libellés tels qu'ils figurent sur la source ; absent = toutes), soit
un objet { keep, add } pour ajouter des options au prix de votre
grille, avec leurs obligations (params, cf. GET /options). Une clé
inconnue renvoie 422 unknown_option, une obligation manquante
422 requirements_not_met. Un créneau need_appointment ajoute
d'office l'option « Prise de rendez-vous ».
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Réponse
Mission créée par duplication.
Mission créée par duplication (DTO allow-list).
Identifiant de la nouvelle mission (offer_id).
Options finales par jambe (conservées, ajoutées, prise de rendez-vous automatique), clés {nom} - {prix}.
Show child attributes
Show child attributes
"M-58121"
Statut public stable d'une mission (ou de sa jambe retour) :
scheduled (planifiée, en attente de convoyeur), assigned (convoyeur
attribué, véhicule pas encore enlevé), in_transit (aller en cours),
in_transit_return (retour en cours), awaiting_documents (en attente des
PV / documents), under_review (documents en validation), completed
(terminée, jamais une mission annulée), incident (anomalie signalée),
cancelled (mission annulée).
scheduled, assigned, in_transit, in_transit_return, awaiting_documents, under_review, completed, incident, cancelled Show child attributes
Show child attributes
Show child attributes
Show child attributes
Référence courte vers une mission.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
