1Démarrage
Trois choses : une URL, une clé, un en-tête. Rien de plus pour la première requête.
| Élément | Valeur |
|---|---|
| URL de base | https://demo.scellance.com (migrera vers api.scellance.com) |
| Authentification | En-tête X-API-Key: <votre clé> |
| Versionnage | Préfixe /v1/ sur toutes les routes |
| Format | JSON (requêtes et réponses) |
curl -s https://demo.scellance.com/v1/chain/verify \ -H "X-API-Key: sc_live_7PaL-vwRtQMhFz-_wybkXSOG5ZTjwVsqfF6uqQWkWkw" # -> {"verified": true, "checked": N, ...} (200) # sans cle -> 401. Reference interactive complete : /docs (Swagger).
2Le flux en 4 gestes
Scellance ne trie jamais (zéro ML). Votre moteur décide, Scellance greffe. Le principe : sceller la fiche de poste, puis chaque décision qui la cite.
a. Sceller la fiche de poste (avant toute décision)
La grille de critères est figée et horodatée. Toute décision devra référencer cette version exacte.
{
"reference": "fiche:{jobId}:v1",
"content": { "titre": "...", "criteres": [ ... ] }
}
# -> renvoie content_hash + sealed_at. A refaire (v2, v3...) a chaque modif de la grille.b. Sceller chaque décision de tri
Les explications que votre matching produit déjà deviennent les criteria : chacun DOIT citer sa source dans la fiche (source_ref), sinon l'API refuse (422). Le candidat n'est qu'une référence opaque (RGPD).
{
"event_type": "decision.screening",
"actor": { "type":"system", "id":"votre-moteur", "role":"algorithme" },
"subject": { "candidate_ref": "cand_a1b2c3" },
"job": { "job_id":"{jobId}", "referential":"fiche:{jobId}:v1" },
"outcome": { "decision":"shortlist", "score_total":0.82, "rank":3 },
"criteria": [
{ "criterion_id":"experience", "source_ref":"fiche:{jobId}:v1#experience",
"weight":0.3, "score":0.8, "threshold":0.6, "passed":true }
]
}c. Superviser : confirmation ou override humain (AI Act art. 14)
Le recruteur reste décideur. Un override exige un motif (sinon 422) et un acteur humain.
{ "event_type":"decision.human_override",
"actor":{ "type":"human", "id":"recruteur-07", "role":"recruteur" },
"subject":{...}, "job":{...},
"outcome":{ "decision":"rejection", "original_decision":"shortlist", "motif":"..." } }d. Vérifier l'intégrité
{ "verified": true, "checked": 128 }
# toute alteration d'un evenement passe casse la chaine -> verified:false. Detectable par un tiers.3Exports d'audit, à la demande
Les livrables que le déployeur (votre client, ou une collectivité) doit produire, générés depuis le journal.
Journal (art. 12)
GET /v1/exports/journal - extrait intégral et ordonné.
Notice de transparence (art. 13)
GET /v1/exports/notice - pré-remplie pour le DPO.
Trame FRIA (art. 27)
GET /v1/exports/fria - sections techniques pré-remplies.
Contrefactuel candidat
GET /v1/candidates/{ref}/counterfactual - droit à l'explication.
4Supervision et webhooks
En mode strict, chaque décision automatique émet un webhook supervision.pending : votre UI affiche une corbeille de validation avant toute notification au candidat.
- GET /v1/supervision/pending : la corbeille (sans donnée personnelle).
- POST /v1/webhooks : s'abonner. Le secret n'est renvoyé qu'une fois.
- Chaque livraison est signée HMAC-SHA256 avec ce secret : vérifiez la signature à la réception.
5Idempotence, erreurs, versions
- Idempotence : en-tête Idempotency-Key sur POST /v1/events - un rejeu renvoie le même événement, sans doublon.
- Versionnage : toutes les routes sous /v1/. Pas de rupture sans nouvelle version.
- Règles bloquantes (422) : un criterion sans source_ref ; une décision citant un référentiel non scellé ; un override sans motif.
6SDK
Deux SDK sans dépendance, miroir l'un de l'autre. Idempotency-Key gérée nativement.
import { ScellanceClient } from "@scellance/sdk"; const sc = new ScellanceClient(process.env.SCELLANCE_BASE_URL, process.env.SCELLANCE_API_KEY); await sc.sealReferential(`fiche:${jobId}:v1`, { titre, criteres }); await sc.screening({ candidateRef, jobId, referential, decision:"shortlist", criteria:[{ criterionId:"experience", sourceRef:"fiche:...#experience", score:0.8, threshold:0.6, passed:true }] }); const v = await sc.verifyChain();
from scellance_sdk import ScellanceClient, Criterion with ScellanceClient(base_url, api_key) as sc: sc.seal_referential("fiche:1024:v1", {"criteres": [...]}) sc.screening(candidate_ref="cand_42", job_id="job-1", referential="fiche:1024:v1", decision="shortlist", criteria=[Criterion("exp", "fiche:1024:v1#exp", score=0.8, threshold=0.6, passed=True)]) assert sc.verify_chain().verified
Méthodes : sealReferential, screening, humanConfirm, humanOverride, listEvents, verifyChain, pendingSupervision, createWebhook. Distribution PyPI et npm en cours ; en attendant, les SDK sont fournis avec l'accès développeur.
7RGPD by design
- Le candidat est désigné par une référence opaque (candidate_ref), jamais par son nom ni son email. Vous gardez la maîtrise de l'identité.
- Droit d'accès : GET /v1/candidates/{ref}/personal-data.
- Effacement : POST /v1/candidates/{ref}/erasure - crypto-shredding (destruction de la clé du candidat), les données chiffrées deviennent illisibles, la chaîne reste intacte.
- Hébergement France / UE.