h1. API Authentic {{>toc}} h2. Notes de version | Version | Auteur | Remarque | | 0.1 | bdauvergne | Première version, manque la définition du format pour la description des comptes et des erreurs | 15122016 | | 0.2 | mates | Ajout paramètres pour l'envoi de mail à la création | 08032017 | | 0.3 | bdauvergne | Mise à jour pour conformité avec la liste des attributs du compte | 21032017 | | 0.4 | bdauvergne, mates | URLs, ex modified__gte, envoi email à la création, forcer changement de mot de passe, test existence en masse | 26062017 | | 0.5 | jkouka, mates | Correction valeurs attributs gender, utilisation des alias d'attributs, ajouts appels suppression fédération FC et envvoi jeton réinit mot de passe | 10072017 | | 0.6 | bdauvergne, mates | Ajout du service de modification d'une adresse de messagerie | 31082017 | | 0.7 | mates | Ajout des attributs FranceConnect | 01092017 | | 0.8 | mates | Contrôle sur les attributs | 10102017 | | 0.9 | mates | Précisions sur la pagination | 16022018 | | 0.10 | bdauvergne | Première ébauche API validation des comptes | 05032018 | | 0.11 | bdauvergne, mates | Version initiale API validation des comptes | 14032018 | | 0.12 | mates | Corrections mineures sur API validation des comptes | 23042018 | | 0.13 | mates | Corrections sur les urls, corrections mineures diverses | 24042018 | | 0.14 | bdauvergne | Ajout code schema-error pour API de validation des identités | 25042018 | | 0.15 | bdauvergne | Ajout paramètre page pour le code d'erreur justificatifs-bad-format pour l'API de validation des identités | 25042018 | | 0.16 | bdauvergne | Ajout remarque sur le WS de test des comptes en masse | 02072018 | | 0.17 | mates | Publication sur projet Authentic | 30072018 | h2. Disclaimer *Il s'agit d'un travail en cours. Certaines des fonctionnalités présentées peuvent ne pas être encore disponibles dans authentic mais uniquement dans authentic2-cut.* h2. Aperçu Cette API offre la possibilité de créer, lire, modifier et rechercher et supprimer (CRUD) des utilisateurs. h2. Transport HTTP obligatoire h2. Style de l'interface REST/JSON h2. Authentification L'authentification se fait via un login et un mot de passe en utilisant le mode d'authentification HTTP Basic. h2. Contrôle d'accès En utilisant la fonctionnalité des rôles affectés aux utilisateurs techniques il est possible d'autoriser ou non les différentes actions: créer, modifier, rechercher, supprimer. h3. Contrôle sur les attributs La valeur d'un champs de téléphone peut débuter par un '+'. Elle ne doit ensuite contenir que des chiffres, maximum 20. Les champs nom et prénoms de naissance sont limités à 64 caractères. Les autres champs sont limités à 256 caractères. h2. Liste/recherche un compte | URL | Méthode | Contenu | Paramètres | | @/api/users/@ | GET | document JSON | voir plus loin | h3. Paramètres | Nom | Sémantique | Valeurs permises | Exemple | | ordering | Permet de passer le nom d'un champ par lequel les réponses seront ordonnées, préfixé par @-@ l'ordre est inversé, ex.: @ordering=last_name@ | @[-]date_joined@, @[-]modified@, @[-]first_name@, @[-]last_name@ | | @first_name@ | recherche exacte sur le prénom pour une valeur exacte | | | | @first_name__iexact@ | recherche exacte sur le prénom pour une valeur exacte en ignorant la casse | | | | @first_name__icontains@ | recherche exacte sur le prénom pour une sous chaîne en ignorant la casse | | | | @first_name__gte@ | recherche sur le prénom supérieure ou égale à la valeur | | | | @first_name__lte@ | recherche sur le prénom inférieure ou égale à la valeur | | | | @first_name__gt@ | recherche sur le prénom supérieure à la valeur | | | | @first_name__lt@ | recherche sur le prénom inférieure à la valeur | | | | @last_name@ + @__iexact@, @__icontains@, @__gte@, @__lte@, @__gt@, @__lt@ | idem que pour le prénom mais avec le nom | | | | @modified__gte@ | recherche sur la date de dernière modification supérieure ou égale à la valeur | date et heure au format ISO-8601: YYYY-MM-DDTHH:MM:SS | curl -X GET -u partenaire:geronimo https://connexion-grandlyon.dev.entrouvert.org/api/users/?modified__gte=2017-03-28T00:00:00| | @modified__lte@ | recherche sur la date de dernière modification inférieure ou égale à la valeur | date et heure au format ISO-8601: YYYY-MM-DDTHH:MM:SS | | | @modified__gt@ | recherche sur la date de dernière modification supérieure à la valeur | date et heure au format ISO-8601: YYYY-MM-DDTHH:MM:SS | | | @modified__lt@ | recherche sur la date de dernière modification inférieure à la valeur | date et heure au format ISO-8601: YYYY-MM-DDTHH:MM:SS | | | @email@ | recherche sur le courriel exact | | | | @email__iexact@ | recherche sur le courriel exact en ignorant la casse | | | h3. Format retour Le document retour est un objet/dictionnaire JSON, les résultats sont toujours paginés, chaque page a une taille de 100, le lien vers la page suivante est dans la propriété @next@ et celui vers la page @précédente@ dans la propriété @previous@. La propriété @results@ contient la liste des résultats. Les résultats contiennent les propriétés suivantes: | Propriété | Description | Format | | sub | identifiant | chaîne hexadécimal | | first_name | prénom | chaîne quelconque | | given_name | idem (alias) | idem | | last_name | nom | chaîne quelconque | | family_name | idem (alias) | idem | | email | courriel | courriel | | gender | genre de la personne | male ou female | | birthdate | date de naissance | format ISO8601: YYYY-MM-DD | | birthplace | lieu de naissance | chaîne quelconque | | birthplace_insee | code INSEE du lieu de naissance | code INSEE (https://www.insee.fr/fr/information/2114819) | | birthcountry | pays de naissance | chaîne quelconque | | birthcountry_insee | code INSEE du pays de naissance | code INSEE (https://www.insee.fr/fr/information/2028273) | | birthdepartment | nom du département de naissance | chaîne quelconque | | preferred_givenname | prénom préféré | chaîne quelconque | | preferred_username | nom préféré | chaîne quelconque | | comment | commentaire | chaîne quelconque | | title | civilité | "Monsieur" ou "Madame" | | address_number | adresse: numéro de voie | chaîne quelconque | | address_street | adresse: type et nom de la voie | chaîne quelconque | | address_complement | adresse: complément d'adresse | chaîne quelconque | | address_zipcode | adresse: code postal | chaîne quelconque | | address_city | adresse: nom de la ville | chaîne quelconque | | address_country | adresse: pays | chaîne quelconque | | address_fc | attribut address fournie par FranceConnect | Object JSON tel que défini dans les "spécifications OpenIDConnect 1.0":https://openid.net/specs/openid-connect-basic-1_0.html#AddressClaim | | home_phone | téléphone fixe personnel | Peut commencer par un '+'. Ne contient ensuite que des chiffres, maximum 20. | | home_mobile_phone | téléphone fixe personnel | Peut commencer par un '+'. Ne contient ensuite que des chiffres, maximum 20. | | professional_phone | téléphone fixe professionnel | Peut commencer par un '+'. Ne contient ensuite que des chiffres, maximum 20. | | professional_mobile_phone | téléphone fixe professionnel | Peut commencer par un '+'. Ne contient ensuite que des chiffres, maximum 20. | | phone_number_fc | attribut phone fourni par FranceConnect | chaîne quelconque | | modified | date dernière mofification | date et heure au format ISO-8601: YYYY-MM-DDTHH:MM:SS | | validated | statut de validation du compte | booléen | | validation_date | date de validation du compte | format ISO8601: YYYY-MM-DD | | validation_context | contexte de validation | énumération: "FC" ou "online" ou "office" | h3. Exemple cas-passant
GET /api/users/ HTTP/1.1
Authorization: Basic xxx

200 Ok
Content-Type: application/json
Content-Length: xxxx

{
    "next": "https://cresson.entrouvert.org/api/users/?cursor=XYZ",
    "previous": null,
    "results": [
        {
            "address_city": "",
            "address_complement": "",
            "address_country": "",
            "address_fc": {
                "country": "France",
                "formatted": "26 rue Desaix, 75015 Paris",
                "locality": "Paris",
                "postal_code": "75015",
                "region": "Ile-de-France",
                "street_address": "26 rue Desaix"
            },
            "address_number": "",
            "address_street": "",
            "address_zipcode": "",
            "birthcountry": "FRANCE",
            "birthcountry_insee": "99100",
            "birthdate": "1981-06-23",
            "birthdepartment": "",
            "birthplace": "GIF-SUR-YVETTE",
            "birthplace_insee": "91272",
            "comment": null,
            "creation_domain": null,
            "creation_mode": null,
            "creation_partner": null,
            "date_joined": "2017-07-25T08:41:40.998793Z",
            "email": "eric.mercier@france.fr",
            "email_verified": true,
            "family_name": "Mercier",
            "first_name": "Eric",
            "gender": "male",
            "given_name": "Eric",
            "home_mobile_phone": "",
            "home_phone": "",
            "is_active": true,
            "last_name": "Mercier",
            "modified": "2017-08-31T15:16:29.690864Z",
            "phone_number_fc": null,
            "preferred_givenname": "",
            "preferred_username": null,
            "professional_mobile_phone": "",
            "professional_phone": "",
            "sub": "YTIBAQB9-fZcwZKt7k28P_towGlszsW0uDvxq5hd_zQOJhGBJ1qP3FYajF-JUY6ug_Ekw8k",
            "title": "Monsieur",
            "validated": "True",
            "validation_context": "FC",
            "validation_date": "2017-08-31"
        },
        ...
    ]
}
h3. Cas non-passant | Code | Signification | Contenu | | 400 | Le format de la requête est invalide (paramètre interdit ou avec une valeur invalide) | Un document JSON décrivant les erreurs rencontrées | | 401 | L'authentification a échouée | | | 403 | Permission non accordée d'effectuer l'action | | h3. Pagination des résultats La réponse d'un cas passant contient au maximum 100 comptes. Si le résultat est supérieur à 100 comptes, le résultat se découpe en plusieurs pages et la réponse à la requête initiale ne contient que les 100 premiers comptes de la liste. Il faut ensuite parcourir les pages suivantes en interrogeant l'url spécifiée dans le champs @next@ de la réponse et cela jusqu'à ce que le champs @next@ soit à @null@. Par exemple :
GET /api/users/ HTTP/1.1
Authorization: Basic xxx

200 Ok
Content-Type: application/json
Content-Length: xxxx

{
    "next": "https://moncompte.grandlyon.com/api/users/?cursor=XYZ",
    "previous": null,
    "results": [
        {
...
Le champs @next@ indique qu'il y a une autre page de résultat que l'on obtient par la requête :
GET /api/users/?cursor=XYZ HTTP/1.1
Authorization: Basic xxx

200 Ok
Content-Type: application/json
Content-Length: xxxx

{
    "next": null,
    "previous": "https://moncompte.grandlyon.com/api/users/?cursor=ABC",
    "results": [
        {
...
h2. Création d'un compte | URL | Méthode | Contenu | Paramètres | | /api/users/ | POST | document JSON décrivant le compte à créer (à spécifier) | non | h3. Format entrée Le document en entrée est un object/dictionnaire JSON avec les propriétés suivantes: | Propriété | Description | Valeur requise | Valeur permise | | first_name | prénom | oui | chaîne quelconque | | last_name | nom | oui | chaîne quelconque | | email | courriel | non | courriel | | gender | genre de la personne | non | entier: 1 = homme, 2 = femme | | birthdate | date de naissance | non | format ISO8601: YYYY-MM-DD | | birthplace | lieu de naissance | non | chaîne quelconque | | birthplace_insee | code INSEE du lieu de naissance | non | code INSEE (https://www.insee.fr/fr/information/2114819) | | birthcountry | pays de naissance | non | chaîne quelconque | | birthcountry_insee | code INSEE du pays de naissance | non | code INSEE (https://www.insee.fr/fr/information/2028273) | | birthdepartment | nom du département de naissance | non | chaîne quelconque | | preferred_givenname | prénom préféré | non | chaîne quelconque | | preferred_username | nom préféré | non | chaîne quelconque | | comment | commentaire | non | chaîne quelconque | | title | civilité | non | "Monsieur" ou "Madame" | | address_number | adresse: numéro de voie | non | chaîne quelconque | | address_street | adresse: type et nom de la voie | non | chaîne quelconque | | address_complement | adresse: complément d'adresse | non | chaîne quelconque | | address_zipcode | adresse: code postal | non | chaîne quelconque | | address_city | adresse: nom de la ville | non | chaîne quelconque | | address_country | adresse: pays | non | chaîne quelconque | | home_phone | téléphone fixe personnel | non | Peut commencer par un '+'. Ne contient ensuite que des chiffres, maximum 20. | | home_mobile_phone | téléphone fixe personnel | non | Peut commencer par un '+'. Ne contient ensuite que des chiffres, maximum 20. | | professional_phone | téléphone fixe professionnel | non | Peut commencer par un '+'. Ne contient ensuite que des chiffres, maximum 20. | | professional_mobile_phone | téléphone fixe professionnel | non | Peut commencer par un '+'. Ne contient ensuite que des chiffres, maximum 20. | | send_registration_email | Envoyer un email à la création de compte terminer l'enregistrement. | non | "True" | | send_registration_email_next_url | Adresse sur laquelle rediriger l'utilisateur après l'enregistrement. | URL valide | Les valeurs @null@ ne sont pas autorisées. La validité INSEE des champs birthplace, birthplace_insee, birthcountry et birthcountry_insee, ainsi que la cohérence entre birthplace et birthplace_insee et entre birthcountry et birthcountry_insee, est à la charge du client. h3. Exemple
POST /api/users/ HTTP/1.1 
Content-Type: application/json
Authorization: Basic xxxx
Content-Length: xxx

{
    "email": "john.doe@example.com",
    "first_name": "John",
    "last_name": "Doe",
    "gender": 1,
    "email": "john.doe@example.com",
    "birthdate": "1981-06-01",
    "birthplace": "Marseille",
    "birthcountry": "France",
    "preferred_username": "john",
    "address_city": "New-York",
    "send_registration_email": "True",
    "send_registration_email_next_url": "http://www.entrouvert.com"
}
h3. Retour passant
201 Created
Content-Type: application/json
Content-Length: xxx

{
        "sub": "8e7f200b4bb447fa8a91cd03c0f0ade3",
        "first_name": "john",
        "given_name": "john",
        "last_name": "doe",
        "family_name": "doe",
        "email": "john.doe@entrouvert.com",
        "modified": "2017-03-20T13:16:44.991343Z",
        "birthplace_insee": null,
        "gender": "1",
        "birthcountry_insee": null,
        "title": null,
        "birthdate": "1981-06-01",
        "birthplace": "Marseille",
        "birthcountry": "France",
        "preferred_username": "john
        "preferred_givenname": null,
        "address_number": null,
        "address_street": null,
        "address_complement": null,
        "address_zipcode": null,
        "address_city": "New-York",
        "address_country": null,
        "birthdepartment": null,
        "comment": null,
        "validated": null,
        "validation_date": null,
        "validation_context": null,
        "home_phone": null,
        "home_mobile_phone": null,
        "professional_phone": null,
        "professional_mobile_phone": null
}
h3. Retour non-passant | Code | Signification | Contenu | | 400 | Le format de la requête est invalide (JSON mal formaté, attribut manquant, etc..) | Un document JSON décrivant les erreurs rencontrées | | 401 | L'authentification a échouée | | | 403 | Permission non accordée d'effectuer l'action | |
HTTP/1.1 400 BAD REQUEST
Content-Type: application/json
Content-Length: xxxx

{
    "errors": {
        "last_name": [
            "Ce champ est obligatoire."
        ]
    },
    "result": 0
}
h3. Extension get-or-create et update-or-create Dans certains cas il sera souhaite de créer uniquement si un utilisateur équivalent n'existe pas déjà (avec un même mail ou nom d'utilisateur), dans ce cas on pourra ajouter autant de fois que nécessaire les paramètres @get_or_create@ ou @update_or_create@ à l'URL pour indiquer les champs concernés. Ces deux champs sont exclusifs (on ne peut pas utiliser @get_or_create@ et @update_or_create@ en même temps). Les différents comportements dépendent du résultat de la recherche : * si aucun utilisateur n'est trouvé la création a lieu normalement, * si un utilisateur est trouvé : ** pour @get_or_create@, l'utilisateur est retourné avec un code @200 Ok@ au lieu de @201 Created@ mais aucune modification ne lui est apporté, les données postées sont ignorées, ** pour @update_or_create@, l'utilisateur est mis à jour avec les données postées puis retourné avec un code @200 Ok@, * si plusieurs utilisateurs sont trouvés l'opération échouera avec une erreur. Exemple (*email* dans l'URL doit être écrit littéralement, il ne faut pas indiquer un courriel ou une variable)
POST /api/users/?get_or_create=email HTTP/1.1 
Content-Type: application/json
Authorization: Basic xxxx
Content-Length: xxx


{
    "email": "john.doe@example.com",
    "first_name": "John",
    "last_name": "Doe",
    "gender": 1,
    "email": "john.doe@example.com",
    "birthdate": "1981-06-01",
    "birthplace": "Marseille",
    "birthcountry": "France",
    "preferred_username": "john",
    "address_city": "New-York",
    "send_registration_email": "True",
    "send_registration_email_next_url": "http://www.entrouvert.com"
}
200 Ok
Content-Type: application/json



{
        "sub": "8e7f200b4bb447fa8a91cd03c0f0ade3",
        "first_name": "john",
        "given_name": "john",
        "last_name": "doe",
        "family_name": "doe",
        "email": "john.doe@examle.com",
        "modified": "2017-03-20T13:16:44.991343Z",
}
Exemple avec clé multiple :
POST /api/users/?update_or_create=first_name&update_or_create=last_name HTTP/1.1 
Content-Type: application/json
Authorization: Basic xxxx
Content-Length: xxx


{
    "email": "john.doe2@example.net",
    "first_name": "john",
    "last_name": "doe",
}
200 Ok
Content-Type: application/json



{
        "sub": "8e7f200b4bb447fa8a91cd03c0f0ade3",
        "first_name": "John",
        "given_name": "Doe",
        "last_name": "doe",
        "family_name": "doe",
        "email": "john.doe2@examle.com",
        "modified": "2017-03-20T13:16:44.991343Z",
}
h2. Lecture d'un comptes | URL | Méthode | Contenu | Paramètres | | /api/users// | GET | document JSON décrivant le compte lu | non |
GET /api/users// HTTP/1.1
Authorization: Basic xxxx

h3. Retour passant | Code | Signification | Contenu | | 200 | Un document JSON décrivant le compte |
200 Ok
Content-Type: application/json
Content-Length: xxxx

{
        "sub": "8e7f200b4bb447fa8a91cd03c0f0ade3",
        "first_name": "john",
        "given_name": "john",
        "last_name": "doe",
        "family_name": "doe",
        "email": "john.doe@example.com",
        "modified": "2017-03-20T13:16:44.991343Z",
        "birthplace_insee": null,
        "gender": "1",
        "birthcountry_insee": null,
        "title": null,
        "birthdate": "1981-06-01",
        "birthplace": "Marseille",
        "birthcountry": "France",
        "preferred_username": "ben",
        "preferred_givenname": null,
        "address_number": null,
        "address_street": null,
        "address_complement": null,
        "address_zipcode": null,
        "address_city": "New-York",
        "address_country": null,
        "birthdepartment": null,
        "comment": null,
        "validated": null,
        "validation_date": null,
        "validation_context": null,
        "home_phone": null,
        "home_mobile_phone": null,
        "professional_phone": null,
        "professional_mobile_phone": null
}
Les propriétés sans valeur sont à @null@. h3. Retour non-passant | Code | Signification | Contenu | | 401 | L'authentification a échouée | | | 403 | Permission non accordée d'effectuer l'action | | | 404 | L'id compte donné n'existe pas | | voir plus haut h2. Modification d'un comptes | URL | Méthode | Contenu | Paramètres | | /api/users// | PUT | document JSON décrivant le compte | non | | /api/users// | PATCH | document JSON décrivant le compte | non |
PATCH /api/users// HTTP/1.1 
Content-Type: application/json
Authorization: Basic xxxx
Content-Length: xxx

{
    "validated": "True",
    "validation_date": "2016-11-23",
    "validation_context": "FC"
}
L'action PUT nécessite que @first_name@ et @last_name@ (obligatoires) soient dans le document JSON. S'ils ne sont pas renseignés, une erreur 400 est retournée. La validité INSEE des champs birthplace, birthplace_insee, birthcountry et birthcountry_insee, ainsi que la cohérence entre birthplace et birthplace_insee et entre birthcountry et birthcountry_insee, est à la charge du client. *Attention : gender, family_name et given_name sont des alias des attributs title, last_name et firstname, avec gender où Madame est traduit en female et Monsieur en male. Lorsque l'on souhaite modifier ces attributs, cela doit porter sur les attributs title, last_name et firstname et non sur gender, family_name et given_name.* *Attention : l'attribut email n'est pas modifiable par ce service. Sa modification nécessite l'utilisation d'un "service dédié au changement d'email":#Envoyer-un-jeton-pour-modifier-lemail* h3. Retour passant | Code | Signification | Contenu | | 200 | Ok | Un document JSON décrivant le compte modifié |
200 Ok
Content-Type: application/json
Content-Length: xxx

{
        "sub": "8e7f200b4bb447fa8a91cd03c0f0ade3",
        "first_name": "john",
        "given_name": "john",
        "last_name": "doe",
        "family_name": "doe",
        "email": "john.doe@example.com",
        "modified": "2017-03-20T13:16:44.991343Z",
        "birthplace_insee": null,
        "gender": "1",
        "birthcountry_insee": null,
        "title": null,
        "birthdate": "1981-06-01",
        "birthplace": "Marseille",
        "birthcountry": "France",
        "preferred_username": "ben",
        "preferred_givenname": null,
        "address_number": null,
        "address_street": null,
        "address_complement": null,
        "address_zipcode": null,
        "address_city": "New-York",
        "address_country": null,
        "birthdepartment": null,
        "comment": null,
        "validated": "True",
        "validation_date": null,
        "validation_context": null,
        "home_phone": null,
        "home_mobile_phone": null,
        "professional_phone": null,
        "professional_mobile_phone": null
}
h3. Retour non-passant | Code | Signification | Contenu | | 400 | Le format de la requête est invalide (JSON mal formaté, attribut manquant, etc..) | Un document JSON décrivant les erreurs rencontrées | | 401 | L'authentification a échouée | | | 403 | Permission non accordée d'effectuer l'action | | | 404 | L'id compte donné n'existe pas | |
HTTP/1.1 400 BAD REQUEST
Content-Type: application/json
Content-Length: xxxx

{
    "errors": {
        "last_name": [
            "Ce champ est obligatoire."
        ]
    },
    "result": 0
}
h2. Suppression d'un compte | URL | Méthode | Contenu | Paramètres | | /api/users// | DELETE | aucun | non |
DELETE /api/users// HTTP/1.1
Authorization: Basic xxx

h3. Retour passant | Code | Signification | Contenu | | 204 | Ok | aucun |
204 No content
h3. Retour non-passant | Code | Signification | Contenu | | 400 | Le format de la requête est invalide (JSON mal formaté, attribut manquant, etc..) | Un document JSON décrivant les erreurs rencontrées | | 401 | L'authentification a échouée | | | 403 | Permission non accordée d'effectuer l'action | | | 404 | L'id compte donné n'existe pas | JSON d'erreur | h2. Forcer le changement de mot de passe à la prochaine connexion | URL | Méthode | Contenu | Paramètres | | /api/users//force-password-reset/ | POST | aucun | non |
POST /api/users//force-password-reset/ HTTP/1.1
Authorization: Basic xxx

h3. Retour passant | Code | Signification | Contenu | | 204 | Ok | aucun |
204 No content
h3. Retour non-passant | Code | Signification | Contenu | | 400 | Le format de la requête est invalide (JSON mal formaté, attribut manquant, etc..) | Un document JSON décrivant les erreurs rencontrées | | 401 | L'authentification a échouée | | | 403 | Permission non accordée d'effectuer l'action | | | 404 | L'id compte donné n'existe pas | JSON d'erreur | h2. Tests d'existence des comptes en masse Ce web-service doit être utilisé pour la propagation des suppressions de compte. L'appel peut-être fait soit au moment de la détection d'une collision (compte nouveau arrivant avec un email existant), avec envoi du sub du compte existant, soit en masse régulièrement, avec envoi en plusieurs fois (par paquet de 100) de la totalité des subs connus. | URL | Méthode | Contenu | Paramètres | | /api/users/synchronization/ | POST | Document JSON contenant la liste des ID compte à tester | non |
POST /api/users/synchronization/ HTTP/1.1
Authorization: Basic xxx
Content-Type: application/json
Content-Length: xxxx

{
    "known_uuids":["e46d46ebcb1d4d6bac4571159b542389", "1234567890"],
}
h3. Retour passant
200 Ok
Content-Type: application/json
Content-Length: xxxx

{
    "unknown_uuids":["1234567890"],
    "result":1
}
h3. Retour non-passant | Code | Signification | Contenu | | 400 | Le format de la requête est invalide (JSON mal formaté, attribut manquant, etc..) | Un document JSON décrivant les erreurs rencontrées | | 401 | L'authentification a échouée | | | 403 | Permission non accordée d'effectuer l'action | |
400 BadRequest
Content-Type: application/json
Content-Length: xxxx

{    
    "detail":"JSON parse error - Expecting ',' delimiter: line 1 column 53 (char 52)"
}
h2. Supprimer une fédération FranceConnect | URL | Méthode | Contenu | Paramètres | | /api/users//fc-unlink/ | DELETE | aucun | non |
DELETE /api/users//fc-unlink/ HTTP/1.1
Authorization: Basic xxx

h3. Retour passant | Code | Signification | Contenu | | 204 | Ok | aucun |
204 No content
h3. Retour non-passant | Code | Signification | Contenu | | 400 | Le format de la requête est invalide (JSON mal formaté, attribut manquant, etc..) | Un document JSON décrivant les erreurs rencontrées | | 401 | L'authentification a échouée | | | 403 | Permission non accordée d'effectuer l'action | | 404 | L'id compte donné n'existe pas | JSON d'erreur | h2. Envoyer un jeton pour reinitialisation de mot de passe | URL | Méthode | Contenu | Paramètres | | /api/users//password-reset/ | POST | aucun | non |
POST /api/users//password-reset/ HTTP/1.1
Authorization: Basic xxx

h3. Retour passant | Code | Signification | Contenu | | 204 | Ok | aucun |
204 No content
h3. Retour non-passant | Code | Signification | Contenu | | 400 | Le format de la requête est invalide (JSON mal formaté, attribut manquant, etc..) | Un document JSON décrivant les erreurs rencontrées | | 401 | L'authentification a échouée | | | 403 | Permission non accordée d'effectuer l'action | | 404 | L'id compte donné n'existe pas | JSON d'erreur | | 500 | L'utilisateur identifié par l'id compte n'a pas de couriel | JSON d'erreur | h2. Envoyer un jeton pour modifier l'email | URL | Méthode | Contenu | Paramètres | | /api/users//email/ | POST | aucun | non |
POST /api/users//email/ HTTP/1.1
Authorization: Basic xxx

{"email": "nouvelemail@example.com"}
h3. Retour passant | Code | Signification | Contenu | | 204 | Ok | aucun |
200 No content
Content-Type: application/json

{"result": 1}
h3. Retour non-passant | Code | Signification | Contenu | | 400 | Le format de la requête est invalide (JSON mal formaté, attribut manquant, etc..) | Un document JSON décrivant les erreurs rencontrées | | 401 | L'authentification a échouée | | | 403 | Permission non accordée d'effectuer l'action | | 404 | L'id compte donné n'existe pas | JSON d'erreur | h2. Demande de validation de compte Pour éviter les problématiques de validation des pièces jointes, seul le format JPEG est autorisé au niveau de l'API portée par le compte. Charge aux clients de l'API de convertir d'autres formats en JPEG. | URL | Méthode | Contenu | Paramètres | | /api/users//validate/ | POST | application/json | non |
POST /api/users//validate/ HTTP/1.1
Authorization: Basic xxx
Content-Type: application/json

Le champ @external_id@ représente l'identifiant de la demande dans le SI du demandeur, il permet d'empêcher les doublons. Le couple (@id_compte@, @external_id@) doit être unique, sinon la création de la demande est rejetée.
{
    "justificatifs": [{
       "b64_content": "..."
    }],
    "external_id": "XYZ1234"
}
Le champs @justificatifs@ est une liste de dictionnaire contenant une unique clé @b64_content@. Chaque dictionnaire représente une page du justificatif, jusqu'à 2. Chaque page doit peser moins de 300Ko, sinon la demande est rejetée, et doit être un fichier JPEG encodé en base64 dans une chaîne JSON. h3. Retour passant | Code | Signification | Contenu | | 201 | Created | application/json |
201 Created
Content-Type: application/json

{
   "result": 1,
   "status": "received",
   "sub": "xyz1234543534535",
   "external_id": "32423424324",
   "id": 123
}
h3. Retour non passant À noter qu'il est interdit de créer plusieurs demandes pour un même @external_id@ pour un partenaire donné mais que plusieurs demandes pour un même @id_compte@ (même usager) peuvent être créée. C'est au partenaire de décider dans son système s'il autorise cela. | Code | Signification | Contenu | | 400 | Le format de la requête est invalide (JSON mal formaté, attribut manquant, etc..) | Un document JSON décrivant les erreurs rencontrées | | 404 | L'id compte donné n'existe pas | | | 401 | L'authentification a échoué | | | 403 | Permission non accordée d'effectuer l'action | | | 413 | Entity too large | la requête dépasse la limite dur du serveur web (disons 5x la limite par justificatif) |
400 Bad Request
Content-Type: application/json

{
   "result": 0,
   "errors": [
       {
          'code': 'justificatifs-bad-format',
          'page': 0,
          'accepted': ['image/jpeg'],
       },
       {
          'code': 'justificatifs-too-big',
          'page': 0,
          'max-size': '300000',
       }
       {
          'code': 'already-exists',
       }
   ]
}
Liste des codes d'erreur | Code | Paramètres | Signification | | justificatifs-bad-format | page: l'index du justificatif qui pose problème, accepted: la liste des types MIME acceptés | une des pièces jointes n'est pas dans un des formats autorisés | | justificatifs-too-big | page: l'index du justificatif qui pose problème, max-size: la taille maximum acceptée | une des pièces jointes dépasse la taille autorisée | | already-exists | Aucun | la demande a déjà été créé | | schema-error | field: le champ JSON concerné sub-errors: une liste de chaîne expliquant l'erreur ou un dictionnaire si l'erreur est dans un sous-champ (ici uniquement b64_content) | le format du document JSON envoyé ne correspond pas à ce qui est attendu. Ce code signale une erreur dans le code appelant qui ne respecte pas le format du document JSON attendu. | h2. Lister les demandes de validation La liste est paginée (comme pour le listing des compte), par groupe de 100. L'ordre est l'ordre croissant de la date de création. Voir cette "section":#Pagination-des-r%C3%A9sultats pour l'utilisation de la pagination. Les demandes traitées ayant plus d'un mois sont purgées. | URL | Méthode | Contenu | Paramètres | | /api/validate/ | GET | non | voir plus loin | | /api/users//validate/ | GET | non | voir plus loin | La version avec l'@id_compte@ ne liste que les demandes concernant cet ID compte. h3. Paramètres | Nom | Sémantique | Valeurs permises | Exemple | | validated__gt | Liste les demandes validées, acceptées (@"status": "accepted"@) ou refusées (@"status": "refused"@) après la date indiquée. *Ne s'applique que sur /api/validate/*. | date et heure au format ISO-8601: YYYY-MM-DDTHH:MM:SSZ | | h3. Retour passant | Code | Signification | Contenu | | 200 | OK | application/json |
200 OK
Content-Type: application/json

{
    "next": null,
    "previous": null,
    "result": 1,
    "results": [
        {
            "created": "2018-04-24T06:49:37.371577Z",
            "external_id": "7",
            "id": 9,
            "reason": "",
            "status": "received",
            "sub": "YTIBAQCbZndVIpit-Eog-Y-33sFBf9hTbHYa4YVxDfqW6kwmJWo3_5glGQtGbzQI7FajXtw",
            "validated": null
        },
        ...
        {
            "created": "2018-04-23T17:03:16.791785Z",
            "external_id": "4",
            "id": 6,
            "reason": "",
            "status": "accepted",
            "sub": "YTIBAQCbZndVIpit-Eog-Y-33sFBf9hTbHYa4YVxDfqW6kwmJWo3_5glGQtGbzQI7FajXtw",
            "validated": "2018-04-23T17:06:52.623275Z"
        },
        {
            "created": "2018-04-23T17:01:46.458133Z",
            "external_id": "3",
            "id": 5,
            "reason": "underaged",
            "status": "refused",
            "sub": "YTIBAQCbZndVIpit-Eog-Y-33sFBf9hTbHYa4YVxDfqW6kwmJWo3_5glGQtGbzQI7FajXtw",
            "validated": "2018-04-23T17:04:52.121961Z"
        },
        {
            "created": "2018-04-23T16:59:24.773830Z",
            "external_id": "2",
            "id": 4,
            "reason": "unreadable",
            "status": "refused",
            "sub": "YTIBAQCbZndVIpit-Eog-Y-33sFBf9hTbHYa4YVxDfqW6kwmJWo3_5glGQtGbzQI7FajXtw",
            "validated": "2018-04-23T17:01:02.989202Z"
        },
        {
            "created": "2018-04-23T16:44:24.223940Z",
            "external_id": "1",
            "id": 3,
            "reason": "invalid",
            "status": "refused",
            "sub": "YTIBAQCbZndVIpit-Eog-Y-33sFBf9hTbHYa4YVxDfqW6kwmJWo3_5glGQtGbzQI7FajXtw",
            "validated": "2018-04-23T16:57:50.874902Z"
        },
        ...
    ]
}
Le champ @status@ peut contenir trois valeurs différentes : * @received@ pour les nouvelles demande non encore traitées, * @accepted@ pour les demandes acceptées, * @refused@ pour les demandes refusées, la raison se trouvant dans le champ @reason@ qui est une chaîne de texte. Le champ @reason@ est un code parmi les valeurs suivantes : | Valeur | Signification | | unreadable | L'agent n'est pas parvenu à lire la ou les pièces jointes. | | invalid | La pièce jointe ne correspond pas à une pièce jointe acceptable (à déterminer dans la convention de partenariat et pas dans du code) ou elle n'est pas complète ou elle est périmée. | | underaged | L'usager est mineur. | Lorsqu'une demande passe du statut @"received"@ à @"accepted"@ ou @"refused"@, la date de la transition est conservée dans le champs @validated@. Le fait de filtrer à l'aide de @validated__gt@ ne renvoie que des demandes validées (@"status": "accepted"@ ou @"status": "refused"@), donc dont le champs @validated@ n'est pas @null@. h3. Retour non passant | Code | Signification | Contenu | | 401 | L'authentification a échoué | | | 403 | Permission non accordée d'effectuer l'action | | | 404 | L'id compte donné n'existe pas | |