ediverse Explorer la plateforme

À la une PEPPOL BIS Billing 3.0 L’obligation européenne d’e-invoicing arrive : France sept 2026, Belgique janv 2026, Allemagne 2025.

Appointment — Réservation d'un acte de soin

La brique de scheduling FHIR : rendez-vous médical, séance de kiné, téléconsultation, intervention au bloc. Elle relie patient, professionnel, lieu et plage horaire en une seule ressource.

Objet de la ressource

Appointment représente la réservation d'un événement de soin entre un ou plusieurs patients, praticiens, RelatedPerson et/ou devices, à une date et une heure précises. Elle accommode aussi bien les rendez-vous cliniques standards que les systèmes communautaires (« permanence sans rendez-vous », walk-in, télé-suivi), et supporte les rendez-vous récurrents via recurrenceTemplate.

La ressource est volontairement orthogonale à Schedule (l'agenda de disponibilité du praticien) et Slot (le créneau dans cet agenda). Le pattern canonique : Schedule expose des Slot free, l'app cliente crée un Appointment qui pointe vers les Slot consommés, et ces Slot basculent en busy.

Champs clés

La StructureDefinition R5 publie 32 éléments de premier niveau. Les plus importants en pratique :

ChampTypeCardinalitéRôle
identifierIdentifier[]0..*Identifiants externes du rendez-vous (numéro métier de l'EHR, voucher, code-barres patient).
statuscode1..1Statut du cycle de vie. Modifier — change la sémantique du rendez-vous.
cancellationReasonCodeableConcept0..1Motif d'annulation. Présent uniquement si status=cancelled ou noshow.
classCodeableConcept[]0..*Classification du rendez-vous (ambulatoire, hospitalisation, urgence…).
serviceCategoryCodeableConcept[]0..*Catégorie globale (Médecine générale, Dentaire, Imagerie…).
serviceTypeCodeableReference[]0..*Service précis (extraction dentaire, IRM cérébral…).
specialtyCodeableConcept[]0..*Spécialité du praticien (SNOMED CT 394814009 = General practice).
appointmentTypeCodeableConcept0..1Type fonctionnel (FOLLOWUP, ROUTINE, WALKIN, EMERGENCY… — v2-0276).
reasonCodeableReference[]0..*Motif clinique du rendez-vous (peut référencer une Condition ou un Observation).
priorityCodeableConcept0..1Priorité (R = Routine, EM = Emergency… — v3-ActPriority).
startinstant0..1Datetime de début effective. instant = précision seconde + timezone obligatoire.
endinstant0..1Datetime de fin.
minutesDurationpositiveInt0..1Durée en minutes (redondant avec start/end mais utile pour les RDV qui ne sont pas encore positionnés).
slotReference(Slot)[]0..*Les Slot consommés par ce rendez-vous (un long RDV peut consommer plusieurs Slot consécutifs).
requestedPeriodPeriod[]0..*Plage demandée par le patient quand le RDV est en proposed mais pas encore positionné.
subjectReference(Patient | Group)0..1Sujet principal — typiquement le patient.
participantBackboneElement[]1..*Tous les acteurs du RDV — patient, praticien, lieu, device. Chaque participant porte actor, required, status.
basedOnReference(CarePlan | DeviceRequest | MedicationRequest | ServiceRequest)[]0..*Le RDV est créé en exécution d'une demande de soin antérieure.
recurrenceTemplateBackboneElement[]0..*Définition d'une récurrence (hebdomadaire, mensuelle…) avec règle iCalendar RRULE-like.
virtualServiceVirtualServiceDetail[]0..*Informations de visio (URL, type de service, code d'accès) pour une téléconsultation.
patientInstructionCodeableReference[]0..*Instructions au patient (à jeun, apporter ordonnance, arriver 10 min avant…).

Statuts du cycle de vie

Le code status est obligatoire et porte la sémantique métier du rendez-vous. Les valeurs publiées par HL7 (Required binding) sont :

CodeSens
proposedRendez-vous suggéré mais aucune date fixée. Le système attend la confirmation des participants.
pendingRendez-vous positionné, en attente de validation par tous les participants.
bookedConfirmé. Le créneau est verrouillé.
arrivedLe patient est arrivé (check-in en salle d'attente).
fulfilledLe rendez-vous a eu lieu (l'Encounter associé est généralement déjà créé).
cancelledAnnulé. cancellationReason renseigne le motif.
noshowLe patient ne s'est pas présenté. Distinct de cancelled pour les besoins de reporting.
entered-in-errorSaisie erronée — à corriger dans le système amont.
checked-inCheck-in effectué au desk (alternative à arrived, utilisé par les workflows IT).
waitlistListe d'attente — le patient sera contacté en cas de désistement.

Exemple JSON

Rendez-vous de suivi de 20 minutes dans le système d'un cabinet de médecine générale, le 22 mai 2026 à 09:00 (heure de Paris), entre le Dr Adam Careful et le patient Peter Chalmers, dans le service « South Wing, second floor ».

json appointment-example.json
{
  "resourceType": "Appointment",
  "id": "example",
  "status": "booked",
  "serviceCategory": [{
    "coding": [{
      "system": "http://example.org/service-category",
      "code": "gp",
      "display": "General Practice"
    }]
  }],
  "serviceType": [{
    "concept": {
      "coding": [{
        "system": "http://example.org/service-type",
        "code": "52",
        "display": "General Discussion"
      }]
    }
  }],
  "specialty": [{
    "coding": [{
      "system": "http://snomed.info/sct",
      "code": "394814009",
      "display": "General practice"
    }]
  }],
  "appointmentType": {
    "coding": [{
      "system": "http://terminology.hl7.org/CodeSystem/v2-0276",
      "code": "FOLLOWUP",
      "display": "A follow up visit from a previous appointment"
    }]
  },
  "reason": [{
    "concept": {
      "coding": [{
        "system": "http://snomed.info/sct",
        "code": "413095006",
        "display": "Clinical mental health assessment"
      }]
    }
  }],
  "priority": {
    "coding": [{
      "system": "http://terminology.hl7.org/CodeSystem/v3-ActPriority",
      "code": "R",
      "display": "Routine"
    }]
  },
  "description": "Suivi des résultats de la prise de sang du mois dernier",
  "start": "2026-05-22T09:00:00+02:00",
  "end": "2026-05-22T09:20:00+02:00",
  "minutesDuration": 20,
  "slot": [{ "reference": "Slot/example" }],
  "created": "2026-05-14T10:30:00+02:00",
  "patientInstruction": [{
    "concept": {
      "text": "Veuillez arriver 10 minutes avant l'heure de votre rendez-vous"
    }
  }],
  "participant": [{
    "actor": { "reference": "Patient/example", "display": "Peter James Chalmers" },
    "required": true,
    "status": "accepted"
  }, {
    "type": [{
      "coding": [{
        "system": "http://terminology.hl7.org/CodeSystem/v3-ParticipationType",
        "code": "ATND"
      }]
    }],
    "actor": { "reference": "Practitioner/example", "display": "Dr Adam Careful" },
    "required": true,
    "status": "accepted"
  }, {
    "actor": { "reference": "Location/1", "display": "South Wing, second floor" },
    "required": true,
    "status": "accepted"
  }]
}

À noter dans cet exemple :

  • Le participant[] liste trois acteurs : patient, praticien, lieu. Chacun a son propre status (accepted/declined/tentative).
  • slot pointe vers une ressource Slot ; ce Slot doit basculer en busy côté Schedule du praticien.
  • start et end sont en type instant avec timezone : indispensable pour les apps multi-fuseaux.
  • patientInstruction porte un texte libre lisible par le patient.

Cycle de réservation

Le pattern de réservation FHIR canonique combine trois ressources et deux opérations standards :

  1. L'app cliente interroge GET /Slot?schedule=Schedule/123&status=free&start=ge2026-05-22 pour récupérer les Slot libres du praticien.
  2. L'utilisateur sélectionne un créneau ; l'app crée un Appointment en POST /Appointment avec status=pending et un slot qui pointe vers le Slot choisi.
  3. Le serveur valide la disponibilité, bascule le Slot référencé en status=busy, et bascule l'Appointment en status=booked dès que tous les participant[].status requis sont à accepted.
  4. Le serveur peut exposer l'opération $find ou $book en commodité pour combiner ces étapes (voir les profils US Core et Argonaut Scheduling).
  5. À l'arrivée du patient, l'EHR passe le statut à arrived ou checked-in. Quand l'acte est réalisé, le statut bascule à fulfilled et un Encounter est créé.

Pièges courants

  • Slot non bloqué — créer un Appointment sans basculer les Slot référencés en busy permet le double-booking. Cette synchronisation est de la responsabilité du serveur, pas du client.
  • start/end sans timezone — le type FHIR instant exige un offset. Omettre la timezone (2026-05-22T09:00:00 sans suffixe) est rejeté par le validateur.
  • participant[].required=true mais status=declined — incohérence métier : si un participant requis a décliné, le rendez-vous ne peut pas être en booked.
  • Téléconsultation sans virtualService — un Appointment en mode visio doit porter au moins une entrée virtualService avec channelType et adresse de connexion, sinon le patient n'a aucun moyen technique de joindre la session.
  • recurrenceTemplate incohérent — un template récurrent doit décrire des occurrences atteignables dans requestedPeriod. Une RRULE qui pointe vers une date hors borne est ignorée silencieusement par certains serveurs.
  • Confusion cancelled / noshowcancelled = annulation explicite avant le RDV. noshow = patient non venu sans annuler. Les deux comptent différemment dans le reporting et la facturation.

Ressources liées

  • Schedule — l'agenda de disponibilité du praticien, du device ou du lieu.
  • Slot — chaque créneau libre/occupé exposé par un Schedule.
  • AppointmentResponse — réponse asynchrone d'un participant à une invitation.
  • Encounter — l'interaction de soin créée à partir du rendez-vous, une fois le patient présent.
  • Patient, Practitioner — les acteurs principaux référencés dans participant.
  • ServiceRequest, CarePlan, DeviceRequest — demandes de soin qui peuvent déclencher la création de l'Appointment via basedOn.

Voir aussi : l'index FHIR R5 pour la liste complète des ressources.