Kiosk Integration Contract (1.0.0)

Download OpenAPI specification:

Kiosk Integration Contract V1

Contrat REST vendor-neutral entre la borne d'accueil patient (ApiBorne kiosk) et l'éditeur du système de gestion médical. Il couvre le parcours patient complet : identification, consultation du RDV, mise à jour du patient, gestion des documents, check-in et opérations satellites.

Pendant le parcours patient, l'éditeur est appelé selon l'un des deux modes de connectivité configurés côté ApiBorne (réglage kioskContractVia, page Intégration de l'admin) :

  • borne en direct (défaut) : la borne appelle l'éditeur directement depuis son navigateur — éventuellement sur une adresse locale du réseau de l'établissement, différente de celle que voit le serveur ApiBorne ;
  • relais serveur : la borne appelle {serveur ApiBorne}/api/contractRelay/api/apiborneIntegrationService/... et le serveur ApiBorne relaie la requête telle quelle vers l'éditeur (passthrough — éditeur injoignable → 502 RELAY_UPSTREAM_UNREACHABLE côté borne).

Le contrat vu par l'éditeur est identique dans les deux modes : seul le chemin réseau change. Dans tous les cas, le serveur ApiBorne reste requis pour la configuration de la borne au démarrage et la numérotation des tickets.

Toutes les opérations du contrat sont OBLIGATOIRES. Il n'y a pas de routes optionnelles ni de déclaration de support : un éditeur qui n'a pas la fonctionnalité implémente la forme minimale conforme — liste de documents vide (la borne saute le flow), 204 sans effet (PATCH patient, prescripteur), 404 systématique (codes de convocation non gérés), 401 INVALID_CREDENTIALS (pas de comptes personnel), { "ready": true } (pas de notion de notification). C'est ce qui garde la configuration côté ApiBorne simple et sans exception.

Authentification

Chaque requête porte deux headers obligatoires :

Header Contenu
X-Kiosk-Auth-Key Clé d'autorisation partagée (provisionnée chez l'éditeur, connue de la conf borne)
X-Kiosk-Device-Id Identifiant unique du device borne, connu de l'éditeur

L'éditeur DOIT valider les deux : device inconnu → 401 UNKNOWN_DEVICE, clé invalide pour ce device → 401 INVALID_AUTH_KEY.

ApiBorne envoie en plus le header X-Kiosk-Office-Id : l'identité de l'office/du groupe de licences telle que configurée côté ApiBorne (identifiant libre choisi par l'éditeur ; EasyDoct utilise la forme composée {officeId}!#!{officeVisibleId}). Un éditeur multi-sites DEVRAIT s'en servir pour sélectionner l'office cible au lieu de le résoudre via sa table de devices (la flotte des bornes est gérée dans l'admin ApiBorne, un device peut lui être inconnu). Un éditeur mono-site peut l'ignorer. Ce header doit être autorisé dans Access-Control-Allow-Headers (CORS).

En mode relais serveur, ces headers (X-Kiosk-Auth-Key, X-Kiosk-Device-Id, X-Kiosk-Office-Id) sont transmis inchangés à l'éditeur : X-Kiosk-Device-Id reste l'identifiant de la borne réelle, jamais celui du serveur ApiBorne — la validation attendue de l'éditeur est identique dans les deux modes.

Chiffrement de bout en bout (obligatoire)

Contexte de configuration (<code>context</code>)

<code>vendorData</code>

Chiffrement de bout en bout (obligatoire)

Le contrat impose un chiffrement applicatif de bout en bout entre la borne et l'éditeur, par-dessus TLS : l'établissement génère une paire de clés RSA, la clé PRIVÉE reste sur le serveur de l'éditeur, la clé PUBLIQUE est saisie dans l'admin ApiBorne et transportée à la borne via sa configuration. Le serveur ApiBorne et tous les intermédiaires réseau sont incapables de déchiffrer (zero-knowledge) : en mode relais serveur, le relais ne voit passer que des corps chiffrés (passthrough zero-knowledge). C'est aussi ce chiffrement qui rend acceptable une URL contrat http sur un réseau local en mode borne directe.

Périmètre

Le chiffrement s'applique aux routes de communication émises par la borne (les 10 opérations du parcours patient : identifyPatients, getAppointmentByCode, getAppointmentById, updatePatient, setAppointmentPrescriber, listAppointmentDocuments, uploadAppointmentDocument, deleteAppointmentDocument, checkInAppointment, getNotificationReadiness) — requêtes et réponses 2xx.

Ne sont PAS chiffrés :

  • les routes de configuration (openapi-config.yaml) : ce sont des référentiels sans donnée patient, consommés par le serveur ApiBorne ;
  • staffSignIn et setAppointmentStatus : émises par le serveur ApiBorne, qui est le consommateur légitime de leurs réponses (E2E sans objet, TLS seul).

Protocole (v1)

  • Chiffrement symétrique : AES-256-GCM, IV de 96 bits, tag d'authentification de 128 bits concaténé à la fin du ciphertext (convention WebCrypto).
  • Enveloppe de clé : la clé de session (32 octets) est wrappée en RSA-OAEP avec SHA-256 (clé publique de l'établissement, RSA ≥ 2048 bits, 4096 recommandé).
  • Clé de session unique PAR TENTATIVE : chaque requête (y compris chaque retry) génère une sessionKey ET un IV neufs — jamais de réutilisation.

La borne envoie deux headers sur toutes les méthodes (GET inclus, car les réponses sont sensibles) :

Header Contenu
X-Kiosk-Encryption: v1 Version du protocole de chiffrement
X-Kiosk-Encryption-Key SessionKey AES-256 wrappée RSA-OAEP-SHA256, en base64

Le corps chiffré (requêtes avec corps) remplace le JSON clair par l'enveloppe (voir le schéma EncryptedEnvelope) :

{ "encrypted": { "v": 1, "iv": "<base64 12 octets>", "data": "<base64 ciphertext+tag>" } }

Réponses

  • 2xx avec corps : l'éditeur répond la même enveloppe { "encrypted": { v, iv, data } }, chiffrée avec la même sessionKey que la requête et un IV neuf (jamais celui de la requête), plus le header X-Kiosk-Encryption: v1.
  • 204 : pas de corps, rien à chiffrer.
  • Erreurs 4xx/5xx : toujours EN CLAIR (format ErrorDto normal) — cela préserve la politique de retry et le diagnostic. Les messages d'erreur ne doivent JAMAIS contenir de données patient.

Échec de déchiffrement

Si l'éditeur ne peut pas déchiffrer (clé inconnue, tag invalide, enveloppe malformée), il répond 400 DECRYPTION_FAILED (en clair). La borne ne retente jamais et ne bascule jamais en clair (anti-downgrade) : l'erreur est affichée et tracée.

Taille des uploads

La limite contractuelle de 10 Mo (uploadAppointmentDocument) s'entend sur le JSON en clair. Le transport chiffré ajoute ~35 % (base64 du ciphertext) : l'éditeur DOIT dimensionner sa limite de corps HTTP en conséquence.

Rotation des clés

L'éditeur PEUT conserver plusieurs clés privées et essayer chacune à l'unwrap de la sessionKey. Procédure : déployer la nouvelle clé privée chez l'éditeur AVANT de saisir la nouvelle clé publique dans l'admin ApiBorne, puis retirer l'ancienne clé privée après la propagation de la configuration.

CORS

Les deux headers doivent être ajoutés au CORS de l'éditeur :

  • Access-Control-Allow-Headers: …, X-Kiosk-Encryption, X-Kiosk-Encryption-Key
  • Access-Control-Expose-Headers: X-Kiosk-Encryption

En mode relais serveur, les routes du parcours ne reçoivent que des appels serveur → serveur : l'exigence CORS navigateur (preflights et headers ci-dessus) ne s'applique plus au parcours.

Contexte de configuration (context)

Chaque requête POST/PATCH/PUT peut porter un objet context optionnel :

  • context.locationId : identifiant du lieu (site) associé au device.
  • context.config : sous-ensemble strict de la configuration borne consommé par l'éditeur (identification, documents, checkIn).
  • context.vendorData : données opaques précédemment renvoyées par l'éditeur (voir plus bas).

Règle contractuelle : si context.config est fourni, l'éditeur DOIT l'utiliser et NE DOIT JAMAIS rappeler le serveur ApiBorne pour obtenir de la configuration. Si context.config est absent, l'éditeur utilise sa propre base de configuration (mode legacy direct).

vendorData

Les réponses peuvent contenir des champs vendorData (objets JSON opaques, au niveau réponse, patient ou rendez-vous). La borne ne les interprète jamais : elle les renvoie tels quels dans context.vendorData des appels suivants du même parcours qui concernent la même entité. L'éditeur peut s'en servir pour véhiculer des identifiants internes (éviter des relectures en base).

Formats

  • DTOs : JSON camelCase, en anglais.
  • Dates : ISO 8601date (YYYY-MM-DD) pour les dates de naissance, date-time avec offset (YYYY-MM-DDThh:mm:ss±hh:mm) pour les horodatages.
  • Listes : vraies listes JSON (jamais de chaînes jointes par séparateur).
  • Fichiers : pages en base64 dans des tableaux JSON (sans préfixe data:).
  • Identifiants (patient.id, appointment.id, documentId, examId, locationId…) : chaînes opaques choisies par l'éditeur (max 128 caractères, utilisables dans une URL). La borne ne les interprète pas.

Erreurs normalisées

Statuts HTTP réels + corps { "error": { "code", "message", "details" } } :

Code HTTP Sens
INVALID_AUTH_KEY 401 Clé X-Kiosk-Auth-Key invalide pour ce device
UNKNOWN_DEVICE 401 X-Kiosk-Device-Id inconnu
VALIDATION_ERROR 400 Requête malformée ou champ invalide
UNKNOWN_PATIENT 404 Patient introuvable
UNKNOWN_APPOINTMENT 404 Rendez-vous introuvable
UNKNOWN_DOCUMENT 404 Document introuvable
ALREADY_CHECKED_IN 409 Check-in impossible car déjà effectué (voir sémantique check-in)
UPLOAD_TOO_LARGE 413 Upload au-delà de la taille max supportée
DECRYPTION_FAILED 400 Enveloppe chiffrée indéchiffrable (clé inconnue, tag invalide) — jamais retenté, jamais de fallback en clair
INTERNAL_ERROR 500 Erreur interne éditeur
NOT_SUPPORTED 501 DÉPRÉCIÉ — toutes les opérations sont obligatoires ; répondez la forme minimale conforme plutôt que 501

La borne retente les erreurs réseau et les 5xx (selon sa politique de retry), mais jamais les 4xx.

Anomalies

Les anomalies de check-in sont transmises par code métier vendor-neutral (ex. PR, DI), jamais par identifiant interne d'un éditeur. Le référentiel des codes provient de la configuration borne (serveur ApiBorne).

Matching côté borne

Le contrat renvoie des données patient/RDV pures. Le matching des critères d'admission et des messages d'information (kiosk informations) est effectué côté borne à partir de sa propre configuration — l'éditeur n'a rien à implémenter.

patients

Identification et mise à jour des patients

Identifier les patients et leurs RDV du jour

Recherche les patients correspondant aux critères (lecture carte de santé ou saisie manuelle) et renvoie, pour chacun, ses rendez-vous du jour éligibles au parcours borne.

  • Les critères sont combinés : l'éditeur DOIT utiliser tous les critères fournis.
  • birthDate seul ou lastName+firstName (+ birthDate) constituent le minimum utile ; socialSecurityId est prioritaire quand il est fourni.
  • Si context.config.identification.twoFieldsIdentification vaut true, l'éditeur DOIT aussi tenter les recherches croisées à deux champs (nom+date, prénom+date, nom+prénom) quand la recherche stricte ne donne rien.
  • Aucun patient trouvé → 200 avec patients: [] (pas une erreur).
  • Patient trouvé sans RDV du jour → une entrée avec appointments: [].
Authorizations:
(kioskAuthKeykioskDeviceId)
Request Body schema: application/json
required
object (KioskIntegrationContext)

Contexte transmis par la borne. Si config est fourni, l'éditeur DOIT l'utiliser et NE DOIT JAMAIS rappeler le serveur ApiBorne.

required
object (IdentifyCriteria)

Critères d'identification. Au minimum socialSecurityId, ou lastName + firstName (idéalement avec birthDate).

Responses

Request samples

Content type
application/json
Example
{
  • "context": {
    },
  • "criteria": {
    }
}

Response samples

Content type
application/json
{
  • "patients": [
    ],
  • "vendorData": { }
}

Mettre à jour les données administratives du patient

Met à jour les données administratives du patient (sémantique PATCH : seuls les champs présents dans patient sont modifiés ; un champ absent est inchangé ; null explicite efface la valeur si l'éditeur le supporte).

Après un 204, la borne recharge le rendez-vous via GET /appointments/{appointmentId} pour obtenir les données canoniques.

Authorizations:
(kioskAuthKeykioskDeviceId)
path Parameters
patientId
required
string <= 128 characters

Identifiant patient (patient.id d'une réponse précédente)

Request Body schema: application/json
required
object (KioskIntegrationContext)

Contexte transmis par la borne. Si config est fourni, l'éditeur DOIT l'utiliser et NE DOIT JAMAIS rappeler le serveur ApiBorne.

required
object (PatientUpdate)

Champs modifiables du patient (sémantique PATCH)

Responses

Request samples

Content type
application/json
{
  • "context": {
    },
  • "patient": {
    }
}

Response samples

Content type
application/json
{
  • "error": {
    }
}

appointments

Consultation des rendez-vous, prescripteur, check-in

Charger un RDV par code scanné ou saisi

Résout un rendez-vous à partir d'un code : contenu d'un QR code de convocation ou identifiant lisible communiqué au patient. L'éditeur décide des formats de code qu'il accepte ; la borne transmet le code tel quel (URL-encodé).

Authorizations:
(kioskAuthKeykioskDeviceId)
path Parameters
code
required
string <= 512 characters

Code scanné (QR) ou saisi par le patient, tel quel

Responses

Response samples

Content type
application/json
{
  • "patient": {
    },
  • "appointment": {
    },
  • "otherAppointments": [
    ],
  • "vendorData": { }
}

Identifier un RDV par numéro de ticket + date de naissance

Résout un rendez-vous du jour à partir du numéro de ticket émis au check-in ET de la date de naissance du patient (garde d'accès). C'est le parcours de l'app patient « Pass » (saisie manuelle : le patient tape le numéro imprimé sur son ticket et sa date de naissance).

L'éditeur accepte le format de ticket qu'il expose (brut 2 ou formaté RA-2) et vérifie que la naissance correspond au patient du RDV. Renvoie la même forme que by-code. Ticket+naissance non concordants → 404.

Authorizations:
(kioskAuthKeykioskDeviceId)
Request Body schema: application/json
required
object (KioskIntegrationContext)

Contexte transmis par la borne. Si config est fourni, l'éditeur DOIT l'utiliser et NE DOIT JAMAIS rappeler le serveur ApiBorne.

ticketNumber
required
string <= 64 characters

Numéro de ticket émis au check-in, tel que saisi/scanné par le patient. L'éditeur accepte le format qu'il expose (brut 2 ou formaté RA-2).

birthDate
required
string <date>

Date de naissance du patient (ISO YYYY-MM-DD) — garde d'accès

officePlaceVisibleId
required
string <= 128 characters

Identifiant du lieu de soins (officePlace) où le ticket a été émis. Requis : le numéro de ticket est recyclé par lieu, l'identification est scopée au lieu.

Responses

Request samples

Content type
application/json
{
  • "context": {
    },
  • "ticketNumber": "string",
  • "birthDate": "2019-08-24",
  • "officePlaceVisibleId": "string"
}

Response samples

Content type
application/json
{
  • "patient": {
    },
  • "appointment": {
    },
  • "otherAppointments": [
    ],
  • "vendorData": { }
}

Charger un RDV par identifiant

Recharge un rendez-vous déjà connu de la borne (après mise à jour du patient, ou en mode simulation). Renvoie la même forme que by-code.

Authorizations:
(kioskAuthKeykioskDeviceId)
path Parameters
appointmentId
required
string <= 128 characters

Identifiant du rendez-vous (appointment.id d'une réponse précédente)

Responses

Response samples

Content type
application/json
{
  • "patient": {
    },
  • "appointment": {
    },
  • "otherAppointments": [
    ],
  • "vendorData": { }
}

Refléter un changement de statut fait dans le Cockpit ApiBorne

Reflète chez l'éditeur un changement de statut effectué dans le Cockpit ApiBorne (accueil au guichet, fin de prise en charge) — l'agenda de l'éditeur reste la source de vérité et doit refléter l'état réel.

Progression UNIQUEMENT vers l'avant (checkedIninCaredone) : si le RDV est déjà à l'état demandé ou au-delà, l'appel est idempotent (200 sans effet). Un RDV annulé ou déjà terminé n'est pas modifiable (400 VALIDATION_ERROR).

Contrairement aux opérations borne, l'appel vient du serveur ApiBorne : seul le header X-Kiosk-Auth-Key est requis (pas de device, comme staff/sign-in), la clé devant correspondre à l'établissement du RDV.

Authorizations:
kioskAuthKey
path Parameters
appointmentId
required
string <= 128 characters

Identifiant du rendez-vous (appointment.id d'une réponse précédente)

Request Body schema: application/json
required
status
required
string
Enum: "checkedIn" "inCare" "done"

État cible du RDV

Responses

Request samples

Content type
application/json
{
  • "status": "checkedIn"
}

Response samples

Content type
application/json
{
  • "status": "checkedIn"
}

Renseigner le prescripteur du RDV

Enregistre le prescripteur du rendez-vous (typiquement après validation par le patient d'une proposition issue de l'analyse d'ordonnance). Opération idempotente : rejouer la même valeur donne le même état.

Note : le flux d'analyse d'ordonnance (analysis.prescriberProposals de la réponse d'upload) n'est pas activé pour les intégrations libres à ce stade — l'analyse a vocation à être portée par ApiBorne, pas exigée de l'éditeur. Il reste pleinement utilisé par l'intégration EasyDoct.

Authorizations:
(kioskAuthKeykioskDeviceId)
path Parameters
appointmentId
required
string <= 128 characters

Identifiant du rendez-vous (appointment.id d'une réponse précédente)

Request Body schema: application/json
required
object (KioskIntegrationContext)

Contexte transmis par la borne. Si config est fourni, l'éditeur DOIT l'utiliser et NE DOIT JAMAIS rappeler le serveur ApiBorne.

required
object (PractitionerRef)

Référence d'un praticien (prescripteur, médecin traitant…)

Responses

Request samples

Content type
application/json
{
  • "prescriber": {
    }
}

Response samples

Content type
application/json
{
  • "error": {
    }
}

Enregistrer l'arrivée du patient (check-in)

Enregistre l'arrivée du patient pour ce rendez-vous et déclenche, côté éditeur, la suite du parcours (mise en salle d'attente, notification des équipes…).

  • anomalyCodes : codes d'anomalies constatées pendant le parcours (référentiel fourni par la configuration borne, vendor-neutral).
  • Multi-RDV : quand le patient a plusieurs RDV du jour, la borne fait un check-in par RDV. Le premier appel porte sequence.number: 1 ; les suivants référencent le RDV principal via mainAppointmentId.
  • Idempotence recommandée : si le RDV est déjà check-in, l'éditeur DEVRAIT renvoyer 200 avec le ticket existant. 409 ALREADY_CHECKED_IN est réservé au cas où l'état du RDV rend le check-in réellement impossible.
  • ticketNumber/ticketNumberFormatted sont absents si l'éditeur ne gère pas de file d'appel (la borne peut alors générer un ticket local).
Authorizations:
(kioskAuthKeykioskDeviceId)
path Parameters
appointmentId
required
string <= 128 characters

Identifiant du rendez-vous (appointment.id d'une réponse précédente)

Request Body schema: application/json
required
object (KioskIntegrationContext)

Contexte transmis par la borne. Si config est fourni, l'éditeur DOIT l'utiliser et NE DOIT JAMAIS rappeler le serveur ApiBorne.

identifiedWithHealthCard
required
boolean

Le patient s'est identifié avec sa carte de santé (et non manuellement)

attendantCheckIn
boolean
Default: false

Check-in effectué par un accompagnant/brancardier (mode paramédical)

anomalyCodes
required
Array of strings[ items <= 32 characters ]

Codes des anomalies constatées pendant le parcours (référentiel de la configuration borne)

documentsComplete
boolean or null

Dossier documentaire complet au moment du check-in : tous les types de documents requis (requiredDocumentTypes de listAppointmentDocuments) sont fournis. Absent/null quand la borne ne gère pas les documents pour ce parcours (fonctionnalité désactivée ou groupe documents non supporté par l'éditeur). L'éditeur PEUT le tracer sur le dossier (indicateur « dossier complet/incomplet » à l'arrivée).

required
object

Position de ce RDV dans le parcours multi-RDV du patient

otherAppointmentsReadyForCheckIn
boolean
Default: false

Au moins un autre RDV du jour du patient est également prêt pour le check-in (indication pour le regroupement des notifications côté éditeur)

mainAppointmentId
string or null <= 128 characters

Identifiant du RDV principal (présent seulement pour les RDV liés, sequence.number > 1)

linkedAppointmentIds
Array of strings[ items <= 128 characters ]

Identifiants des autres RDV du jour inclus dans le même parcours

examId
string or null <= 128 characters

Identifiant d'examen de ce RDV

otherExamIds
Array of strings[ items <= 128 characters ]

Identifiants d'examen des autres RDV du parcours

object or null

Numéro de ticket proposé par la borne (réservé auprès du serveur ApiBorne avant le check-in). L'éditeur PEUT l'adopter comme numéro d'appel et DOIT l'accepter sans erreur s'il ne l'adopte pas. Quand la configuration borne est portée par ApiBorne, la borne affiche et imprime ce ticket quel que soit le contenu de CheckInResponse (le ticket éditeur est alors ignoré et tracé en log).

Responses

Request samples

Content type
application/json
Example
{
  • "context": {
    },
  • "identifiedWithHealthCard": true,
  • "attendantCheckIn": false,
  • "anomalyCodes": [
    ],
  • "sequence": {
    },
  • "examId": "exam-77",
  • "linkedAppointmentIds": [ ],
  • "otherExamIds": [ ]
}

Response samples

Content type
application/json
{
  • "ticketNumber": 0,
  • "ticketNumberFormatted": "string",
  • "vendorData": { }
}

Le dossier est-il prêt pour la notification des équipes ?

Indique si le dossier du rendez-vous est complet au sens de l'éditeur (documents requis présents, prescripteur renseigné…), c'est-à-dire si le check-in pourra notifier les équipes sans signaler un dossier incomplet. La borne s'en sert pour décider d'ajouter l'anomalie « dossier incomplet ».

Un éditeur sans notion de notification renvoie 200 { "ready": true } (jamais 501).

Authorizations:
(kioskAuthKeykioskDeviceId)
path Parameters
appointmentId
required
string <= 128 characters

Identifiant du rendez-vous (appointment.id d'une réponse précédente)

query Parameters
identifiedWithHealthCard
boolean
Default: false

Le patient s'est identifié avec sa carte de santé

sequenceNumber
integer >= 1
Default: 1

Rang du RDV dans le parcours multi-RDV (1 = principal)

examId
string <= 128 characters

Identifiant d'examen du RDV

otherExamIds
Array of strings[ items <= 128 characters ]

Identifiants d'examen des autres RDV du jour (séparés par des virgules)

Responses

Response samples

Content type
application/json
{
  • "ready": true,
  • "reason": "notificationNotConfigured",
  • "vendorData": { }
}

documents

Documents attachés à un rendez-vous

Lister les documents du RDV et les types attendus

Renvoie les documents déjà rattachés au rendez-vous et la liste des types de documents attendus (obligatoires) pour ce rendez-vous. La borne en déduit les documents manquants (comparaison sur documentType).

Authorizations:
(kioskAuthKeykioskDeviceId)
path Parameters
appointmentId
required
string <= 128 characters

Identifiant du rendez-vous (appointment.id d'une réponse précédente)

Responses

Response samples

Content type
application/json
{
  • "documents": [
    ],
  • "requiredDocumentTypes": [
    ],
  • "vendorData": { }
}

Uploader un document (pages images en base64)

Rattache un document au rendez-vous. Les pages sont des images (JPEG ou PNG) encodées en base64, dans l'ordre de lecture. L'éditeur est libre du stockage (conversion PDF, compression…).

  • Taille : l'éditeur DOIT accepter au moins 10 Mo par requête (JSON encodé) ; au-delà de sa limite, il répond 413 UPLOAD_TOO_LARGE. La borne limite ses uploads à la taille annoncée dans sa configuration.
  • rotationAngle est une indication de rotation à appliquer aux pages (sens horaire) ; un éditeur peut l'ignorer.
  • Si le document est une ordonnance (documentType: prescription) et que l'éditeur dispose d'une analyse automatique, il PEUT renvoyer analysis avec des propositions de prescripteur soumises au patient. Sinon, il omet simplement analysis. Intégrations libres : ce flux n'est pas activé à ce stade (la borne ne sollicite pas l'analyse ; l'IA a vocation à être portée par ApiBorne) — il reste utilisé par l'intégration EasyDoct.
  • Le remplacement d'un document existant se fait par DELETE préalable (la borne s'en charge).
Authorizations:
(kioskAuthKeykioskDeviceId)
path Parameters
appointmentId
required
string <= 128 characters

Identifiant du rendez-vous (appointment.id d'une réponse précédente)

Request Body schema: application/json
required
object (KioskIntegrationContext)

Contexte transmis par la borne. Si config est fourni, l'éditeur DOIT l'utiliser et NE DOIT JAMAIS rappeler le serveur ApiBorne.

documentType
required
string (DocumentType) <= 64 characters ^[A-Za-z][A-Za-z0-9_-]*$

Code de type de document, vendor-neutral. Le RÉFÉRENTIEL appartient à l'éditeur : il l'expose via GET /config/document-types (voir openapi-config.yaml) et peut y déclarer ses propres codes — la borne compare les codes tels quels (documents manquants, remplacement), le libellé affiché voyage toujours dans label.

Un vocabulaire standard de 41 codes est défini dans contract/document-types.md (prescription, mutualInsuranceCard, mriQuestionnaire… et other, valeur par défaut des types inconnus) : utilisez-le quand un code correspond — c'est lui qui garantit l'interopérabilité des configurations entre éditeurs. Un éditeur qui ne reconnaît pas un code le traite comme other.

required
Array of objects (DocumentPage) non-empty

Pages du document dans l'ordre de lecture

rotationAngle
integer
Default: 0
Enum: 0 90 180 270

Rotation (sens horaire) à appliquer aux pages — indication, ignorable

Responses

Request samples

Content type
application/json
{
  • "documentType": "prescription",
  • "rotationAngle": 0,
  • "pages": [
    ]
}

Response samples

Content type
application/json
{
  • "documentId": "string",
  • "analysis": {
    },
  • "vendorData": { }
}

Supprimer un document du RDV

Supprime un document rattaché au rendez-vous (utilisé par la borne avant de ré-uploader un document du même type). Supprimer un document déjà supprimé renvoie 404 UNKNOWN_DOCUMENT.

Authorizations:
(kioskAuthKeykioskDeviceId)
path Parameters
appointmentId
required
string <= 128 characters

Identifiant du rendez-vous (appointment.id d'une réponse précédente)

documentId
required
string <= 128 characters

Identifiant du document (documents[].id)

Responses

Response samples

Content type
application/json
Example
{
  • "error": {
    }
}

preparatorySurvey

Questionnaire préparatoire d'un rendez-vous (OPTIONNEL)

Résoudre (et créer si besoin) le questionnaire préparatoire d'un RDV

OPTIONNEL. Renvoie le questionnaire préparatoire attendu pour ce RDV, en le créant à la volée si la configuration de l'éditeur le prévoit, et renvoie son identifiant de résultat (surveyResultId) à charger ensuite via getPreparatorySurvey.

Un éditeur qui ne gère pas de questionnaire préparatoire (ou aucun attendu pour ce RDV) renvoie 200 { "surveyResultId": null, "completed": false } (ou 404 s'il n'expose pas la fonctionnalité) : la borne / l'app patient n'affiche alors pas de module questionnaire.

Authorizations:
(kioskAuthKeykioskDeviceId)
path Parameters
appointmentId
required
string <= 128 characters

Identifiant du rendez-vous (appointment.id d'une réponse précédente)

Responses

Response samples

Content type
application/json
{
  • "surveyResultId": "string",
  • "name": "string",
  • "completed": true
}

Charger la définition et les données d'un questionnaire préparatoire

OPTIONNEL. Renvoie la définition du questionnaire (schéma SurveyJS, jsonDef), les valeurs de préremplissage et les données déjà saisies. surveyResultId provient de ensurePreparatorySurvey.

Authorizations:
(kioskAuthKeykioskDeviceId)
path Parameters
surveyResultId
required
string <= 128 characters

Identifiant du résultat de questionnaire (surveyResultId de ensurePreparatorySurvey)

Responses

Response samples

Content type
application/json
{
  • "jsonDef": null,
  • "prefilledInfos": [
    ],
  • "existingData": { },
  • "alreadyDone": true
}

Soumettre les réponses d'un questionnaire préparatoire

OPTIONNEL. Enregistre les réponses du patient. data est l'objet de résultat SurveyJS (paires nom→valeur). Renvoie les éléments servant à générer le PDF du résultat (définition, réponses, entête/pied…).

Authorizations:
(kioskAuthKeykioskDeviceId)
path Parameters
surveyResultId
required
string <= 128 characters

Identifiant du résultat de questionnaire (surveyResultId de ensurePreparatorySurvey)

Request Body schema: application/json
required
object (KioskIntegrationContext)

Contexte transmis par la borne. Si config est fourni, l'éditeur DOIT l'utiliser et NE DOIT JAMAIS rappeler le serveur ApiBorne.

required
object

Objet de résultat SurveyJS (nom → valeur)

Responses

Request samples

Content type
application/json
{
  • "context": {
    },
  • "data": { }
}

Response samples

Content type
application/json
{
  • "jsonDef": "string",
  • "jsonResult": "string",
  • "patient": "string",
  • "appointmentStartDate": "string",
  • "officeName": "string",
  • "footer": "string"
}

Téléverser le PDF du questionnaire rempli

OPTIONNEL. Corps binaire application/pdf (le PDF est généré côté client à partir des réponses). Sans lui, le résultat n'est pas téléchargeable côté éditeur.

Authorizations:
(kioskAuthKeykioskDeviceId)
path Parameters
surveyResultId
required
string <= 128 characters

Identifiant du résultat de questionnaire (surveyResultId de ensurePreparatorySurvey)

Request Body schema: application/pdf
required
string <binary>

Responses

Response samples

Content type
application/json
Example
{
  • "error": {
    }
}

staff

Authentification du personnel d'accueil (Cockpit)

Authentifier un membre du personnel d'accueil (Cockpit)

Valide les identifiants d'un membre du personnel chez l'éditeur et renvoie les établissements auxquels il a accès. Utilisé par le serveur ApiBorne pour le login du Cockpit quand la source d'authentification est l'éditeur : ApiBorne rapproche ensuite chaque établissement de sa configuration locale (licence) pour établir la session. Contrairement aux autres opérations, seul le header X-Kiosk-Auth-Key est requis (pas de device : l'appel ne vient pas d'une borne). Identifiants invalides → 401 avec le code INVALID_CREDENTIALS.

Authorizations:
kioskAuthKey
Request Body schema: application/json
required
login
required
string <= 256 characters

Identifiant de connexion du membre du personnel (email ou login éditeur)

password
required
string <= 256 characters

Mot de passe (transmis uniquement en HTTPS)

Responses

Request samples

Content type
application/json
{
  • "login": "string",
  • "password": "string"
}

Response samples

Content type
application/json
{
  • "offices": [
    ],
  • "userEmail": "string",
  • "userDisplayName": "string",
  • "vendorData": { }
}