Guide intégrateur : les champs santé dans l'API

Vous consommez déjà les dossiers de Dématérialisation des Démarches Sociales par l'API. Cette page documente le seul delta santé : quatre types de champs propres à la plateforme (NIR, RPPS, FINESS établissement, FINESS entité juridique), la façon dont ils se distinguent des champs texte ordinaires, et le contrat de la fiche détaillée qu'ils transportent. Pour l'API générale, référez-vous à la documentation de Démarches numériques.

API GraphQL v2 Développeur intégrateur

Le concept : deux niveaux de valeur par champ

Un champ santé désigne une entité d'un annuaire national officiel : un établissement du FINESS (le Fichier National des Établissements Sanitaires et Sociaux), ou un praticien du RPPS (Répertoire Partagé des Professionnels intervenant dans le système de Santé). Quand l'usager sélectionne une entité, la plateforme fige deux choses de nature différente :

Le libellé et la fiche ne sont pas au même endroit

Le libellé composite (« numéro, raison sociale, code postal, ville ») est la valeur texte du champ, exposée par stringValue. La fiche, c'est-à-dire l'enregistrement structuré recopié de l'annuaire au moment de la sélection (une vingtaine de champs : adresse, statut juridique, dates, identifiants INSEE), vit dans un champ à part, data. Le numéro FINESS ou RPPS nu, isolé, se lit dans data.

Conséquence directe pour un intégrateur : parser le libellé pour en extraire le numéro est fragile (le séparateur « - » apparaît aussi dans certaines raisons sociales). La donnée exploitable par machine est data, et elle n'existe que sur l'API GraphQL v2.


Correspondance type de champ / type GraphQL

Trois des quatre champs santé ont un type GraphQL dédié. Le NIR (Numéro d'Inscription au Répertoire, le numéro de sécurité sociale) est servi comme un champ texte ordinaire, sans type dédié.

Type de champ Dématérialisation des Démarches Sociales et type GraphQL correspondant
Type de champ Type GraphQL (__typename) Expose data ?
FINESS établissement FinessChamp Oui
FINESS entité juridique FinessEjChamp Oui
RPPS RppsanteChamp Oui
NIR (numéro de sécurité sociale) TextChamp (pas de type dédié) Non

Le discriminant fiable est __typename. N'utilisez pas le libellé du champ pour discriminer. Un champ NIR se comporte à l'API exactement comme un champ texte : son numéro est dans stringValue, et il n'y a aucune fiche associée. Interrogez le type santé avec un fragment inline sur l'interface Champ :

{
  dossier(number: 123) {
    champs {
      __typename
      label
      stringValue
      ... on FinessChamp   { data }
      ... on FinessEjChamp { data }
      ... on RppsanteChamp { data }
    }
  }
}

FinessChamp, FinessEjChamp et RppsanteChamp implémentent tous l'interface Champ


Le contrat de data

data est un scalaire JSON non typé (une valeur JSON libre, opaque au schéma). L'introspection GraphQL n'en dit rien : elle vous donne data: JSON et rien de plus. Aucun client typé généré à partir du schéma ne connaîtra donc la forme interne de data. Vous devez lire chaque clé de manière défensive : sa valeur peut être nil ou vide.

Les clés ne sont pas arbitraires pour autant. Elles proviennent d'un jeu canonique par annuaire : 23 clés pour FINESS, 19 clés pour RPPS. Voici les grandes familles ; pour la liste exhaustive des noms de clés, référez-vous au schéma GraphQL et aux référentiels de données.

FINESS (23 clés)

Identifiants
finess, ej_finess (FINESS de l'entité juridique gestionnaire), siret, siren, type (ET établissement ou EJ entité juridique)
Dénominations
rs (raison sociale, le nom officiel), et_rs, ej_rs
Classification
statut_jur_lib, categ_lib_court, categ_etab_lib
Adresse
adresse_num_voie, adresse_type_voie, adresse_nom_voie, adresse_code_postal, adresse_lib_routage, commune, departement et deux compléments de voie
Dates
date_extract_finess, date_autorisation, date_ouverture

RPPS (19 clés)

Identifiants praticien
identifiant_pp, identification_nationale_pp, type_d_identifiant_pp
Identité
nom_d_exercice, prenom_d_exercice, libelle_civilite, libelle_civilite_d_exercice
Profession
libelle_profession, code_profession, libelle_categorie_professionnelle, libelle_savoir_faire, libelle_mode_exercice
Structure d'exercice
numero_siret_site, numero_finess_site, autorite_d_enregistrement, libelle_secteur_d_activite, raison_sociale_site
Localisation
code_postal_coord_structure, libelle_commune_coord_structure

Deux avertissements sur le remplissage réel de data :

  • data peut valoir null sur d'anciens dossiers dont le champ a été rempli avant que la fiche ne soit capturée. Prévoyez ce cas systématiquement.
  • Les clés canoniques sont toujours présentes ; leur valeur peut porter nil ou une chaîne vide. Un champ FINESS entité juridique, par exemple, renvoie les clés d'établissement avec une valeur vide. Lisez donc chaque valeur défensivement.

Le libellé (stringValue) contre la fiche (data)

stringValue (identique à value côté modèle) porte le libellé composite affiché à l'usager et à l'instructeur. Sa composition diffère selon l'annuaire :

Ce que porte chaque niveau de valeur
Champ stringValue (le libellé) Le numéro nu se lit dans
FINESS « 750100125 - HOPITAL COCHIN - 75014 PARIS » (numéro, raison sociale, code postal, ville) data.finess
RPPS « 10001234567 - Jean Martin - Médecin - 75014 - PARIS » (identifiant, nom, profession, code postal, commune) data.identifiant_pp

Ne reconstruisez jamais le numéro par découpage du libellé. Le numéro faisant foi est une clé de data ; le libellé sert à l'affichage humain.


RPPS : deux numérotations

Un praticien RPPS porte deux écritures de son identifiant, et vous rencontrerez les deux selon la source :

11 chiffres
La forme sans préfixe. C'est la valeur de data.identifiant_pp, celle que la recherche indexe.
12 chiffres commençant par 8
La forme préfixée. La recherche accepte une saisie à 12 chiffres préfixée 8 et la ramène aux 11 chiffres de identifiant_pp avant comparaison. Si vous transmettez un identifiant à 12 chiffres, seul le noyau à 11 chiffres est comparé.

Autrement dit : traitez un identifiant RPPS à 12 chiffres préfixé 8 et le même à 11 chiffres comme désignant le même praticien.


Limites et pièges

data n'est défini que sur les types GraphQL v2. Tout autre canal qui sérialise la valeur du champ ne transporte que le libellé composite. Si votre intégration a besoin de l'adresse, du SIRET (identifiant à quatorze chiffres attribué par l'INSEE à un établissement), du SIREN (identifiant à neuf chiffres de l'entreprise) ou des dates d'autorisation, vous devez passer par GraphQL v2 et lire data.

Comme le champ NIR est servi en TextChamp, il n'expose pas data. Un fragment ... on NirChamp n'existe pas dans le schéma et provoquerait une erreur de validation. Le numéro NIR est simplement la valeur de stringValue.

Parce que data est un scalaire JSON non typé, aucune valeur de clé n'est garantie renseignée. Un accès du type data["siret"] peut renvoyer null selon votre langage. Lisez chaque clé de manière défensive, et gérez explicitement le cas data == null.

FinessChamp désigne un site (type: "ET") ; FinessEjChamp désigne la structure gestionnaire (type: "EJ"). Les deux partagent le même schéma de clés, mais un champ « entité juridique » laisse les clés d'établissement (SIRET, ej_finess) sans valeur renseignée. Discriminez sur __typename.


À retenir

Checklist d'intégration pour récupérer la fiche santé :

  • Pour obtenir la fiche, GraphQL v2 est obligatoire : c'est le seul canal où data est défini.
  • Un fragment inline par __typename (FinessChamp, FinessEjChamp, RppsanteChamp) pour atteindre data ; le NIR se lit dans stringValue de son TextChamp.
  • Lecture nil-safe des clés de data : les clés sont présentes, leur valeur peut être nil ou vide, et data lui-même peut être null.