Aller au contenu principal

API des Rendez-vous

🚀 Pourquoi utiliser l’API des Rendez-vous ?​

Les rendez-vous sont le cƓur des opĂ©rations d’entrepĂŽt dans DataDocks. Ils reprĂ©sentent des crĂ©neaux horaires planifiĂ©s Ă  vos quais ou dans vos cours pour la rĂ©ception ou l’expĂ©dition d’inventaire. L’API des rendez-vous vous donne le contrĂŽle programmatique de tout votre flux de planification d’entrepĂŽt — de la rĂ©servation de crĂ©neaux au suivi des mouvements de camions jusqu’à la complĂ©tion des expĂ©ditions.

ProblĂšmes rĂ©els rĂ©solus par cette API​

  • Éliminer la double saisie : Synchronisez directement les rendez-vous entre votre ERP/WMS et DataDocks
  • RĂ©duire la surcharge de communication : Automatisez les notifications entre l’équipe d’entrepĂŽt et les transporteurs
  • Optimiser l’utilisation des quais : Programmez les rendez-vous pour maximiser l’efficacitĂ©
  • Suivez les indicateurs en temps rĂ©el : Surveillez la ponctualitĂ©, le temps d’attente et le dĂ©bit
  • AmĂ©liorer la visibilitĂ© : Offrez aux transporteurs et clients un accĂšs libre-service au statut des rendez-vous

DĂ©marrage rapide en 5 minutes​

Vous souhaitez voir l’API en action immĂ©diatement ? Suivez ces Ă©tapes pour crĂ©er votre premier rendez-vous :

  1. Demandez et obtenez votre jeton API auprĂšs du support
  2. Trouvez votre sous-domaine d’emplacement (ex. : votre-entrepot.datadocks.com)
  3. Créez un rendez-vous de base avec cette commande :
Voir l’exemple cURL de dĂ©marrage rapide
curl -X POST \
https://your-warehouse.datadocks.com/api/v1/appointments \
-H 'Authorization: Token YOUR_API_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"appointment": {
"scheduled_at": "2023-12-15T10:00:00-05:00",
"duration": 60,
"dock_name": "Dock 1",
"shipping_number": "SHIP-12345"
}
}'
  1. Une requĂȘte rĂ©ussie renvoie 200 OK avec votre rendez-vous. VĂ©rifiez votre tableau de bord DataDocks pour le voir. Utilisez une date appropriĂ©e, un quai existant, et ajoutez tout champ additionnel requis par votre emplacement.

Vue d’ensemble de l’architecture de l’API​

┌─────────────────┐ ┌─────────────────┐ ┌────────────────────┐
│ Votre systĂšme │──────▶│ API DataDocks │──────▶│ Ops d’entrepĂŽt │
│ (ERP/WMS/TMS) │◀─────── (REST/JSON) │◀─────── (Planification) │
└─────────────────┘ └─────────────────┘ └────────────────────┘
│ â–Č
│ │
â–Œ │
┌─────────────────┐
│ Applis transporteur │
│ (Pointage) │
└─────────────────────┘

Authentification​

Toutes les requĂȘtes Ă  l’API doivent inclure votre jeton API dans l’en-tĂȘte Authorization :

Authorization: Token YOUR_API_TOKEN

Les jetons API appartiennent Ă  des utilisateurs. Les permissions d’accĂšs Ă  l’emplacement et au rendez-vous suivent celles de l’utilisateur. Les journaux d’audit identifient l’utilisateur API ; le nom affichĂ© dĂ©pend de sa configuration. Utilisez le nom d’hĂŽte complet de l’emplacement, incluant le suffixe d’organisation si applicable.

Limitations importantes​

  • Rendez-vous rĂ©currents : impossible de les crĂ©er ou modifier par l’API
  • Suppression de rendez-vous : non prise en charge par l’API (utilisez plutĂŽt l’annulation)
  • Les paramĂštres DateTime doivent inclure l’info de fuseau horaire pour Ă©viter toute ambiguĂŻté ; sinon, la valeur du fuseau de l’emplacement sera utilisĂ©e.
  • Seuls les rendez-vous non rĂ©currents sont retournĂ©s pour les points de terminaison listant, incluant les instances gĂ©nĂ©rĂ©es, mais excluant les modĂšles rĂ©currents.

Lister les rendez-vous​

Objectif​

Récupérez une liste paginée de rendez-vous avec possibilité de filtrer par période ou numéro de bon de commande. Utilisez ce point de terminaison pour synchroniser les rendez-vous avec vos systÚmes ou générer des rapports.

Cas d’usages mĂ©tier​

  • Synchronisez les rendez-vous avec votre WMS ou TMS pour la semaine Ă  venir
  • GĂ©nĂ©rez des rapports sur les expĂ©ditions Ă  venir par quai ou transporteur
  • Affichez les rendez-vous dans un tableau de bord avec supervision du statut
  • Suivez des KPI comme la ponctualitĂ©, le temps d’attente, l’utilisation des quais

RequĂȘte HTTP​

GET https://[location_subdomain].datadocks.com/api/v1/appointments

ParamĂštres de requĂȘte​

ParamĂštreTypeRequisDescriptionExemple
pageIntegerNonNuméro de page pour la pagination (défaut 1)page=2
internal_idStringNonFiltre par ID interne du rendez-vous (insensible Ă  la casse, correspondance exacte)internal_id=ERP-A12345
po_numberStringNonFiltre par numéro de bon de commande (insensible à la casse, exact)po_number=PO-12345
fromStringNonRetourne les rendez-vous planifiés ce jour/heure ou aprÚs (fuseau local)from=2023-10-01 08:00 AM
toStringNonRetourne les rendez-vous planifiés avant ce jour/heure (fuseau local)to=2023-10-05 06:00 PM

Les filtres peuvent se combiner. Les rĂ©sultats sont ordonnĂ©s par ID de rendez-vous. Les filtres de date excluent les rendez-vous sans horaire. Le filtrage PO s’applique au numĂ©ro sur la liste d’emballage et au bon de commande liĂ©.

Format de la rĂ©ponse​

La rĂ©ponse contient un tableau paginĂ© d’objets rendez-vous ayant les champs suivants. Les valeurs optionnelles non dĂ©finies sont null. Respectez le dĂ©calage dans les horodatages ISO8601 retournĂ©s sans supposer un fuseau particulier :

ChampTypeDescription
idIntegerIdentifiant unique du rendez-vous
location_nameStringNom de l’entrepĂŽt; inclus dans les rĂ©ponses de liste, d’affichage, de crĂ©ation et de mise Ă  jour
locationStringAlias compatible pour location_name
orgStringNom de l'organisation
ref_numberStringNuméro de référence formaté du rendez-vous
created_at, updated_atStringHorodatages de crĂ©ation et de mise Ă  jour de l’enregistrement
appointment_numberIntegerNuméro lisible du rendez-vous
stateStringStatut actuel du rendez-vous (ex. : "booked", "arrived", "completed")
durationIntegerDurée en minutes
scheduled_atStringHorodatage ISO8601 du créneau prévu
shipping_numberStringNumĂ©ro de rĂ©fĂ©rence d’expĂ©dition
trailer_numberStringNumĂ©ro d’identification de la remorque
bol_numberStringNuméro de BOL (connaissement)
carrier_nameStringNom du transporteur
carrier_idIntegerID de la compagnie de transport
driver_nameStringNom du chauffeur
driver_phoneStringTéléphone du chauffeur
driver_emailStringCourriel du chauffeur
created_byStringNom de l’utilisateur ayant créé le rendez-vous
outboundBooleanIndique si c’est un rendez-vous sortant (true) ou entrant (false)
drop_trailerBooleanIndique s'il s’agit d’un rendez-vous DĂ©poser une remorque/conteneur
queuedBooleanIndique si ce rendez-vous est dans une file d’attente
dockStringNom du quai assigné (null si une cour est assignée)
yardStringNom de la cour assignée (null si un quai est assigné)
internal_idStringIdentifiant interne de ce rendez-vous
free_untilStringHorodatage "libre jusqu’à" stocké ; pas une heure de dispo calculĂ©e
approved_atStringHorodatage d’approbation du rendez-vous
arrived_atStringHorodatage d'arrivée
started_atStringDébut du chargement/déchargement
completed_atStringFin du chargement/déchargement
left_atStringDépart
cancelled_atStringAnnulation du rendez-vous (null = activité en cours)
custom_valuesObjectPaires clé/valeur des champs personnalisés
packing_listsArrayListes d’emballage associĂ©es au rendez-vous
notesArrayListe des notes associées (voir format note ci-dessous)
documentsArrayDocuments sécurisés, chacun avec id, filename et presigned_url
warningsArrayMessages d’avertissement prĂ©sents seulement si disponibles

carrier_number et checklist_values sont acceptĂ©s en entrĂ©e, mais ne sont pas retournĂ©s. Les clĂ©s rĂ©ponse dock et yard diffĂšrent des clĂ©s requĂȘte dock_name et yard_name.

Les listes d’emballage retournent : id, po_number, customer_id, customer_name, created_at, updated_at, product, supplier, unit, booked_quantity, booked_weight, actual_quantity, actual_weight, et custom_values. Les valeurs associĂ©es ou numĂ©riques peuvent ĂȘtre null. Le client ne reçoit pas customer_number, product_name ou unit_name.

Exemples de code​

cURL​

Voir l’exemple cURL
# Liste de base
curl -H "Authorization: Token YOUR_API_TOKEN" \
https://YOUR_LOCATION.datadocks.com/api/v1/appointments

# Filtré par plage de dates et numéro de bon de commande
curl -H "Authorization: Token YOUR_API_TOKEN" \
"https://YOUR_LOCATION.datadocks.com/api/v1/appointments?from=2023-10-01%2008:00%20AM&to=2023-10-05%2006:00%20PM&po_number=PO-12345"

JavaScript​

Voir l’exemple JavaScript
// Utilisation de fetch API avec les filtres
const getAppointments = async (fromDate, toDate, poNumber) => {
const params = new URLSearchParams();
if (fromDate) params.append("from", fromDate);
if (toDate) params.append("to", toDate);
if (poNumber) params.append("po_number", poNumber);

const response = await fetch(
`https://YOUR_LOCATION.datadocks.com/api/v1/appointments?${params.toString()}`,
{
method: "GET",
headers: {
Authorization: "Token YOUR_API_TOKEN",
"Content-Type": "application/json",
},
}
);

// Gestion des erreurs potentielles
if (!response.ok) {
const errorData = await response.text();
throw new Error(
`Erreur lors de la récupération des rendez-vous : ${JSON.stringify(errorData)}`
);
}

return response.json();
};

// Traitement des résultats paginés
const getAllAppointments = async (fromDate, toDate, poNumber) => {
let currentPage = 1;
let allAppointments = [];
let hasMorePages = true;

while (hasMorePages) {
const params = new URLSearchParams({
page: currentPage.toString(),
});
if (fromDate) params.append("from", fromDate);
if (toDate) params.append("to", toDate);
if (poNumber) params.append("po_number", poNumber);

const response = await fetch(
`https://YOUR_LOCATION.datadocks.com/api/v1/appointments?${params.toString()}`,
{
method: "GET",
headers: {
Authorization: "Token YOUR_API_TOKEN",
"Content-Type": "application/json",
},
}
);

if (!response.ok) {
throw new Error("Échec lors de la rĂ©cupĂ©ration des rendez-vous");
}

const appointments = await response.json();
allAppointments = [...allAppointments, ...appointments];

// VĂ©rifiez s’il y a d’autres pages
const totalPages = parseInt(response.headers.get("Total-Pages"), 10);
if (!Number.isInteger(totalPages) || totalPages < 1) {
throw new Error("En-tĂȘte Total-Pages manquant ou invalide");
}
hasMorePages = currentPage < totalPages;
currentPage++;
}

return allAppointments;
};

Exemple de rĂ©ponse​

Voir l’exemple de rĂ©ponse
[
{
"id": 1,
"location_name": "EntrepĂŽt principal",
"location": "EntrepĂŽt principal",
"org": "Organisation Exemple",
"ref_number": "1",
"created_at": "2020-09-22T13:35:00-04:00",
"updated_at": "2020-09-25T13:35:00-04:00",
"appointment_number": 1,
"state": "left",
"duration": 120,
"shipping_number": "57886",
"trailer_number": "2222222",
"bol_number": "922",
"carrier_name": "FastCo",
"carrier_id": 12,
"driver_name": "Jason Smith",
"driver_phone": "+1 (555) 123-4567",
"driver_email": "jason.smith@fastco.example.com",
"created_by": "Sysadmin",
"outbound": false,
"drop_trailer": false,
"queued": false,
"dock": "Dock 2",
"yard": null,
"internal_id": "ERP-A12345",
"free_until": null,
"scheduled_at": "2020-09-30T06:00:00-04:00",
"approved_at": "2020-09-22T13:35:00-04:00",
"arrived_at": null,
"started_at": "2020-09-24T13:35:00-04:00",
"completed_at": "2020-09-24T13:35:00-04:00",
"left_at": "2020-09-25T13:35:00-04:00",
"cancelled_at": null,
"custom_values": {
"expected_at": "2020-10-01",
"travel_type": "Truck",
"forklift_operator": "Sue",
"inspection_passed": "1"
},
"packing_lists": [
{
"id": 4,
"created_at": "2020-09-22T13:35:00-04:00",
"updated_at": "2020-09-25T13:35:00-04:00",
"supplier": null,
"po_number": "A-2000",
"customer_name": "FishCo",
"customer_id": 34,
"product": "Trout",
"unit": "Skid",
"booked_quantity": 10,
"booked_weight": 152,
"actual_quantity": 12,
"actual_weight": 160,
"custom_values": {
"barcode": "11223344",
"dimensions": "S",
"temperature_celcius": "-5"
}
}
],
"notes": [
{
"id": 3,
"body": "PremiĂšre note.",
"note_type": "user_note"
}
],
"documents": []
}
]

Pagination​

La rĂ©ponse contient jusqu’à 20 rendez-vous par page. Les en-tĂȘtes incluent Current-Page, Page-Items, Total-Pages, Total-Count et Link. Une requĂȘte au-delĂ  de la derniĂšre page retourne la derniĂšre page ; utilisez donc les en-tĂȘtes au lieu d’attendre une page vide. Pour plus de dĂ©tails sur les en-tĂȘtes et navigation de pagination, consultez la documentation Pagination.

PiĂšges courants et dĂ©pannage​

  • ProblĂšmes d’analyse date/heure : les paramĂštres from et to sont interprĂ©tĂ©s dans le fuseau du site. Si le rĂ©sultat est inattendu, vĂ©rifiez que l’info de fuseau est fournie.

    ✅ Bon : from=2023-10-01T08:00:00-04:00
    ✅ Bon : from=2023-10-01 08:00 AM EDT
    ✅ Bon : from=2023-10-01 (minuit du fuseau local)
  • Filtrage PO : insensible Ă  la casse mais demande une correspondance exacte. La correspondance partielle Ă©chouera.

    ✅ Correspond : po_number=PO-12345
    ✅ Correspond : po_number=po-12345
    ❌ Échoue : po_number=12345 (partiel)
  • Gestion des dates mal formĂ©es : les dates malformĂ©es n’ont pas de validation cohĂ©rente : l’analyse peut donner un rĂ©sultat vide ou une erreur. PrĂ©fĂ©rez ISO8601 et encodez vos paramĂštres d’URL.

  • Rendez-vous non rĂ©currents uniquement : ce point de terminaison ne retourne que les rendez-vous non rĂ©currents. Les modĂšles rĂ©currents ne sont pas inclus.

  • Performance : avec de grands intervalles de dates, effectuez les requĂȘtes par tranches plus courtes (ex: semaine plutĂŽt que mois) pour de meilleures performances.

CrĂ©er un rendez-vous​

Objectif​

CrĂ©er un nouveau rendez-vous Ă  un quai ou une cour prĂ©cise, avec listes d’emballage et mĂ©tadonnĂ©es optionnelles. C’est la principale mĂ©thode pour planifier de nouveaux rendez-vous dans votre entrepĂŽt.

Cas d’usages mĂ©tier​

  • IntĂ©gration systĂšme : planifier les rendez-vous directement via votre ERP, WMS ou TMS
  • Planification automatisĂ©e : crĂ©er un rendez-vous selon des rĂšgles mĂ©tier
  • Libre-service transporteur : permettre aux transporteurs de rĂ©server par votre portail
  • Applications mobiles : activer la crĂ©ation via des applis mobiles d’entrepĂŽt
  • ExĂ©cution de commandes : crĂ©er automatiquement les sorties quand les commandes sont prĂȘtes

RequĂȘte HTTP​

POST https://[location_subdomain].datadocks.com/api/v1/appointments

Corps de la requĂȘte​

ParamÚtreTypeRequisDescriptionContraintesPar défautExemple
scheduled_atStringNonHoraire ISO8601 du RDVDates passées selon permissions; min 2000-01-01Aucun"2023-10-15T09:00:00-04:00"
durationIntegerNonDurĂ©e en minutesDoit ĂȘtre > 0CalculĂ©e selon rĂšgles de rĂ©servation120
dock_nameStringNon*Nom du quai assignéInsensible à la casseAucun"Dock 1"
yard_nameStringNon*Nom de la cour assignéeInsensible à la casseAucun"Yard A"
carrier_nameStringNon**Nom du transporteur2–64 caractùres si requisAucun"FastCo Logistics"
carrier_idIntegerNonID du transporteur accessible ; ID modifiĂ© non vide prioritaireDoit ĂȘtre accessibleAucun123
carrier_numberStringNonID du transporteur dans votre systĂšmeAucunAucun"CARRIER-123"
shipping_numberStringNon**NumĂ©ro de rĂ©fĂ©rence d’expĂ©ditionAucunAucun"SHIP-9876"
trailer_numberStringNon**NumĂ©ro d’identification de la remorqueAucunAucun"TRAILER-456"
bol_numberStringNon**NumĂ©ro de BOL (connaissement)2–256 caractĂšres si non nulAucun"BOL-789"
driver_nameStringNon**Nom du chauffeur2–64 caractùres si non nulAucun"John Smith"
driver_phoneStringNon**TĂ©lĂ©phone du chauffeur10–20 caractĂšres si non nulAucun"+1 (555) 123-4567"
driver_emailStringNon**Courriel du chauffeur7–128 caractùres si non nul ; pas de validation emailAucun"driver@carrier.com"
outboundBooleanNonIndique si sortie (true)AucunPréférence utilisateur ou lieutrue
drop_trailerBooleanNonRendez-vous Déposer une remorque/conteneurAucunfalsefalse
queuedBooleanNonRendez-vous en file d’attenteAucunfalsefalse
free_untilStringNonHorodatage « libre jusqu’à » enregistrĂ©Pas de comparaison gĂ©nĂ©rale avec scheduled_at ; peut ĂȘtre obligatoireAucun"2023-10-15T11:00:00-04:00"
internal_idStringNonID interne du rendez-vousAucunAucun"ERP-A12345"
approved_atStringNonDate/heure d’approbation ISO8601AucunAucun"2023-10-14T09:00:00-04:00"
arrived_atStringNonArrivée ISO8601AucunAucun"2023-10-15T08:45:00-04:00"
started_atStringNonDébut de chargement ISO8601AucunAucun"2023-10-15T09:05:00-04:00"
completed_atStringNonFin du chargement ISO8601AucunAucun"2023-10-15T10:30:00-04:00"
left_atStringNonDépart ISO8601AucunAucun"2023-10-15T10:45:00-04:00"
cancelled_atStringNonAnnulation ISO8601AucunAucun"2023-10-14T10:00:00-04:00"
packing_listsArrayNon**Tableaux de listes d’emballageAucunAucunVoir format ci-dessous
notesArrayNonTableaux de notesAucunAucunVoir format ci-dessous
custom_valuesObjectNon**Champs personnalisés clé/valeur. La clé sera en minuscules avec underscores.Selon configuration lieuAucun{"reference": "ABC123"}
checklist_valuesObjectNonValeurs de liste de contrĂŽle conservĂ©es ; non retournĂ©es en rĂ©ponseSelon configurationAucun{"safety_check": "Passed"}

* L’assignation dĂ©pend de la configuration et l’auto-assignation. Les noms inconnus ne retournent pas une erreur dĂ©diĂ©e, la validation et auto-association peuvent alors s’appliquer.

** Peut ĂȘtre requis selon les prĂ©fĂ©rences de l’emplacement.

Approbation automatique des rendez-vous​

Par dĂ©faut, les rendez-vous créés via API peuvent ĂȘtre automatiquement approuvĂ©s selon les paramĂštres de votre emplacement (si scheduled_at est prĂ©sent). Ce comportement est gĂ©rĂ© en interne (contactez le support pour modifier ce rĂ©glage d’approbation automatique API).

Un rendez-vous peut ĂȘtre créé sans scheduled_at. L’omission de duration lance les rĂšgles de rĂ©servation par dĂ©faut. Toute modification pertinente dĂ©clenche un nouveau calcul. L’approbation explicite et les transitions d’état ultĂ©rieures peuvent remplir le champ approved_at mĂȘme si l’approbation automatique API est dĂ©sactivĂ©e.

Logique d’assignation du transporteur​

Un carrier_id changĂ© et non vide prĂ©vaut et doit rĂ©fĂ©rer Ă  une entreprise accessible. Sinon, carrier_number est utilisĂ© (insensible Ă  la casse), lorsque le nom est vide ou inchangĂ©. Si aucun numĂ©ro ne correspond, il devient le nom utilisĂ© pour l’assignation suivante. Un nom changĂ© prĂ©vaut gĂ©nĂ©ralement sur le numĂ©ro. L’assignation par nom peut correspondre ou crĂ©er un transporteur selon les rĂ©glages et permissions d’emplacement. Renvoyer le mĂȘme ID n’est pas considĂ©rĂ© comme un changement.

Format des listes d’emballage​

{
"po_number": "PO-12345",
"customer_name": "ACME Corp",
"customer_number": "CUST-001",
"product_name": "Widgets",
"unit_name": "Skid",
"booked_quantity": 10,
"booked_weight": 500,
"actual_quantity": null,
"actual_weight": null,
"custom_values": {
"temperature": "-5",
"fragile": "Yes"
}
}

DĂ©tail des paramĂštres de liste d'emballage​

ParamÚtreTypeRequisDescriptionContraintesDéfautExemple
idIntegerNon*ID existant de la liste (obligatoire pour MAJ/suppression)Doit ĂȘtre valide pour une liste existante liĂ©e au rendez-vousAucun123
po_numberStringNon**Numéro de bon de commandeLongueur max selon lieuAucun"PO-12345"
customer_nameStringNon**Nom du client2–255 car. si fourniAucun"ACME Corp"
customer_numberStringNonNuméro du client (recherche si nom/ID non fourni)AucunAucun"CUST-001"
customer_idIntegerNonID direct du client (prioritaire)Doit ĂȘtre accessible via l’emplacementAucun456
product_nameStringNon**Nom du produitDoit exister ou ĂȘtre crĂ©able selon le lieuAucun"Widgets"
unit_nameStringNon**Nom de l’unitĂ©IdemAucun"Skid"
booked_quantityDĂ©cimalNon**QuantitĂ© planifiĂ©e>= 0 ; obligatoire ou selon limitesAucun10 ou 10.5
booked_weightDĂ©cimalNon**Poids planifiĂ©>= 0 ; obligatoire ou selon limitesAucun500 ou 500.75
actual_quantityDĂ©cimalNonQuantitĂ© rĂ©elle reçue/expĂ©diĂ©e (en MÀJ)>= 0 et dans les limitesnull9 ou 9.5
actual_weightDĂ©cimalNonPoids rĂ©el reçu/expĂ©diĂ© (en MÀJ)>= 0 et dans les limitesnull450 ou 450.25
custom_valuesObjetNon**Champs personnalisés clé/valeur. Clef minuscule avec underscores.Champs obligatoires vérifiés, clés inconnues non filtrées{}{"lot_number": "A123"}
_destroyBooléenNon*Mettre à true pour supprimer la liste (en MAJ seulement)Seulement lors des PUT sur /appointments/:idfalsetrue

* Uniquement pertinent lors des MAJ via PUT /appointments/:id pour modifier/supprimer une liste d’emballage existante.

** Peut ĂȘtre requis selon la configuration des champs du lieu. Consultez les rĂ©glages de votre site.

Logique d’assignation du client​

Lors de la crĂ©ation/modif des listes d’emballage, un customer_id modifiĂ©, non vide, prĂ©vaut et doit rĂ©fĂ©rer Ă  une entreprise accessible. Renvoyer le mĂȘme ID Ă  nouveau n’est pas un changement. Sinon :

  1. Si customer_number est fourni et que le nom est vide ou inchangé, le systÚme :

    • Cherche une sociĂ©tĂ© avec le mĂȘme numĂ©ro client
    • Si trouvĂ©, remplit automatiquement customer_name et customer_id
    • Sinon, met customer_name = customer_number fourni
  2. Un nom changĂ© prĂ©vaut gĂ©nĂ©ralement sur la recherche par numĂ©ro. L’assignation de nom peut correspondre ou crĂ©er un client selon les permissions.

Gestion des Produits et UnitĂ©s​

Pour produits et unitĂ©s, la correspondance insensible Ă  la casse ignore les espaces autour. La crĂ©ation automatique est dĂ©sactivĂ©e par dĂ©faut et peut ĂȘtre activĂ©e via support. Les noms inconnus ne gĂ©nĂšrent pas toujours une erreur : les rĂšgles obligatoires et la validation dĂ©terminent si la requĂȘte Ă©choue, ou si l’association reste vide. Les restrictions de produit-unitĂ© s’appliquent.

En mise à jour, l’omission de product_name ou unit_name conserve l’association. Une chaüne vide la retire selon la validation.

Format de la note​

{
"body": "Le chauffeur a besoin d’un hayon hydraulique"
}

Les nouvelles notes sont liĂ©es automatiquement Ă  l’utilisateur API courant. Ajoutez un id pour modifier, ou id + _destroy: true pour supprimer. Utilisez notes intĂ©grĂ© plutĂŽt que l’ancien champ scalaire note.

Les réponses incluent un champ en lecture seule note_type :

ValeurSignification
user_noteUne note Ă©crite par une personne. Par dĂ©faut ; seul type crĂ©able par l’API.
cancellation_noteSaisie par DataDocks lors d’une annulation par le portail de rĂ©servation (raison obligatoire).

note_type est attribuĂ© par DataDocks et ignorĂ© en entrĂ©e. Les notes d’annulation sont indĂ©lĂ©biles : les demandes de suppression d’une telle note Ă©chouent et font Ă©chouer toute la modification.

RĂ©ponse​

Une requĂȘte Ă  succĂšs retourne un 200 OK avec l’objet rendez-vous complet, incluant l’id gĂ©nĂ©rĂ© et toutes valeurs systĂšme.

Exemples de code​

cURL​

Voir l’exemple cURL
curl -H "Authorization: Token YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-X POST \
-d '{
"appointment": {
"scheduled_at": "2023-10-15T09:00:00-04:00",
"duration": 120,
"dock_name": "Dock 1",
"carrier_name": "FastCo Logistics",
"carrier_number": "CARRIER-123",
"trailer_number": "TRAILER-456",
"driver_name": "John Smith",
"driver_phone": "+1 (555) 123-4567",
"driver_email": "john.smith@fastco.example.com",
"outbound": false,
"internal_id": "ERP-A12345",
"packing_lists": [
{
"po_number": "PO-12345",
"product_name": "Widgets",
"unit_name": "Skid",
"booked_quantity": 10,
"booked_weight": 500
}
],
"notes": [
{
"body": "Le chauffeur a besoin d’un hayon hydraulique"
}
],
"custom_values": {
"reference": "ABC123",
"priority": "Haut"
},
"checklist_values": {
"safety_check": "Prévu",
"dock_seal": "Requis"
}
}
}' \
https://YOUR_LOCATION.datadocks.com/api/v1/appointments

JavaScript​

Voir l’exemple JavaScript
const createAppointment = async (
apiToken,
locationSubdomain,
appointmentData
) => {
try {
const response = await fetch(
`https://${locationSubdomain}.datadocks.com/api/v1/appointments`,
{
method: "POST",
headers: {
Authorization: `Token ${apiToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ appointment: appointmentData }),
}
);

if (!response.ok) {
const errorData = await response.text();
const errorMessages = errorData || `HTTP ${response.status}`;

throw new Error(`Échec de la crĂ©ation du rendez-vous :\n${errorMessages}`);
}

return await response.json();
} catch (error) {
console.error("Erreur API :", error);
throw error;
}
};

// Exemple d’utilisation avec donnĂ©es complĂštes
const appointmentData = {
scheduled_at: "2023-10-15T09:00:00-04:00",
duration: 120,
dock_name: "Dock 1",
carrier_name: "FastCo Logistics",
carrier_number: "CARRIER-123",
trailer_number: "TRAILER-456",
driver_name: "John Smith",
driver_phone: "+1 (555) 123-4567",
driver_email: "john.smith@fastco.example.com",
outbound: false,
internal_id: "ERP-A12345",
packing_lists: [
{
po_number: "PO-12345",
product_name: "Widgets",
unit_name: "Skid",
booked_quantity: 10,
booked_weight: 500,
},
],
notes: [
{
body: "Le chauffeur a besoin d’un hayon hydraulique",
},
],
custom_values: {
reference: "ABC123",
priority: "Haut",
},
checklist_values: {
safety_check: "Prévu",
dock_seal: "Requis",
},
};

// Création du rendez-vous
createAppointment("YOUR_API_TOKEN", "your-warehouse", appointmentData)
.then((appointment) => {
console.log("Rendez-vous créé :", appointment.id);
// Processus supplémentaire...
})
.catch((error) => {
// Gérer les erreurs
});

Gestion des erreurs​

CodeDescriptionPossible cause
400Mauvaise requĂȘteRequĂȘte mal formĂ©e, ex. : wrapper appointment manquant
404IntrouvableID d’enregistrement imbriquĂ© non trouvĂ© dans la portĂ©e accessible
422EntitĂ© non traitableValidation mĂ©tier Ă©chouĂ©e (ex. : conflit d’horaire, quai plein)
401Non autoriséJeton API invalide ou manquant
403InterditPermissions insuffisantes

Les validations Ă©chouĂ©es retournent gĂ©nĂ©ralement 422. Dock, cour, produit ou unitĂ© inconnus ne gĂ©nĂšrent pas forcĂ©ment 404. Les emplacements supprimĂ©s ou impayĂ©s retournent 402 ; les requĂȘtes trop nombreuses : 429. Les erreurs peuvent ĂȘtre JSON, texte brut ou vides. Les erreurs de liste d’emballage peuvent inclure un index de champ imbriquĂ©.

Exemple d’erreur​

{
"errors": {
"driver_name": ["est trop court (minimum 2 caractĂšres)"]
}
}

PiĂšges courants et dĂ©pannage​

  • Assignation quai/cour : fournir dock_name ou yard_name de prĂ©fĂ©rence. Si les deux sont renseignĂ©s, une cour modifiĂ©e prĂ©vaut, sinon le quai. En mise Ă  jour, un nom omis conserve l’association, une chaĂźne vide la supprime.

  • Formats temporels : prĂ©cisez le fuseau horaire. Sinon, interprĂ©tĂ© en fuseau d’emplacement.

    ✅ Bon : "2023-10-15T09:00:00-04:00"
    ✅ Accepté : "2023-10-15T09:00:00" (fuseau local)
  • CrĂ©ation prod./unité : dĂ©sactivĂ©e par dĂ©faut. Les noms inconnus Ă©chouent la validation ou laissent l’association vide. Demandez l’activation auprĂšs du support si nĂ©cessaire.

  • Recherche client : les numĂ©ros clients sont insensibles Ă  la casse (ex : "CUST-001" ou "cust-001" matchent).

  • Suppression d’une liste d’emballage en MÀJ :

    {
    "id": 123,
    "_destroy": true
    }
  • Rendez-vous rĂ©currents : non pris en charge ; utilisable via l’interface web uniquement.

  • Champs personnalisĂ©s : les champs nĂ©cessaires sont validĂ©s, mais les nouveaux ne sont pas filtrĂ©s.

  • Approbation automatique : vĂ©rifiez ce paramĂštre auprĂšs de l’administrateur. La dĂ©sactivation de l’approbation automatique API saute ce chemin seulement ; l’approbation explicite et les autres transitions peuvent toujours remplir le champ approved_at.

Conseils d’optimisation​

  • Groupez vos requĂȘtes : espacez-les pour Ă©viter la limitation du dĂ©bit
  • RĂ©duisez les champs personnalisĂ©s : incluez seulement ceux vĂ©ritablement requis
  • PrĂ©chargez les ressources : assurez-vous que produits, unitĂ©s et transporteurs existent
  • Validez localement : vĂ©rifiez les formats cĂŽtĂ© client avant l’envoi

Obtenir un rendez-vous spĂ©cifique​

Objectif​

Obtenez de l’info dĂ©taillĂ©e sur un rendez-vous par ID. Utilisez ce point si vous avez besoin de toutes les donnĂ©es, calendrier, statuts, listes d’emballage et mĂ©tadonnĂ©es, sur un rendez-vous particulier.

Cas d’usage​

  • Suivi du statut : vĂ©rification d’état du rendez-vous
  • Surveillance arrivĂ©e : voir horaires d’arrivĂ©e/dĂ©part
  • VĂ©rification des documents : consulter documents et listes d’emballage joints
  • Information transporteur : chauffeurs, remorques, etc.
  • Champs personnalisĂ©s : accĂ©der aux champs propres au site (pas de checklist_values)

RequĂȘte HTTP​

GET https://[location_subdomain].datadocks.com/api/v1/appointments/:id

Paramùtres d’URL​

ParamĂštreTypeRequisDescription
idIntOuiID unique du rendez-vous

RĂ©ponse​

Succùs = 200 OK avec l’objet rendez-vous complet (comme pour list).

Exemples de code​

cURL​

Voir l’exemple cURL
curl -H "Authorization: Token YOUR_API_TOKEN" \
https://YOUR_LOCATION.datadocks.com/api/v1/appointments/123

JavaScript​

Voir l’exemple JavaScript
const getAppointment = async (appointmentId) => {
try {
const response = await fetch(
`https://YOUR_LOCATION.datadocks.com/api/v1/appointments/${appointmentId}`,
{
method: "GET",
headers: {
Authorization: "Token YOUR_API_TOKEN",
"Content-Type": "application/json",
},
}
);

if (!response.ok) {
if (response.status === 404) {
throw new Error(`Rendez-vous #${appointmentId} introuvable`);
}

const errorData = await response.text();
throw new Error(
`Échec Ă  la rĂ©cupĂ©ration du rendez-vous : ${JSON.stringify(errorData)}`
);
}

return await response.json();
} catch (error) {
console.error("Erreur récupération rendez-vous :", error);
throw error;
}
};

// Usage
getAppointment(123)
.then((appointment) => {
console.log(
`Le rendez-vous #${appointment.id} est actuellement dans l’état ${appointment.state}`
);

// Vérifie si complété
if (appointment.completed_at) {
const completionTime = new Date(appointment.completed_at);
console.log(`Terminé à : ${completionTime.toLocaleString()}`);
}

// Calcule la durée totale
if (appointment.left_at && appointment.arrived_at) {
const arrivedTime = new Date(appointment.arrived_at);
const leftTime = new Date(appointment.left_at);
const durationMinutes = Math.round((leftTime - arrivedTime) / 60000);
console.log(`Temps total passé sur site : ${durationMinutes} minutes`);
}
})
.catch((error) => {
// Gestion d’erreur
if (error.message.includes("introuvable")) {
// Cas not found
} else {
// Autres erreurs
}
});

Codes d’erreur​

CodeDescriptionCause possible
404IntrouvableID de rendez-vous inexistant
401Non autoriséJeton API invalide/manquant
403InterditPermissions insuffisantes

Limitations​

  • Seuls les rendez-vous non rĂ©currents peuvent ĂȘtre consultĂ©s ici
  • Pour voir les modĂšles rĂ©currents, utilisez l’interface web

Mise à jour d’un rendez-vous​

Objectif​

Mettre à jour les détails, statuts, données associées. Ce point accepte les champs listés plus haut, sous réserve de configuration et de permissions. Impossible de télécharger documents et signatures via cette API.

Cas d’usages​

  • Changements d’état : marquer comme arrivĂ©, commencĂ©, terminĂ©, ou quittĂ©
  • Modif sĂ©ance/durĂ©e : changer horaire ou durĂ©e
  • DĂ©tail : mettre Ă  jour transporteur, remorque, rĂ©fĂ©rence d’expĂ©dition
  • Listes d’emballage : modifier produits, quantitĂ©s ou valeurs personnalisĂ©es
  • Gestion notes : consigner des infos importantes

RequĂȘte HTTP​

PUT https://[location_subdomain].datadocks.com/api/v1/appointments/:id

Paramùtres d’URL​

ParamĂštreTypeRequisDescription
idIntOuiID unique du rendez-vous

Corps de requĂȘte​

Le corps accepte les mĂȘmes paramĂštres que la crĂ©ation. Seuls les champs Ă  changer doivent ĂȘtre inclus.

Flux de transitions d’état​

Lors de la MAJ des champs d’état, suivez idĂ©alement cette sĂ©quence :

scheduled_at → approved_at → arrived_at → started_at → completed_at → left_at

Permissions et validations rĂ©gissent chaque changement. L’état dĂ©pend des horodatages ; le champ state n’est pas modifiable. Toute modification d’état peut renseigner les horaires manquants prĂ©cĂ©dents ou effacer ceux ultĂ©rieurs. Par exemple, dĂ©finir left_at remplit approuvĂ©, arrivĂ©, dĂ©but et terminĂ© avec l’heure de sortie si vides. Envoyez des horodatages rĂ©els si disponibles.

ScĂ©narios courants de MAJ​

Marquer comme arrivé​

{
"appointment": {
"arrived_at": "2023-10-15T08:45:00-04:00",
"trailer_number": "TRAILER-789"
}
}

Mise Ă  jour des quantitĂ©s de liste d’emballage​

{
"appointment": {
"packing_lists": [
{
"id": 123,
"actual_quantity": 9,
"actual_weight": 450
}
]
}
}

Ajouter une note​

{
"appointment": {
"notes": [
{
"body": "Camion arrivé avec un scellé endommagé. Inspection effectuée."
}
]
}
}

Supprimer une liste d’emballage​

{
"appointment": {
"packing_lists": [
{
"id": 123,
"_destroy": true
}
]
}
}

Marquer comme terminé​

{
"appointment": {
"completed_at": "2023-10-15T10:30:00-04:00",
"left_at": "2023-10-15T10:45:00-04:00",
"checklist_values": {
"dock_condition": "Propre",
"paperwork_complete": "Oui"
}
}
}

Exemples de code​

cURL​

Voir l’exemple cURL
curl -H "Authorization: Token YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-X PUT \
-d '{
"appointment": {
"trailer_number": "UPDATED-TRAILER-789",
"arrived_at": "2023-10-15T08:45:00-04:00",
"notes": [
{
"body": "Camion arrivé avec un numéro de remorque différent que prévu."
}
]
}
}' \
https://YOUR_LOCATION.datadocks.com/api/v1/appointments/123

JavaScript​

Voir l’exemple JavaScript
const updateAppointment = async (appointmentId, updateData) => {
try {
const response = await fetch(
`https://YOUR_LOCATION.datadocks.com/api/v1/appointments/${appointmentId}`,
{
method: "PUT",
headers: {
Authorization: "Token YOUR_API_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({ appointment: updateData }),
}
);

if (!response.ok) {
const errorData = await response.text();
throw new Error(
`Échec de la mise à jour : ${JSON.stringify(errorData)}`
);
}

return await response.json();
} catch (error) {
console.error("Erreur MAJ rendez-vous :", error);
throw error;
}
};

// Exemple : marquer comme arrivé/débuté
const markAppointmentArrived = async (appointmentId, arrivalTime) => {
const now = arrivalTime || new Date().toISOString();

try {
const updatedAppointment = await updateAppointment(appointmentId, {
arrived_at: now,
notes: [
{
body: `Camion arrivé à ${new Date(now).toLocaleTimeString()}`,
},
],
});

console.log(
`Rendez-vous #${updatedAppointment.id} marqué comme arrivé`
);
return updatedAppointment;
} catch (error) {
console.error(
`Échec lors du marquage de l’arrivĂ©e du rendez-vous #${appointmentId} :`,
error
);
throw error;
}
};

// Exemple : mise Ă  jour des quantitĂ©s d’une liste d’emballage
const updatePackingListQuantities = async (
appointmentId,
packingListId,
actualQuantity,
actualWeight
) => {
try {
const updatedAppointment = await updateAppointment(appointmentId, {
packing_lists: [
{
id: packingListId,
actual_quantity: actualQuantity,
actual_weight: actualWeight,
},
],
});

console.log(
`QuantitĂ©s de la liste d’emballage #${packingListId} mises Ă  jour`
);
return updatedAppointment;
} catch (error) {
console.error(`Erreur de mise à jour des quantités :`, error);
throw error;
}
};

Gestion des erreurs​

CodeDescriptionCause possible
400Mauvaise requĂȘteRequĂȘte mal formĂ©e ; la validation renvoie gĂ©nĂ©ralement 422
404IntrouvableID de rendez-vous inexistant
422Entité non traitableValidation métier échouée (transition invalide)
401Non autoriséJeton API invalide ou manquant
403InterditPermissions insuffisantes

Limitations importantes​

  • Rendez-vous rĂ©currents : impossible de modifier un modĂšle rĂ©current via l’API.
  • Mises Ă  jour partielles : inclure seulement les champs Ă  modifier. Les champs ordinaires non inclus sont conservĂ©s, mais des callbacks peuvent influencer les horodatages, durĂ©e, associations. Les objets JSON (custom_values, checklist_values) remplacent l’attribut au complet.
  • Objets imbriquĂ©s : pour les listes d’emballage, incluez un id pour la MAJ, sinon un nouvel objet sera créé. Omettre l’existant ne supprime pas.
  • Suppression non supportĂ©e : aucun point API ne supprime un rendez-vous. Pour annuler, dĂ©finissez cancelled_at.

Bonnes pratiques de transition d’état​

Envoyez les horodatages rĂ©els en sĂ©quence logique. Un horodatage de prioritĂ© supĂ©rieure contrĂŽle l’état mĂȘme aprĂšs la MÀJ d’un champ antĂ©rieur. SĂ©quence normale :

  1. Création (scheduled_at)
  2. Approbation (approved_at)
  3. Arrivée (arrived_at)
  4. Début (started_at)
  5. Fin (completed_at)
  6. Départ (left_at)

Chaque MAJ d’état doit inclure les mĂ©ta-infos pertinentes (ex. quantitĂ© emballĂ©e Ă  la fin).

Cycle de vie & flux du rendez-vous​

Comprendre le cycle de vie des rendez-vous est essentiel pour une bonne intégration API. Chaque rendez-vous suit un état bien défini régissant son parcours dans vos opérations.

Diagramme cycle de vie rendez-vous​

┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐
│ Booked │───▶│ Arrived │───▶│ Started │───▶│ Completed │───▶│ Left │
└────────────┘ └────────────┘ └────────────┘ └────────────┘ └────────────┘
│
│ ┌────────────┐
└─────────────────────────────▶│ Cancelled │
└────────────┘

ÉvĂ©nements de transition d’état​

Chaque transition résulte de la MAJ du champ horaire correspondant :

DeÀChamp horodatageDescription
Besoin de réservationEn attentescheduled_atRendez-vous avec horaire planifié
En attenteDémarréapproved_atApprobation du rendez-vous (auto possible)
DémarréArrivéarrived_atCamion arrivé sur site
ArrivéCommencéstarted_atDébut chargement/déchargement
CommencéTerminécompleted_atFin chargement/déchargement
TerminéDeboutleft_atDépart du camion du site
N’importeAnnulĂ©cancelled_atRendez-vous annulĂ©

Les Ă©tats retournĂ©s sont needs_booking, pending, booked, arrived, started, completed, left, et cancelled. Priorité : cancelled_at, left_at, completed_at, started_at, arrived_at, approved_at, puis scheduled_at. La planification peut produire auto. un booked sans passer par pending. Effacer cancelled_at recalcule l’état depuis les horaires restants selon permissions.

Collecte de donnĂ©es lors des transitions​

Chaque transition permet la collecte d’informations opĂ©rationnelles clĂ©s :

Arrivé​

  • MAJ informations chauffeur si changĂ©
  • VĂ©rifier numĂ©ro remorque
  • Enregistre l'heure d’arrivĂ©e rĂ©elle pour la ponctualitĂ©
  • Documenter divergences ou problĂšmes

Commencé​

  • Consigner tout changement de quai
  • Enregistre dĂ©but des opĂ©rations
  • DĂ©but suivi du temps total sur site

Terminé​

  • Renseigner quantitĂ©s rĂ©ellement reçues/expĂ©diĂ©es
  • Documenter Ă©carts/qualitĂ©
  • Signatures ou confirmations via workflow de l’application
  • TĂ©lĂ©charger documents via l’app — non supportĂ© ici

DĂ©part​

  • Calculer durĂ©e totale sur le site
  • Enregistrer l’heure de dĂ©part pour gestion cour
  • ComplĂ©ter la liste de vĂ©rification

Bonnes pratiques d’implantation​

  1. Validez les transitions : votre appli doit valider la sĂ©quence logique
  2. Inclure les mĂ©tadonnĂ©es : chaque MAJ d’état doit inclure les donnĂ©es mĂ©tier
  3. Ajouter des notes : gĂ©nĂ©rez automatiquement des notes de contexte
  4. DĂ©clencher des notifications : utilisez les webhooks pour alerter les parties concernĂ©es
  5. Suivre les temps : consignez la durĂ©e par Ă©tat

Meilleures pratiques de sĂ©curité​

La protection des donnĂ©es d’entrepĂŽt nĂ©cessite des mesures de sĂ©curitĂ© appropriĂ©es pour l’API.

Stockage sĂ©curisé​

  • Ne jamais coder les jetons en dur : placez-les dans les variables d’environnement ou un gestionnaire d’identifiants sĂ©curisĂ©
  • Chiffrez au repos : assurez l’encryptage de vos jetons
  • Gestion des secrets : utilisez des outils comme HashiCorp Vault ou AWS Secrets Manager

SĂ©curitĂ© de la connexion​

  • Toujours utiliser HTTPS : pas de requĂȘtes API non chiffrĂ©es
  • Validez les certificats : vĂ©rifiez SSL/TLS sur tous les appels API

Autres mesures de sĂ©curité​

  • Mettre en place la surveillance : alertes pour activitĂ© API suspecte
  • Plan d’intervention : ayez un plan si un jeton est compromis

Endpoints reliĂ©s​

  • Produits API – GĂ©rer les produits rĂ©fĂ©rencĂ©s sur les listes d’emballage
  • Bons de commande API – GĂ©rer les POs liĂ©s aux rendez-vous
  • API Compagnies – GĂ©rer transporteurs et clients
  • Webhooks – Recevoir des notifications temps rĂ©el sur les changements de rendez-vous

Suppression de rendez-vous (non supportĂ©)​

Limite importante​

L’API des rendez-vous ne permet pas la suppression d’un rendez-vous. Utilisez l’annulation pour prĂ©server l’historique.

Alternatives à la suppression​

PlutÎt que de supprimer, envisagez les solutions suivantes :

  • Annulez le rendez-vous via le champ cancelled_at
  • MAJ des dĂ©tails si changements requis
  • Champs personnalisĂ©s pour suivre l’état dans votre systĂšme

Annulation​

Annulez via cancelled_at. Toute note envoyĂ©e est une simple user_note ; les notes d’annulation officielles ne proviennent que du portail rĂ©servĂ©.

Voir l’exemple cURL
curl -H "Authorization: Token YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-X PUT \
-d '{
"appointment": {
"cancelled_at": "2023-10-14T15:30:00-04:00",
"notes": [
{
"body": "Annulé à cause des conditions météo."
}
]
}
}' \
https://YOUR_LOCATION.datadocks.com/api/v1/appointments/123

Livre de recettes API : scĂ©narios courants​

Cette section fournit des recettes prĂȘtes-Ă -l’emploi pour les cas d’intĂ©gration frĂ©quents. Copiez, adaptez, utilisez pour accĂ©lĂ©rer votre dĂ©ploiement.

Recette : synchronisation des expĂ©ditions sortantes depuis l’ERP​

Exemple pour crĂ©er automatiquement des rendez-vous pour les expĂ©ditions sortantes prĂȘtes dans votre ERP.

Voir l’exemple JavaScript
/**
* CrĂ©er un rendez-vous sortant depuis l’ERP
* @param {Object} shipment – DonnĂ©es expĂ©dition ERP
* @returns {Object} – Rendez-vous créé
*/
async function createOutboundAppointment(shipment) {
// Calcul durée du rendez-vous selon items
const duration = Math.max(30, shipment.items.length * 15); // 30 min min

// Formater horaire avec fuseau
const scheduledDate = new Date(shipment.plannedShipDate);
const scheduledTime = scheduledDate.toISOString();

// Construire listes d’emballage
const packingLists = shipment.items.map((item) => ({
po_number: item.purchaseOrderNumber,
product_name: item.productName,
unit_name: item.unitType,
booked_quantity: item.quantity,
booked_weight: item.weight,
customer_number: shipment.customerId,
customer_name: shipment.customerName,
}));

// CrĂ©er l’objet rendez-vous
const appointmentData = {
scheduled_at: scheduledTime,
duration: duration,
outbound: true,
dock_name: shipment.preferredDock || "Shipping Dock",
shipping_number: shipment.shipmentId,
carrier_name: shipment.carrierName,
carrier_number: shipment.carrierId,
internal_id: `SHIP-${shipment.id}`,
custom_values: {
origin: "ERP-SYNC",
priority: shipment.priority,
department: shipment.department,
},
packing_lists: packingLists,
notes: [
{
body: `Rendez-vous sortant automatisé pour expédition ${shipment.shipmentId}.`,
},
],
};

// Appel DataDocks API
const response = await fetch(
`https://YOUR_LOCATION.datadocks.com/api/v1/appointments`,
{
method: "POST",
headers: {
Authorization: "Token YOUR_API_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({ appointment: appointmentData }),
}
);

if (!response.ok) {
const errorData = await response.text();
throw new Error(
`Impossible de créer le rendez-vous : ${JSON.stringify(errorData)}`
);
}

return await response.json();
}

Recette : tableau de bord d’utilisation des quais en temps rĂ©el​

Calcule l’utilisation prĂ©vue et le temps de sĂ©jour. Fournissez les limites de date avec leur offset de fuseau, et le nombre de minutes d’opĂ©ration au total pour l’intervalle. Les temps d’arrivĂ©e/dĂ©part reprĂ©sentent le sĂ©jour sur site — non l’occupation du quai.

Voir l’exemple JavaScript
/**
* Calculer l’utilisation des quais
* @param {string} fromDate – DĂ©but (avec offset)
* @param {string} toDate – Fin exclue (avec offset)
* @param {number} operatingMinutes – Total minutes d’utilisation
* @returns {Object} – Utilisation et prĂ©sence par quai
*/
async function calculateDockUtilization(fromDate, toDate, operatingMinutes) {
if (!(operatingMinutes > 0)) throw new Error("Indiquez les minutes d’exploitation");

// RĂ©cupĂšre les rendez-vous dans l’intervalle
const appointments = await getAllAppointments(fromDate, toDate);

// Grouper par quai
const dockMap = {};

appointments.forEach((appt) => {
if (!appt.dock || appt.state === "cancelled") return;

if (!dockMap[appt.dock]) {
dockMap[appt.dock] = {
totalAppointments: 0,
completedAppointments: 0,
scheduledMinutes: 0,
facilityMinutes: 0,
appointmentsList: [],
};
}

// Minutes planifiées
const scheduledMinutes = appt.duration || 0;

// Durée présence (arrivée/départ présents)
let facilityMinutes = 0;
if (appt.arrived_at && appt.left_at) {
const arrivedTime = new Date(appt.arrived_at);
const leftTime = new Date(appt.left_at);
facilityMinutes = Math.round((leftTime - arrivedTime) / 60000);
}

dockMap[appt.dock].totalAppointments++;
dockMap[appt.dock].scheduledMinutes += scheduledMinutes;
dockMap[appt.dock].facilityMinutes += facilityMinutes;

if (appt.completed_at) {
dockMap[appt.dock].completedAppointments++;
}

dockMap[appt.dock].appointmentsList.push({
id: appt.id,
state: appt.state,
scheduled_at: appt.scheduled_at,
duration: appt.duration,
carrier_name: appt.carrier_name,
});
});

// Calcul des taux d’utilisation
const dockUtilization = {};
const businessHours = operatingMinutes;

Object.keys(dockMap).forEach((dockName) => {
const dock = dockMap[dockName];

dockUtilization[dockName] = {
...dock,
scheduledUtilization:
((dock.scheduledMinutes / businessHours) * 100).toFixed(
1
) + "%",
completionRate: dock.totalAppointments
? ((dock.completedAppointments / dock.totalAppointments) * 100).toFixed(
1
) + "%"
: "0%",
};
});

return dockUtilization;
}

Recette : gestion automatisĂ©e arrivĂ©e camion​

Met Ă  jour le statut rendez-vous lors de l’arrivĂ©e du camion et met Ă  jour les donnĂ©es du chauffeur.

Voir l’exemple JavaScript
/**
* Traiter l’arrivĂ©e d’un camion
* @param {string} appointmentId – ID rendez-vous
* @param {Object} arrivalData – DonnĂ©es collectĂ©es Ă  l’arrivĂ©e
* @returns {Object} – Rendez-vous mis à jour
*/
async function processTruckArrival(appointmentId, arrivalData) {
const arrivalTime = new Date().toISOString();

// Préparer MAJ rendez-vous
const appointmentUpdate = {
arrived_at: arrivalTime,
trailer_number: arrivalData.trailerNumber || null,
driver_name: arrivalData.driverName || null,
driver_phone: arrivalData.driverPhone || null,
driver_email: arrivalData.driverEmail || null,
notes: [
{
body: `Camion arrivé à ${new Date(
arrivalTime
).toLocaleString()}. Pointage effectué par la sécurité.`,
},
],
custom_values: {
...(arrivalData.customValues || {}),
actual_arrival_time: arrivalTime,
},
};

if (arrivalData.isDelayed) {
appointmentUpdate.notes.push({
body: `Arrivé ${arrivalData.delayMinutes} min aprÚs prévue. Motif : ${arrivalData.delayReason}`,
});
}

// Appel DataDocks API
const response = await fetch(
`https://YOUR_LOCATION.datadocks.com/api/v1/appointments/${appointmentId}`,
{
method: "PUT",
headers: {
Authorization: "Token YOUR_API_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({ appointment: appointmentUpdate }),
}
);

if (!response.ok) {
const errorData = await response.text();
throw new Error(
`Impossible de mettre Ă  jour le rendez-vous : ${JSON.stringify(errorData)}`
);
}

return await response.json();
}

Recette : mise à jour en masse du statut des rendez-vous​

Chaque requĂȘte est envoyĂ©e sĂ©parĂ©ment. Partagez la limitation de dĂ©bit API entre workers utilisant les mĂȘmes identifiants.

Voir l’exemple JavaScript
/**
* Traite un lot de MAJ de statuts sur rendez-vous
* @param {Array} updates – Tableau de MAJ à traiter
* @returns {Object} – RĂ©sultats des MAJ
*/
async function processBatchStatusUpdates(updates) {
const results = {
successful: [],
failed: [],
};

// Espacer les appels sous la limite API ; d’autres workers partagent le budget.
for (const update of updates) {
await new Promise((resolve) => setTimeout(resolve, 1000));
try {
const { appointmentId, status, timestamp, notes } = update;

// Identifier le champ d’état Ă  mettre Ă  jour
let statusUpdate = {};
switch (status) {
case "arrived":
statusUpdate = { arrived_at: timestamp || new Date().toISOString() };
break;
case "started":
statusUpdate = { started_at: timestamp || new Date().toISOString() };
break;
case "completed":
statusUpdate = {
completed_at: timestamp || new Date().toISOString(),
};
break;
case "left":
statusUpdate = { left_at: timestamp || new Date().toISOString() };
break;
default:
throw new Error(`Statut invalide : ${status}`);
}

// Ajouter notes si fournies
if (notes) {
statusUpdate.notes = [{ body: notes }];
}

// Appel API MAJ rendez-vous
const response = await fetch(
`https://YOUR_LOCATION.datadocks.com/api/v1/appointments/${appointmentId}`,
{
method: "PUT",
headers: {
Authorization: "Token YOUR_API_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({ appointment: statusUpdate }),
}
);

if (!response.ok) {
const errorData = await response.text();
throw new Error(JSON.stringify(errorData));
}

const updatedAppointment = await response.json();
results.successful.push({
appointmentId,
status,
result: updatedAppointment,
});

} catch (error) {
results.failed.push({
appointmentId: update.appointmentId,
status: update.status,
error: error.message,
});
}
}

return results;
}

Optimisation des performances​

Optimisez votre intégration API grùce à ces conseils :

Chargement efficace de donnĂ©es​

  • Limitez les rĂ©sultats avec des filtres de date : toujours fournir from et to
  • Mettez en cache les donnĂ©es stables
  • Utilisez la pagination : rĂ©cupĂ©rez seulement ce dont vous avez besoin

Optimisation des requĂȘtes​

  • Regroupez vos MAJ
  • ContrĂŽlez la concurrence : limitez les requĂȘtes parallĂšles
  • Utilisez les structures documentĂ©es : Conditional GET, ETag non supportĂ©s

RĂ©seau​

  • Connections persistantes (keep-alive)
  • Corps JSON non compressé : Gzip non documentĂ© comme supportĂ©
  • Backoff exponentiel : en cas de limitation, reculez graduellement

DĂ©pannage des problĂšmes courants​

Problùmes d’authentification​

Symptîmes​

  • Erreurs 401 Non autorisĂ©
  • Messages "AccĂšs refusĂ©"

Solutions​

  1. Vérifier le jeton API (valide et à jour)
  2. Vérifier les permissions du jeton
  3. VĂ©rifier que l’utilisateur API a accĂšs Ă  l’emplacement
  4. VĂ©rifiez le format de l’en-tĂȘte : Authorization: Token YOUR_API_TOKEN

Limitation de dĂ©bit​

Symptîmes​

  • Erreurs 429 Trop de requĂȘtes
  • RequĂȘtes subitement Ă©chouĂ©es

Solutions​

  1. Partagez le budget entre clients avec les mĂȘmes jetons : limites API : 120/min, 5000/h par valeur d’en-tĂȘte Authorization. Autres limites gĂ©nĂ©rales s’appliquent.
  2. Échelonnez les requĂȘtes groupĂ©es
  3. Tenez compte de X-RateLimit-Reset (ISO8601) et backoff aprĂšs un 429 ; rĂ©ponses incluent aussi X-RateLimit-Limit et X-RateLimit-Remaining
  4. Avant de retenter aprĂšs une crĂ©ation ambigĂŒe, rĂ©conciliez via internal_id ou rĂ©fĂ©rence pour Ă©viter les doublons ; internal_id N’EST pas une clĂ© idempotente

Problùmes date/heure​

Symptîmes​

  • Rendez-vous créés au mauvais horaire
  • RĂ©sultats de filtre incomplets

Solutions​

  1. Spécifiez toujours le fuseau (ex: 2023-10-15T09:00:00-04:00)
  2. Attention aux changements heure d’étĂ©
  3. ISO8601 pour tout format date/heure
  4. Pour les requĂȘtes d’intervalle, from < to

Erreurs de validation des donnĂ©es​

Symptîmes​

  • 422 EntitĂ© non traitable
  • DĂ©tail prĂ©cis du champ en retour

Solutions​

  1. Consulter la rĂ©ponse d’erreur pour le champ en problĂšme
  2. VĂ©rifier que les champs requis sont fournis. scheduled_at peut ĂȘtre omis, la durĂ©e est calculĂ©e si omise
  3. S’assurer que dock, produit ou unitĂ© existent
  4. Validez les formats en client avant l’envoi

Aide et support​

Comment trouver une solution d’erreur​

Si votre problĂ©matique n’est pas traitĂ©e ici :

  1. Étudiez la rĂ©ponse d’erreur
  2. VĂ©rifiez les limitations de l’API (ex : rĂ©currence refusĂ©e)
  3. Testez par étapes plus simples
  4. Vérifiez les limites de débit : 120/min et 5000/h par jeton

Pour obtenir de l’aide​

Pour toute assistance supplémentaire :

Veuillez fournir :

  • Le sous-domaine de votre emplacement
  • Le dĂ©tail de la requĂȘte (mĂ©thode, point de terminaison, paramĂštres)
  • La rĂ©ponse complĂšte
  • L’horodatage de l’erreur