Vérifier un numéro RPPS avec l'API Annuaire Santé (FHIR R4)

14/04/2026
Authentifier un médecin via Pro Santé Connect confirme son identité professionnelle. Mais PSC ne garantit pas que ce médecin est toujours en exercice. Un praticien suspendu, radié ou retraité conserve ses identifiants un certain temps. La vérification du numéro RPPS contre l'Annuaire Santé de l'ANS est le filet de sécurité qui complète l'authentification.
Ce tutoriel couvre l'ensemble du processus : obtenir une clé API, construire la requête FHIR, parser la réponse, et intégrer le tout dans un backend NestJS. Comptez 10 minutes de lecture.
Pourquoi vérifier le RPPS est indispensable
Le numéro RPPS (Répertoire Partagé des Professionnels de Santé) est l'identifiant national unique de chaque professionnel de santé en France. Il est attribué à vie par l'Ordre professionnel concerné.
Pro Santé Connect vous fournit ce numéro dans le claim SubjectNameID (préfixé par 8). Le problème : PSC authentifie l'identité, pas le statut d'exercice. Entre deux connexions, un médecin peut avoir été :
- Suspendu par son Ordre (faute disciplinaire, problème de santé)
- Radié définitivement
- Retraité et non remplacé dans le système
- Décédé, le délai de mise à jour des annuaires étant variable
Pour une plateforme de téléconsultation, laisser un médecin radié réaliser des actes médicaux expose à des risques juridiques majeurs. La vérification RPPS à chaque connexion est la bonne pratique recommandée par l'ANS.
L'API Annuaire Santé en bref
L'Annuaire Santé est la base de données nationale de référence des professionnels de santé. Il agrège les données du RPPS, de FINESS (établissements), des cartes CPx, de MSSanté et d'Ameli.
L'ANS expose ces données via une API REST conforme à FHIR R4 (Fast Healthcare Interoperability Resources). FHIR est le standard international d'interopérabilité en santé. Si vous ne connaissez pas FHIR, retenez trois choses :
- Les données sont structurées en ressources (Practitioner, Organization, HealthcareService...)
- Les réponses sont des Bundles contenant une ou plusieurs ressources
- L'API suit les conventions REST classiques (GET, paramètres de recherche, pagination)
L'API est hébergée sur le gateway gateway.api.esante.gouv.fr et gérée par la plateforme Gravitee. L'accès en lecture est libre après obtention d'une clé API, sans authentification lourde.
La documentation officielle est sur ansforge.github.io/annuaire-sante-fhir-documentation.
Obtenir sa clé API
L'API Annuaire Santé est gratuite. L'accès se fait en trois étapes :
- Créer un compte sur le portail portail.openfhir.annuaire.sante.fr
- S'abonner à l'API "Annuaire Santé FHIR" depuis le catalogue du portail
- Récupérer la clé API dans votre espace développeur
La clé se transmet via le header HTTP GRAVITEE-API-KEY dans chaque requête. Aucun token OAuth, aucun certificat : un simple header suffit.
Requête FHIR pas à pas : vérifier un praticien
L'endpoint
GET https://gateway.api.esante.gouv.fr/fhir/v1/Practitioner
?identifier=http://rpps.fr|{RPPS_NUMBER}
Le paramètre identifier utilise la syntaxe FHIR system|value. Le system http://rpps.fr identifie le référentiel RPPS, et la valeur est le numéro RPPS du praticien (sans le préfixe 8 du SubjectNameID PSC).
La réponse
{
"resourceType": "Bundle",
"type": "searchset",
"total": 1,
"entry": [
{
"resource": {
"resourceType": "Practitioner",
"identifier": [
{
"system": "http://rpps.fr",
"value": "10101234567"
}
],
"active": true,
"name": [
{
"family": "MARTIN",
"given": ["Marie"]
}
],
"qualification": [
{
"code": {
"coding": [
{
"system": "urn:oid:1.2.250.1.213.1.6.1.109",
"code": "SM26",
"display": "Médecine générale"
}
]
}
}
]
}
}
]
}
Les 4 vérifications à effectuer
| # | Vérification | Champ | Condition |
|---|---|---|---|
| 1 | Le praticien existe | bundle.total |
>= 1 |
| 2 | Le praticien est en exercice | entry[0].resource.active |
=== true |
| 3 | La qualification correspond | qualification[].code.coding[].code |
Cohérent avec le SubjectRole PSC |
| 4 | Le nom correspond | name[0].family / name[0].given |
Cross-check avec les claims PSC |
La vérification #2 est la plus critique : c'est elle qui filtre les médecins suspendus ou radiés. Les vérifications #3 et #4 sont des contrôles de cohérence supplémentaires.
Implémentation NestJS
Le service de vérification
// auth/services/rpps-verification.service.ts
import { Injectable, Logger } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { ConfigService } from '@nestjs/config';
import { Cache } from 'cache-manager';
import { Inject } from '@nestjs/common';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
@Injectable()
export class RppsVerificationService {
private readonly logger = new Logger(RppsVerificationService.name);
constructor(
private httpService: HttpService,
private configService: ConfigService,
@Inject(CACHE_MANAGER) private cacheManager: Cache,
) {}
async verify(rppsNumber: string): Promise<boolean> {
// Vérifier le cache (TTL 24h)
const cacheKey = `rpps:${rppsNumber}`;
const cached = await this.cacheManager.get<boolean>(cacheKey);
if (cached !== undefined && cached !== null) {
return cached;
}
try {
const url = `${this.configService.get('ANNUAIRE_SANTE_URL')}/fhir/v1/Practitioner`;
const response = await this.httpService.axiosRef.get(url, {
params: {
identifier: `http://rpps.fr|${rppsNumber}`,
},
headers: {
'GRAVITEE-API-KEY': this.configService.get(
'ANNUAIRE_SANTE_API_KEY',
),
},
});
const bundle = response.data;
if (!bundle.entry?.length) {
await this.cacheManager.set(cacheKey, false, 86400000); // 24h
return false;
}
const practitioner = bundle.entry[0].resource;
const isActive = practitioner.active === true;
await this.cacheManager.set(cacheKey, isActive, 86400000);
return isActive;
} catch (error) {
this.logger.error(
`RPPS verification failed for ${rppsNumber}: ${error.message}`,
);
// En cas d'erreur API, on refuse l'accès par précaution
return false;
}
}
}
Stratégie de cache
Le statut d'exercice d'un praticien ne change pas à la minute. Mettre en cache le résultat pendant 24 heures est un bon compromis entre sécurité et performance :
- Un médecin vérifié le matin reste valide toute la journée
- L'API Annuaire Santé n'est pas surchargée de requêtes identiques
- En cas d'indisponibilité temporaire de l'API, les médecins récemment vérifiés peuvent continuer à travailler
Si vous avez besoin d'une vérification plus stricte (plateforme à haut risque), réduisez le TTL à 1 heure. Ne descendez pas en dessous : l'API a des limites de rate.
Variables d'environnement
# Annuaire Santé (vérification RPPS)
ANNUAIRE_SANTE_URL=https://gateway.api.esante.gouv.fr
ANNUAIRE_SANTE_API_KEY=your-gravitee-api-key
Les pièges à connaître
1. Passer le RPPS avec le préfixe 8. Le SubjectNameID de PSC est au format 8{RPPS}. L'API Annuaire attend le numéro RPPS seul, sans le préfixe. Pensez à faire subjectNameId.substring(1) avant d'appeler l'API.
2. Oublier le system dans le paramètre identifier. La syntaxe FHIR exige identifier=http://rpps.fr|{number}. Sans le system http://rpps.fr, la recherche ne retourne rien ou retourne des résultats inattendus.
3. Ne pas gérer les erreurs API. L'API peut retourner des 429 (rate limit) ou des 503 (maintenance). Prévoyez un comportement par défaut : refuser l'accès en cas d'échec (fail closed) est plus sûr que de laisser passer (fail open).
4. Cacher le résultat trop longtemps. Au-delà de 24 heures de cache, le risque de laisser passer un médecin radié augmente. Inversement, vérifier à chaque requête HTTP de votre app (pas juste à la connexion) surcharge l'API inutilement. Vérifiez à la connexion, cachez pour la session ou pour 24h.
5. Ignorer le champ active. La simple existence du praticien dans l'annuaire ne suffit pas. Un médecin radié reste dans l'annuaire avec active: false. Seul le champ active === true confirme le droit d'exercice.
FAQ
L'API Annuaire Santé est-elle gratuite ?
Oui. L'accès en lecture à l'API FHIR est gratuit après inscription sur le portail openfhir. Aucun frais d'abonnement ni de volume. Il suffit d'une clé API transmise dans le header GRAVITEE-API-KEY.
Peut-on vérifier un RPPS sans Pro Santé Connect ?
Oui. L'API Annuaire Santé est indépendante de PSC. Vous pouvez l'appeler avec n'importe quel numéro RPPS, quelle que soit la source. En pratique, vous obtenez le RPPS via PSC lors de l'authentification, mais l'API elle-même n'exige pas de lien avec PSC.
À quelle fréquence vérifier le RPPS ?
La recommandation de l'ANS est de vérifier à chaque connexion. Le statut d'un praticien peut changer entre deux sessions (suspension, radiation). Un cache de 24 heures maximum est un bon compromis pour ne pas surcharger l'API tout en maintenant une vérification régulière.
L'API fonctionne-t-elle pour les pharmaciens et infirmiers ?
Oui. L'Annuaire Santé couvre tous les professionnels inscrits au RPPS : médecins, pharmaciens, chirurgiens-dentistes, sages-femmes, infirmiers, masseurs-kinésithérapeutes, et d'autres. Le endpoint Practitioner et le paramètre identifier fonctionnent de la même manière pour tous.
Conclusion
La vérification RPPS via l'API FHIR de l'Annuaire Santé est simple à implémenter : une requête GET, un header API key, et quatre champs à vérifier dans la réponse. Combinée à Pro Santé Connect pour l'authentification, elle constitue le socle de sécurité de toute application de santé conforme.
Besoin d'intégrer l'authentification e-santé de bout en bout ? Chez Bob le développeur, on accompagne les projets santé de l'architecture au déploiement. Contactez-nous.
