Alimentez votre ATS existant en candidats vérifiés
InTransparency ne remplace pas votre ATS : il l'alimente. Lorsqu'une correspondance à haut niveau de confiance se déclenche, nous envoyons un webhook signé ; un relais de 30 lignes le transforme en prospect Greenhouse, en opportunité Lever ou en candidat de réquisition Workday.
Le principe
InTransparency déclenche un webhook → votre petit relais vérifie la signature → votre relais appelle l'endpoint candidates de votre ATS. Aucun middleware personnalisé, aucun polling, aucune synchronisation planifiée. Le relais s'exécute n'importe où (Vercel, Cloudflare Workers, AWS Lambda ou un conteneur FastAPI).
1. Créez une clé d'agent et enregistrez un webhook
# Step 1: Create an InTransparency agent key with webhook scope
curl -X POST https://www.in-transparency.com/api/agents/keys \
-H "Cookie: <your session>" \
-H "Content-Type: application/json" \
-d '{"name":"ATS-relay","scopes":["agent:webhook"]}'
# Response: { "key": "ita_...", ... } — save it once; never shown again
# Step 2: Register your webhook endpoint with InTransparency
curl -X POST https://www.in-transparency.com/api/agents/webhooks \
-H "Authorization: Bearer ita_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-relay.example.com/webhooks/intransparency",
"events": ["match.created", "credential.issued"]
}'
# Response includes { "secret": "..." } — store as INTRANSPARENCY_WEBHOOK_SECRET2. Relais Greenhouse (Node / TypeScript)
Greenhouse Harvest API
// Deno / Node webhook relay: InTransparency → Greenhouse Harvest API
// Env: GREENHOUSE_API_KEY, INTRANSPARENCY_WEBHOOK_SECRET, GREENHOUSE_JOB_ID
import crypto from 'node:crypto'
export default async function relay(req: Request): Promise<Response> {
// 1. Verify the signature
const body = await req.text()
const sig = req.headers.get('X-InTransparency-Signature') || ''
const expected = 'sha256=' + crypto
.createHmac('sha256', process.env.INTRANSPARENCY_WEBHOOK_SECRET!)
.update(body).digest('hex')
if (sig !== expected) return new Response('bad signature', { status: 401 })
const { event, data } = JSON.parse(body)
if (event !== 'match.created' || data.matchScore < 70) {
return new Response('ignored', { status: 200 })
}
// 2. Fetch the candidate's full profile from InTransparency
const candidate = await fetch(
'https://www.in-transparency.com/api/agents/companies/' + data.candidateSlug,
).then(r => r.json())
// 3. Create a prospect in Greenhouse — the "Prospects" stage is perfect
// for sourced leads; they convert to candidates once a recruiter adds them
// to a job.
await fetch('https://harvest.greenhouse.io/v1/candidates', {
method: 'POST',
headers: {
'Authorization': 'Basic ' + Buffer.from(process.env.GREENHOUSE_API_KEY + ':').toString('base64'),
'Content-Type': 'application/json',
'On-Behalf-Of': process.env.GREENHOUSE_USER_ID!,
},
body: JSON.stringify({
first_name: data.candidateName.split(' ')[0],
last_name: data.candidateName.split(' ').slice(1).join(' '),
email_addresses: [{ value: candidate.email, type: 'personal' }],
applications: [{ job_id: Number(process.env.GREENHOUSE_JOB_ID) }],
attachments: [{
filename: 'intransparency-evidence.pdf',
type: 'other',
url: 'https://www.in-transparency.com/en/matches/' + data.matchId + '/why',
}],
custom_fields: {
intransparency_match_score: data.matchScore,
intransparency_match_id: data.matchId,
},
}),
})
return new Response('ok', { status: 200 })
}3. Relais Lever (Python / FastAPI)
Lever Opportunities API
# Python / FastAPI webhook relay: InTransparency → Lever API
# Env: LEVER_API_KEY, INTRANSPARENCY_WEBHOOK_SECRET, LEVER_POSTING_ID
import hashlib, hmac, os, json, httpx
from fastapi import FastAPI, Request, HTTPException
app = FastAPI()
@app.post("/webhooks/intransparency")
async def relay(req: Request):
body = await req.body()
sig = req.headers.get("X-InTransparency-Signature", "")
expected = "sha256=" + hmac.new(
os.environ["INTRANSPARENCY_WEBHOOK_SECRET"].encode(),
body, hashlib.sha256,
).hexdigest()
if not hmac.compare_digest(sig, expected):
raise HTTPException(401, "bad signature")
payload = json.loads(body)
if payload["event"] != "match.created": return {"ok": True}
data = payload["data"]
if data["matchScore"] < 70: return {"ok": True}
# Lever: create an opportunity (candidate attached to a posting)
async with httpx.AsyncClient(auth=(os.environ["LEVER_API_KEY"], "")) as client:
r = await client.post(
"https://api.lever.co/v1/opportunities",
json={
"name": data["candidateName"],
"origin": "sourced",
"sources": ["InTransparency"],
"postings": [os.environ["LEVER_POSTING_ID"]],
"tags": [f"intransparency-score-{data['matchScore']}"],
"links": [data["url"]],
},
)
r.raise_for_status()
return {"ok": True}Autres plateformes ATS
Workday Recruiting
Utilisez le Recruiting Staffing Web Service (SOAP) : ajoutez un Candidate avec l'opération Add_Candidate. Même principe de relais, payload différent.
SmartRecruiters
Faites un POST vers /candidates avec jobId et status=LEAD. Les champs personnalisés se mappent proprement.
Recruitee
Faites un POST vers /candidates avec placements=[{offer_id}]. Joignez l'URL de preuve en tant que note.
Teamtailor
Faites un POST vers /v1/candidates avec les job-applications incluses. Les candidats sourcés apparaissent dans le pipeline en tant que leads.
Personio
Utilisez la Recruiting API : POST /v1/recruiting/applications. Les équipes RH italiennes déjà familières avec Personio peuvent mettre cela en place en moins d'une heure.
Ashby
Faites un POST vers /candidate.create, puis vers /candidate.addApplication. Leur API est nativement compatible avec les webhooks, d'où une logique de relais minimale.