Inscrire et répartir les apprenants#
Une fois le dossier créé, deux étapes : la liste des apprenants, puis leur répartition dans des sessions. Les mêmes que dans l'espace client.
Toutes les routes de ce guide sont sous /dossiers/{dossier_id}/inscriptions. Portées : clients:apprenants:write et clients:dossiers:read. Le dossier doit être à l'étape inscriptions_ouvertes.
Ni numéro de sécurité sociale ni situation de handicap ne transitent par l'API : l'apprenant renseigne ces informations lui-même dans son espace, après l'inscription. Vous fournissez une identité minimale.
L'état des inscriptions#
GET …/inscriptions renvoie tout ce dont vous avez besoin, et le renvoie après chaque écriture :
{
"dossier_id": "…", "numero": "DEV-2026-1400",
"stage": "inscriptions_ouvertes", "allowed_actions": ["set_apprenants", "validate_inscriptions"],
"step": "step1", "locked": false, "total_places": 4,
"lignes": [
{ "id": "L1…", "formation_label": "R482, 3 catégories, expérimenté", "caces_recommendation": "R482", "categories": ["A", "C1"], "nb_apprenants": 4 }
],
"apprenants": [],
"sessions_candidates": [
{ "numero": "S-2026-0412", "formation_label": "…", "date_debut": "2026-10-05", "date_fin": "2026-10-09", "horaires": "8h30 – 17h00",
"centre_label": "Centre de Gennevilliers", "caces_recommendation": "R482", "caces_categories": ["A", "C1"],
"capacite_max": 8, "inscrits_count": 3, "places_restantes": 5, "can_add_apprenant": true }
]
}
step:step1(liste et lignes),step2(répartition),done(verrouillé).lignes: les lignes du devis ; chaque apprenant doit être rattaché à une ou plusieurs lignes.sessions_candidates: les sessions compatibles avec les lignes du dossier, avec leurs places. Vous choisissez parmi elles.- La réponse porte un en-tête
ETag: conservez-le, il est exigé sur les écritures (voir Idempotence et concurrence).
Étape 1 : La liste des apprenants#
PUT …/inscriptions/apprenants remplace la liste. Chaque apprenant indique les lignes qu'il suit.
ETAG=$(curl -s -D - -o /dev/null "https://developer.elrm.app/sandbox/v1/dossiers/{dossier_id}/inscriptions" \
-H "Authorization: Bearer pk_test_…" | grep -i '^etag:' | cut -d' ' -f2 | tr -d '\r')
curl -X PUT "https://developer.elrm.app/sandbox/v1/dossiers/{dossier_id}/inscriptions/apprenants" \
-H "Authorization: Bearer pk_test_…" \
-H "If-Match: $ETAG" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"apprenants": [
{ "nom": "Martin", "prenom": "Lucas", "email": "l.martin@exemple.fr", "telephone": "06 12 34 56 78", "date_naissance": "1991-04-12", "ligne_ids": ["L1…"] },
{ "nom": "Bernard", "prenom": "Inès", "email": "i.bernard@exemple.fr", "telephone": "", "date_naissance": "1988-09-30", "ligne_ids": ["L1…"] }
]
}'
base = f"/dossiers/{dossier_id}/inscriptions"
state = api.get(base)
etag = state.headers["ETag"]
ligne_id = state.json()["lignes"][0]["id"]
r = api.put(f"{base}/apprenants", json={"apprenants": [
{"nom": "Martin", "prenom": "Lucas", "email": "l.martin@exemple.fr",
"telephone": "06 12 34 56 78", "date_naissance": "1991-04-12", "ligne_ids": [ligne_id]},
{"nom": "Bernard", "prenom": "Inès", "email": "i.bernard@exemple.fr",
"date_naissance": "1988-09-30", "ligne_ids": [ligne_id]},
]}, headers={"If-Match": etag, "Idempotency-Key": str(uuid.uuid4())})
r.raise_for_status()
etag = r.headers["ETag"] # nouvel ETag pour la suite
apprenants = r.json()["apprenants"] # chacun a maintenant un id
- Pour modifier un apprenant existant, renvoyez-le avec son
id; sansid, c'est une création. Un apprenant absent de la liste est retiré, sauf s'il est déjà engagé sur une session (can_delete: false). - Carnet du client : à l'ouverture, la liste peut déjà contenir des personnes connues d'un dossier précédent, marquées
carnet: true. Elles ne sont inscrites que si vous les gardez dans votrePUT; les omettre les détache de ce dossier, sans rien supprimer ailleurs. Relisez doncGET …/inscriptionsavant votre premierPUTplutôt que d'envoyer une liste construite à l'aveugle. date_naissanceau formatYYYY-MM-DD.- Sans
If-Match:428.If-Matchpérimé :412, relisez et recommencez.
Quand la liste est complète : POST …/inscriptions/etape-1/valider → step = step2.
Étape 2 : La répartition#
Pour chaque apprenant et chaque ligne, choisissez une session parmi sessions_candidates :
curl -X PUT "https://developer.elrm.app/sandbox/v1/dossiers/{dossier_id}/inscriptions/apprenants/{apprenant_id}/session" \
-H "Authorization: Bearer pk_test_…" \
-H "Content-Type: application/json" \
-d '{ "ligne_id": "L1…", "session_numero": "S-2026-0412" }'
for a in apprenants:
for lid in a["ligne_ids"]:
api.put(f"{base}/apprenants/{a['id']}/session",
json={"ligne_id": lid, "session_numero": "S-2026-0412"}).raise_for_status()
La réponse est l'état complet, sessions_candidates[].places_restantes mis à jour. Une session pleine a can_add_apprenant: false.
Pour retirer un placement : DELETE …/apprenants/{apprenant_id}/session/{ligne_id}.
Besoin de revenir à la liste ? POST …/inscriptions/etape-1/rouvrir ramène à step1 (tant que la validation finale n'a pas eu lieu).
Validation finale#
curl -X POST "https://developer.elrm.app/sandbox/v1/dossiers/{dossier_id}/inscriptions/valider" \
-H "Authorization: Bearer pk_test_…" \
-H "Idempotency-Key: $(uuidgen)"
Tous les apprenants doivent être placés sur toutes leurs lignes. La validation crée les inscriptions, verrouille le dossier (locked: true, step: done, stage: inscriptions_validees) et passe la main à l'organisme : convocations, convention, documents d'entrée en formation. À partir de là, plus aucune écriture n'est possible par l'API, une modification passe par ELRM.
Résumé du flux#
GET …/inscriptions → ETag, lignes, sessions_candidates
PUT …/inscriptions/apprenants (If-Match) → apprenants[].id
POST …/inscriptions/etape-1/valider → step2
PUT …/apprenants/{id}/session × N → placements
POST …/inscriptions/valider → done, dossier verrouillé
Anciennes routes#
POST /inscriptions et GET /inscriptions (« demandes d'inscription » à examiner par l'organisme) sont dépréciées et ne sont plus attribuées aux nouvelles clés. Les intégrations existantes continuent de fonctionner ; vous serez prévenus par email avant tout retrait.