Développeurs
Connectez Screenwell aux outils que vous utilisez déjà
Des webhooks pour chaque évaluation et changement d'étape, une API REST pour vos postes et candidats, et un serveur MCP pour que Claude, ChatGPT et d'autres assistants IA travaillent avec Screenwell pour vous.
Dans chaque formule et pendant l'essai
Clés API
Les webhooks, l'API et le serveur MCP pour vos scripts utilisent la clé API de votre compte. Vous la trouverez dans l'application, sous Paramètres → API et webhooks. Les connecteurs Claude et ChatGPT n'ont pas besoin de clé : vous vous connectez avec Screenwell à la place.
- Vous disposez d'une clé principale et d'une clé secondaire, pour pouvoir passer à une nouvelle clé sans interruption de service.
- Une clé agit en votre nom : elle voit vos postes et ceux de votre équipe, rien d'autre.
- Gardez-la sur votre serveur. Ne l'intégrez jamais dans une page web ou une application mobile.
Zapier
Connectez Screenwell à votre ATS, Slack, Google Sheets et plus de 7 000 autres applications, sans code. Chaque déclencheur part au moment où l’événement a lieu dans Screenwell.
Mise en place
- 1Copiez votre clé API dans l’application : Paramètres → API et webhooks.
- 2Ouvrez Screenwell sur Zapier avec le bouton ci-dessous et acceptez l’invitation.
- 3Créez un Zap, choisissez Screenwell et collez votre clé API quand Zapier la demande.
- 4Choisissez un déclencheur ou une action, testez-le et activez le Zap.
Déclencheurs
- Interview Scored
- Luna a terminé un entretien et la fiche est prête : score, recommandation, résumé et lien vers la fiche.
- Candidate Moved to Stage
- Un candidat a changé d’étape. En option, pour une seule étape, comme Présélection.
- New Candidate
- Un candidat a été ajouté, dans l’application, via l’API ou depuis le lien d’entretien.
- New Job
- Un poste a été créé.
- Interview Completed
- Un entretien s’est terminé, avant que la fiche soit prête.
Actions et recherches
- Add Candidate to Job
- Nom, e-mail, téléphone et un CV en option.
- Send Interview Invite
- Envoie le lien de l’entretien par e-mail. Trouve le candidat par e-mail ou l’ajoute.
- Schedule Meet/Teams Interview
- Réserve Luna pour un entretien Google Meet ou Microsoft Teams.
- Update Candidate Stage
- Déplace vers Nouveau, Invité, Entretien passé, Présélection, Embauché ou Pas retenu.
- Create Job
- Titre, description, entreprise et langue de l’entretien.
- Find Candidate
- Par e-mail, en option dans un poste.
- Find Job
- Par titre.
Idées
- Nouveau candidat dans Workable, Recruitee, Teamtailor ou Greenhouse → Send Interview Invite
- Interview Scored → une note et l’étape suivante dans votre ATS
- Interview Scored → un message dans le canal recrutement sur Slack
- Interview Scored → une nouvelle ligne dans Google Sheets
Webhooks
Screenwell envoie une requête POST signée avec un corps JSON à votre URL dès qu'un événement se produit. Pointez-la vers votre ATS, un hook Zapier ou votre propre point de terminaison.
Configuration
- 1Dans l'application, ouvrez Paramètres → API et webhooks et ajoutez votre URL de webhook. Elle doit être une adresse https publique.
- 2Copiez le secret de signature qui apparaît après le premier enregistrement. Vous en aurez besoin pour vérifier les signatures.
- 3Cliquez sur « Envoyer un événement test » pour recevoir un exemple d'interview.scored avec test: true.
Vous pouvez aussi définir l'URL via l'API : PUT /api/v1/settings/webhook {"webhookUrl": "https://…"}.
Événements
- interview.scored
- Luna a terminé un entretien et la fiche d'évaluation est prête : le score sur 100, sa décision et son degré de certitude, son raisonnement et un lien vers la fiche d'évaluation.
- candidate.stage_changed
- Un candidat a changé d'étape sur le tableau, avec l'étape de départ, l'étape d'arrivée et qui l'a déplacé : luna après l'entretien, ou recruiter quand quelqu'un de votre équipe l'a fait.
Les comptes qui utilisaient CV Parsing continuent de recevoir ses anciens événements (cv_parsed, candidate_created et d'autres).
À quoi ressemble une livraison
Chaque livraison a la même enveloppe : id, eventType, timestamp, userId et data. Les événements de test portent aussi test: true.
{
"id": "evt_01J9ZK4T7Q2M8C6V",
"eventType": "interview.scored",
"timestamp": "2026-09-26T09:44:12.000Z",
"userId": "usr_4f1c",
"data": {
"candidate": { "id": "cand_8f2c", "name": "Maya Kowalski", "email": "maya@example.com" },
"job": { "id": "job_31a0", "title": "Senior Frontend Engineer" },
"interview": { "id": "int_77b1", "finishedAt": "2026-09-26T09:43:50.000Z", "durationSeconds": 1920 },
"score": 84,
"decision": "hire",
"confidence": 82,
"summary": "Strong frontend engineer who led a design system migration.",
"reasoning": "Explains her trade-offs clearly and meets 4 of 5 requirements.",
"scorecardUrl": "https://<app-host>/interviews/int_77b1",
"integrity": { "level": "none" }
}
}{
"id": "evt_01J9ZK4VB1XK0D3R",
"eventType": "candidate.stage_changed",
"timestamp": "2026-09-26T09:44:13.000Z",
"userId": "usr_4f1c",
"data": {
"candidate": { "id": "cand_8f2c", "name": "Maya Kowalski", "email": "maya@example.com" },
"job": { "id": "job_31a0", "title": "Senior Frontend Engineer" },
"from": "invited",
"to": "shortlisted",
"movedBy": "luna",
"changedBy": "rule",
"reason": "Moved by rule: score 84 ≥ 75",
"at": "2026-09-26T09:44:13.000Z"
}
}En-têtes
- X-Screenwell-Event
- Le type d'événement, par exemple interview.scored.
- X-Screenwell-Event-Id
- L'identifiant de l'événement. Il reste le même à chaque nouvelle tentative, utilisez-le donc pour ignorer les événements déjà traités.
- X-Screenwell-Signature
- t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">, signé avec votre secret de signature.
Vérifier la signature
- 1Lisez le corps brut de la requête, avant tout traitement JSON.
- 2Calculez le HMAC-SHA256 de "<t>.<raw body>" avec votre secret de signature, au format hexadécimal.
- 3Comparez-le à v1 en temps constant, et rejetez les requêtes dont le t date de plus de 5 minutes.
import crypto from 'node:crypto'
import express from 'express'
const app = express()
const SECRET = process.env.SCREENWELL_WEBHOOK_SECRET // whsec_...
// Keep the raw body: the signature is over the exact bytes we sent.
app.post('/webhooks/screenwell', express.raw({ type: 'application/json' }), (req, res) => {
const header = req.get('X-Screenwell-Signature') ?? ''
const { t, v1 } = Object.fromEntries(header.split(',').map((part) => part.split('=')))
const expected = crypto.createHmac('sha256', SECRET).update(`${t}.${req.body}`).digest('hex')
const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 5 * 60
const valid = v1?.length === expected.length && crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected))
if (!fresh || !valid) return res.status(400).send('bad signature')
const event = JSON.parse(req.body)
// Skip events you have already handled: event.id stays the same on retries.
console.log(event.eventType, event.data)
res.sendStatus(200)
})
app.listen(3000)import hashlib, hmac, json, os, time
from flask import Flask, request, abort
app = Flask(__name__)
SECRET = os.environ["SCREENWELL_WEBHOOK_SECRET"].encode() # whsec_...
@app.post("/webhooks/screenwell")
def screenwell():
header = request.headers.get("X-Screenwell-Signature", "")
parts = dict(p.split("=", 1) for p in header.split(",") if "=" in p)
t, v1 = parts.get("t", "0"), parts.get("v1", "")
body = request.get_data() # the raw bytes, before any JSON parsing
expected = hmac.new(SECRET, f"{t}.".encode() + body, hashlib.sha256).hexdigest()
if abs(time.time() - int(t)) > 300 or not hmac.compare_digest(v1, expected):
abort(400)
event = json.loads(body)
# Skip events you have already handled: event["id"] stays the same on retries.
print(event["eventType"], event["data"])
return "", 200Tentatives
Répondez avec un statut 2xx dans les 10 secondes. Si votre point de terminaison échoue ou ne répond pas, Screenwell réessaie après 1 minute, 5 minutes, 30 minutes et 2 heures. Paramètres → API et webhooks affiche les dernières livraisons avec leur statut et la réponse de votre point de terminaison.
- 0
- +1m
- +5m
- +30m
- +2h
API REST
Une API JSON pour les postes, candidats et entretiens de votre compte. Envoyez votre clé dans l'en-tête X-API-KEY. Les réponses ressemblent à {"status": "success", "data": …}.
- URL de base
https://api.screenwell.ai/api/v1- Authentification
X-API-KEY: <API key>
Postes
- GET
/jobsVos postes et ceux de votre équipe. - GET
/jobs/:idUn poste avec sa description et ses compétences. - POST
/jobsCréer un poste : intitulé, entreprise, lieu, description et plus encore. - PUT
/jobs/:idModifier les informations d'un poste.
Candidats
- POST
/jobs/:id/candidatesAjouter un candidat à un poste à partir de son CV : un fichier envoyé (file), un lien (fileUrl) ou du base64. - POST
/jobs/:id/candidates/batchAjouter plusieurs CV à un poste en une fois (fileUrls ou base64Files). - GET
/candidates/:idUn candidat avec les détails de son CV, son statut et l'analyse de Luna. - PUT
/candidates/:id/statusDéplacer un candidat, par exemple vers selected (Présélectionné), hired ou rejected. - GET
/candidates/:id/cvUn lien vers le fichier CV du candidat.
Entretiens et fiches d'évaluation
- GET
/meetingsEntretiens et appels, du plus récent au plus ancien. Filtrez avec isInterview=true, limit et offset. - GET
/meetings/:id/interview-insightsLa fiche d'évaluation d'un entretien : score, recommandation, points forts, points de vigilance et éléments justificatifs. - GET
/meetings/:id/transcriptLa transcription de l'entretien.
Compte
- GET
/quotaLe nombre d'entretiens qu'il vous reste ce mois-ci. - GET · PUT
/settings/webhookLire ou définir votre URL de webhook.
Statuts des candidats
Les étapes du tableau correspondent à ces statuts : Nouveau = applied, Invité = interview_scheduled, Interviewé = interviewed, Présélectionné = selected, Recruté = hired, Pas retenu = rejected. Changer un statut n'envoie jamais d'e-mail au candidat.
Exemple : ajouter un candidat à partir d'un CV
curl -X POST https://api.screenwell.ai/api/v1/jobs/job_31a0/candidates \
-H "X-API-KEY: $SCREENWELL_API_KEY" \
-F "file=@maya-kowalski-cv.pdf"
# or from a link
curl -X POST https://api.screenwell.ai/api/v1/jobs/job_31a0/candidates \
-H "X-API-KEY: $SCREENWELL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"fileUrl": "https://example.com/cv/maya.pdf"}'curl -X PUT https://api.screenwell.ai/api/v1/candidates/cand_8f2c/status \
-H "X-API-KEY: $SCREENWELL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "selected"}'Serveur MCP
Utilisez Screenwell depuis Claude, ChatGPT, Cursor ou tout autre client MCP : « Qui Luna a-t-elle présélectionné cette semaine ? », « Ajoute ces 5 CV au poste Backend », « Envoie le lien d'entretien à Tomas ». L'assistant agit en votre nom, avec les mêmes accès que vous avez dans l'application.
- Point de terminaison
POST https://api.screenwell.ai/mcp- Authorization
Bearer <jeton de connexion ou clé API>
Depuis claude.ai ou ChatGPT : connectez-vous avec Screenwell
Aucune clé à copier. Ajoutez Screenwell comme connecteur avec l'URL du serveur, puis connectez-vous avec votre compte Screenwell et validez l'accès.
claude.ai (web, ordinateur et mobile)
- 1Ouvrez Settings → Connectors → Add custom connector. Sur les formules Team et Enterprise, un administrateur (owner) doit d'abord l'ajouter dans Organization settings.
- 2Nommez-le Screenwell et saisissez l'URL du serveur. Laissez l'ID client et le secret OAuth vides.
- 3Cliquez sur Connect. Screenwell s'ouvre : connectez-vous, vérifiez les accès demandés et cliquez sur Allow. Activez ensuite Screenwell depuis le menu des outils d'une conversation.
ChatGPT
- 1Ouvrez Settings → Apps & Connectors → Advanced settings et activez Developer mode. Sur les espaces Business, Enterprise et Edu, un administrateur doit d'abord l'autoriser.
- 2Choisissez Create, nommez-le Screenwell, saisissez l'URL du serveur et sélectionnez OAuth comme authentification.
- 3Screenwell s'ouvre : connectez-vous, vérifiez les accès demandés et cliquez sur Allow. Sélectionnez ensuite le connecteur dans une conversation.
https://api.screenwell.ai/mcpLa page Screenwell affiche quelle app le demande, l'adresse vers laquelle elle vous renvoie, et l'accès qu'elle demande : lecture seule, ou lecture et action (ajouter, déplacer des candidats et leur envoyer des e-mails, toujours après votre accord).
Chaque app connectée est listée dans Paramètres → API et webhooks → Apps connectées. Déconnecter lui coupe l'accès dès sa prochaine requête.
Avec une clé API : Claude Code, Cursor et les scripts
Les outils qui permettent de définir un en-tête peuvent utiliser votre clé API à la place. Claude Code peut aussi se connecter : ajoutez le serveur sans en-tête, puis lancez /mcp et choisissez Authenticate.
# sign in with Screenwell: add the server, then run /mcp and choose Authenticate
claude mcp add --transport http screenwell https://api.screenwell.ai/mcp
# or with an API key
claude mcp add --transport http screenwell https://api.screenwell.ai/mcp \
--header "Authorization: Bearer <API key>"
# read-only
claude mcp add --transport http screenwell-read https://api.screenwell.ai/mcp \
--header "Authorization: Bearer <API key>" \
--header "X-Screenwell-Scope: read"{
"mcpServers": {
"screenwell": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://api.screenwell.ai/mcp", "--header", "Authorization: Bearer ${SCREENWELL_KEY}"],
"env": { "SCREENWELL_KEY": "<API key>" }
}
}
}Claude Desktop se connecte via mcp-remote, qui ajoute l'en-tête de clé pour vous.
Cursor, VS Code, MCP Inspector et les scripts utilisent la même URL, avec un en-tête de clé API ou en vous connectant.
Avec une clé API, ajoutez l'en-tête X-Screenwell-Scope: read pour une connexion en lecture seule. L'assistant peut alors consulter des informations, mais pas ajouter, déplacer ou envoyer d'e-mail à qui que ce soit.
Outils
Consulter
list_jobsVos postes avec les candidats par étape et si le lien d'entretien est actif.get_jobUn poste avec le plan d'entretien de Luna, le lien d'entretien et le pipeline.list_candidatesLes candidats par poste, étape ou nom, avec leur dernier score et qui les a déplacés en dernier.get_candidateUn candidat : coordonnées, briefing de Luna, résumé du CV, fiche d'évaluation et retour du responsable du recrutement.get_scorecardLa fiche d'évaluation complète : score sur 100, décision, points forts, lacunes et moments clés.ask_lunaPosez à Luna, votre conseillère recrutement, une question sur vos candidats.
Agir
add_candidateAjoutez un candidat à partir de ses informations ou d'un CV (PDF ou Word). Luna lit d'abord le CV.move_candidateNécessite votre accordDéplacez un candidat vers une autre étape.add_noteAjoutez une note pour votre équipe sur un candidat.send_interview_linkNécessite votre accordEnvoyez par e-mail le lien d'entretien du poste à 50 candidats maximum.
Rien n'atteint un candidat sans votre accord
- Envoyer le lien d'entretien, ou déplacer quelqu'un vers Recruté ou Pas retenu, affiche d'abord un aperçu (« Ceci enverra un e-mail à 3 candidats : … »). Rien ne se passe tant que l'assistant ne vous a pas demandé votre accord.
- L'assistant ne voit que ce que vous voyez dans l'application : vos postes et ceux de votre équipe. Cela fonctionne avec chaque formule et pendant l'essai, comme l'API.
- 60 appels d'outil par minute maximum et par clé. La lecture des CV et Ask Luna ont leurs propres limites horaires.
Vous construisez quelque chose de plus grand ?
Dites-nous ce que vous aimeriez connecter. Nous vous aiderons à le mettre en place.