EN BREF
Les API des DSE (Dossiers de Santé Électroniques) permettent d'accéder aux dossiers patients stockés chez Epic, Cerner, Athenahealth. La plupart des DSE modernes supportent FHIR (Fast Healthcare Interoperability Resources), le standard d’échange pour les données de santé. L’authentification utilise OAuth 2.0 avec les extensions SMART on FHIR. Pour valider vos intégrations, testez les ressources FHIR et les flux d’authentification sur des environnements de test (sandboxes) avant la connexion en production. Apidog facilite la validation, l’envoi et l’automatisation de vos requêtes FHIR.
Essayez Apidog dès aujourd'hui
Introduction
Les Dossiers de Santé Électroniques centralisent diagnostics, médicaments, résultats de laboratoire, allergies et plans de traitement. Ces données sont stockées dans des plateformes DSE comme Epic, Cerner et Athenahealth.
Pour développer une application de santé connectée, il faut interagir avec ces systèmes via leurs API, et non par des extractions de fichiers. Les API de santé sont spécifiques : elles manipulent des données protégées (ISP), doivent être conformes à la HIPAA (États-Unis) et requièrent des flux d’authentification avancés.
La plupart des DSE modernes exposent FHIR, ce qui simplifie l’accès aux données. Mais l’authentification, la gestion des portées (scopes) et le mapping des données restent des étapes complexes.
Avec Apidog, vous pouvez :
- Tester des ressources FHIR sur des sandboxes publiques
- Valider la structure des données échangées
- Simuler votre intégration en toute sécurité avant de travailler avec des environnements réels
À la fin de ce guide, vous saurez :
- Comprendre la structure des ressources FHIR
- Authentifier une application avec SMART on FHIR
- Interroger les données patients (démographie, clinique)
- Créer et mettre à jour des ressources
- Automatiser vos tests avec Apidog
Comprendre FHIR
FHIR (Fast Healthcare Interoperability Resources) est la norme moderne pour les API de santé. Elle définit :
- Ressources : objets représentant des concepts de santé (Patient, Observation, Médication…)
- API REST : opérations standard pour ces ressources (GET, POST, PUT, DELETE)
- Formats : JSON et XML
Structure de l’URL de base
https://ehr.example.com/fhir/r4/{resource-type}/{id}
Exemple :
GET https://ehr.example.com/fhir/r4/Patient/123
Version de FHIR
La plupart des DSE utilisent FHIR R4 (Release 4). Ce guide couvre R4.
Types de ressources
| Ressource | Objectif |
|---|---|
| Patient | Données démographiques et administratives |
| Praticien | Prestataires de soins de santé |
| Organisation | Hôpitaux, cliniques |
| Observation | Résultats labo, signes vitaux |
| MedicationRequest | Prescriptions |
| Condition | Diagnostics, problèmes |
| Encounter | Visites, admissions |
| DocumentReference | Documents cliniques |
| AllergyIntolerance | Allergies et réactions |
Structure des ressources FHIR
Exemple de ressource Patient
{
"resourceType": "Patient",
"id": "123",
"active": true,
"name": [
{
"use": "official",
"family": "Smith",
"given": ["John", "Michael"]
}
],
"gender": "male",
"birthDate": "1985-03-15",
"address": [
{
"use": "home",
"line": ["123 Main St"],
"city": "Boston",
"state": "MA",
"postalCode": "02101",
"country": "USA"
}
],
"telecom": [
{
"system": "phone",
"value": "555-123-4567",
"use": "home"
},
{
"system": "email",
"value": "john.smith@example.com"
}
],
"identifier": [
{
"system": "http://hospital.example.org/mrn",
"value": "MRN-123456"
}
]
}
Exemple de ressource Observation
{
"resourceType": "Observation",
"id": "obs-123",
"status": "final",
"category": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
"code": "vital-signs",
"display": "Vital Signs"
}
]
}
],
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "8480-6",
"display": "Systolic blood pressure"
}
]
},
"subject": {
"reference": "Patient/123"
},
"effectiveDateTime": "2026-03-24T09:30:00Z",
"valueQuantity": {
"value": 120,
"unit": "mmHg",
"system": "http://unitsofmeasure.org",
"code": "mm[Hg]"
}
}
Authentification avec SMART on FHIR
SMART on FHIR étend OAuth 2.0 pour la santé, en ajoutant gestion du contexte patient et des scopes spécifiques.
Flux OAuth pour l’accès patient
Étape 1 : Récupérer la configuration SMART
GET https://ehr.example.com/fhir/r4/.well-known/smart-configuration
Réponse :
{
"authorization_endpoint": "https://ehr.example.com/oauth2/authorize",
"token_endpoint": "https://ehr.example.com/oauth2/token",
"scopes_supported": [
"patient/*.read",
"patient/*.write",
"user/*.read",
"launch/patient"
]
}
Étape 2 : Rediriger l’utilisateur pour l’autorisation
https://ehr.example.com/oauth2/authorize?
response_type=code&
client_id=YOUR_CLIENT_ID&
redirect_uri=https://yourapp.com/callback&
scope=patient/*.read&
state=random_state_value
Étape 3 : Échanger le code contre un access token
curl -X POST "https://ehr.example.com/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=AUTHORIZATION_CODE" \
-d "redirect_uri=https://yourapp.com/callback" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET"
Réponse :
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "patient/*.read",
"patient": "123"
}
Le champ patient contient l’ID du patient pour le contexte.
Portées SMART
| Portée | Accès |
|---|---|
patient/*.read |
Lire toutes les données du patient |
patient/Patient.read |
Lire uniquement les données démographiques |
patient/Observation.read |
Lire uniquement les observations |
user/*.read |
Lire toutes les données pour l’utilisateur |
launch/patient |
Lancer l’application avec le contexte patient |
Interrogation des données patient
Obtenir les données démographiques du patient
curl -X GET "https://ehr.example.com/fhir/r4/Patient/123" \
-H "Authorization: Bearer ACCESS_TOKEN"
Rechercher des observations
curl -X GET "https://ehr.example.com/fhir/r4/Observation?patient=123&category=vital-signs" \
-H "Authorization: Bearer ACCESS_TOKEN"
Réponse (bundle) :
{
"resourceType": "Bundle",
"type": "searchset",
"total": 5,
"entry": [
{
"resource": { ... Observation resource ... }
}
]
}
Paramètres de recherche courants
# Résultats labo par date
GET /Observation?patient=123&category=laboratory&date=gt2026-01-01
# Code LOINC spécifique
GET /Observation?patient=123&code=http://loinc.org|8480-6
# Médicaments actifs
GET /MedicationRequest?patient=123&status=active
# Diagnostics actifs
GET /Condition?patient=123&clinical-status=active
# Rencontres ambulatoires
GET /Encounter?patient=123&type=AMB
Pagination
Pour paginer les résultats :
GET /Observation?patient=123&_count=20
Réponse avec liens :
{
"link": [
{
"relation": "next",
"url": "https://ehr.example.com/fhir/r4/Observation?patient=123&_count=20&page=2"
}
]
}
Création et mise à jour des ressources
Créer une observation
curl -X POST "https://ehr.example.com/fhir/r4/Observation" \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: application/fhir+json" \
-d '{
"resourceType": "Observation",
"status": "final",
"code": {
"coding": [{
"system": "http://loinc.org",
"code": "8480-6",
"display": "Systolic blood pressure"
}]
},
"subject": {
"reference": "Patient/123"
},
"effectiveDateTime": "2026-03-24T09:30:00Z",
"valueQuantity": {
"value": 118,
"unit": "mmHg",
"system": "http://unitsofmeasure.org",
"code": "mm[Hg]"
}
}'
Mettre à jour un patient
curl -X PUT "https://ehr.example.com/fhir/r4/Patient/123" \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: application/fhir+json" \
-d '{
"resourceType": "Patient",
"id": "123",
"name": [{
"family": "Smith",
"given": ["John", "Michael"]
}],
"telecom": [{
"system": "phone",
"value": "555-999-8888",
"use": "home"
}]
}'
Spécificités des fournisseurs de DSE
Epic
- URL de base :
https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4/ - Sandbox :
https://fhir.epic.com/test/api/FHIR/R4/ - Documentation : https://fhir.epic.com
- Enregistrement obligatoire sur la marketplace pour la production
Cerner
- URL de base :
https://fhir-myrecord.cerner.com/r4/{tenant-id} - Sandbox :
https://fhir-deprecated.cerner.com/r4/ec2458f2-1e24-41c8-b71b-0e701af7583d - Documentation : https://docs.oracle.com/en/health/health-cerner/
Athenahealth
- URL de base :
https://api.platform.athenahealth.com/fhir/r4/{practice-id} - Sandbox via le programme développeur
- Documentation : https://docs.athenahealth.com
Tester avec Apidog
Les API de santé nécessitent des tests rigoureux. Les données des patients sont sensibles.
1. Utiliser des environnements de test publics
Testez vos requêtes sur des sandboxes FHIR :
# HAPI FHIR (open source)
https://hapi.fhir.org/baseR4
# Sandbox SMART Health IT
https://launch.smarthealthit.org
2. Valider les ressources FHIR
Utilisez des assertions pour automatiser la vérification des ressources :
pm.test('Resource is valid Patient', () => {
const response = pm.response.json()
pm.expect(response.resourceType).to.eql('Patient')
pm.expect(response.id).to.exist
pm.expect(response.name).to.be.an('array')
})
pm.test('Observation has required fields', () => {
const resource = pm.response.json()
pm.expect(resource.status).to.exist
pm.expect(resource.code).to.exist
pm.expect(resource.subject).to.exist
})
3. Tester le flux d’authentification
Stockez la configuration SMART dans un environnement de test :
AUTHORIZATION_ENDPOINT: https://ehr.example.com/oauth2/authorize
TOKEN_ENDPOINT: https://ehr.example.com/oauth2/token
CLIENT_ID: your_client_id
CLIENT_SECRET: your_client_secret
SCOPE: patient/*.read
Considérations de conformité
HIPAA
Aux USA, conformité HIPAA obligatoire pour toutes les applications manipulant des ISP :
- Transmission : TLS 1.2 minimum
- Stockage : chiffrement au repos
- Contrôle d’accès : audit, accès minimal
- BAA : Accord d’Associé Commercial avec le DSE
Sécurité SMART on FHIR
- Jetons valides 1h généralement
- Jetons de rafraîchissement pour sessions longues
- Contexte patient lié au scope du jeton
- Révocation du jeton à la déconnexion
Minimisation des données
N’utilisez que les scopes nécessaires :
-
Bon :
patient/Observation.read -
À éviter :
patient/*.readsauf nécessité
Erreurs courantes et solutions
401 Non autorisé
Cause : Jeton expiré/invalide
Solution : Rafraîchir le jeton avec le refresh_token.
403 Interdit
Cause : Scopes insuffisants
Solution : Revoyez les scopes autorisés à l’authentification.
404 Introuvable
Cause : Ressource inexistante
Solution : Vérifiez l’ID et le contexte patient du jeton.
422 Entité non traitable
Cause : Validation FHIR échouée
Solution : Corrigez les champs obligatoires et terminologies :
{
"resourceType": "OperationOutcome",
"issue": [{
"severity": "error",
"code": "required",
"details": {
"text": "Observation.status is required"
}
}]
}
Alternatives et comparaisons
| Caractéristique | Epic | Cerner | Athenahealth | OpenEMR |
|---|---|---|---|---|
| FHIR R4 | ✓ | ✓ | ✓ | Partiel |
| SMART on FHIR | ✓ | ✓ | ✓ | Non |
| Accès sandbox | ✓ | ✓ | Limité | Auto-hébergement |
| Documentation API | Excellente | Bonne | Bonne | Basique |
| Part de marché | Grands hôpitaux | Systèmes santé | Petits cabinets | Open source |
Epic et Cerner dominent les grands hôpitaux. Athenahealth cible plutôt les cabinets. OpenEMR est open source mais le support API reste limité.
Cas d’utilisation réels
Portail patient : Portail connecté à Epic, extraction des résultats labo, médicaments, rendez-vous. Authentification via SMART on FHIR.
Recherche clinique : Identification automatisée de patients éligibles à des essais cliniques via requêtes FHIR multi-systèmes et gestion du consentement.
Surveillance à distance : Intégration de télésanté, envoi d’observations (ex : tension) directement dans le DSE, visibles par les cliniciens.
En résumé
À retenir :
- FHIR est la norme API de la santé
- Les ressources FHIR représentent chaque concept de soins
- SMART on FHIR combine OAuth et contexte patient
- Chaque DSE a ses particularités d’implémentation
- Testez vos intégrations sur sandbox avant la production
Vos prochaines étapes :
- Explorez l’environnement de test HAPI FHIR
- Analysez les ressources FHIR pertinentes pour votre projet
- Inscrivez-vous aux programmes développeur DSE
- Testez vos flux sur Apidog avec des données fictives
- Implémentez la gestion des données conforme HIPAA
Testez les API FHIR avec Apidog - gratuit
FAQ
Quelle est la différence entre FHIR et HL7 v2 ?
HL7 v2 : messagerie hospitalière ancienne génération. FHIR : API REST moderne. Les nouveaux usages privilégient FHIR mais HL7 v2 reste courant dans les systèmes hérités.
Ai-je besoin d’un BAA pour utiliser les API des DSE ?
Oui, si vous traitez des ISP. Accord d’Associé Commercial (BAA) exigé entre entités couvertes et sous-traitants. Consultez l’équipe conformité du DSE.
Comment accéder à l’API FHIR d’Epic ?
Inscrivez-vous sur la marketplace App Orchard d’Epic. Pour tester, utilisez leur sandbox public. La production nécessite l’approbation hôpital.
Qu’est-ce qu’un contexte patient ?
Les jetons SMART on FHIR incluent un identifiant patient. Vos appels API sont limités à ce patient, ce qui protège la confidentialité.
Puis-je écrire des données dans les DSE ?
Oui, avec restrictions. Généralement : création d’observations, mise à jour démographie patient. Diagnostics/médicaments : approbation clinique souvent requise.
Comment gérer les codes de terminologie ?
FHIR s’appuie sur des standards :
- LOINC (labos, observations)
- SNOMED CT (concepts cliniques)
- CIM-10 (diagnostics)
- RxNorm (médicaments)
Respectez ces systèmes lors de la création de ressources.
Qu’en est-il de la santé internationale ?
FHIR est mondial. Chaque pays peut avoir ses guides d’implémentation (ex : US Core). Référez-vous aux profils de votre région.

Top comments (0)