Aller au contenu principal

Intégration ATS

Envoyez les candidats correspondants dans votre ATS existant

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

    InTransparency API

    # 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_SECRET
  2. Relais Greenhouse (Node / TypeScript)

    Greenhouse Harvest API

    // Deno / Node webhook relay: InTransparency → Greenhouse Harvest API
    // Env: GREENHOUSE_API_KEY, GREENHOUSE_USER_ID, GREENHOUSE_JOB_ID,
    //      INTRANSPARENCY_WEBHOOK_SECRET
    import crypto from 'node:crypto'
    
    export default async function relay(req: Request): Promise<Response> {
      // 1. Verify the signature (constant-time compare)
      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')
      const ok = sig.length === expected.length &&
        crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))
      if (!ok) 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. Create a prospect in Greenhouse. Before the student accepts contact,
      // the webhook carries no email or surname — only a first name with an
      // initial ("Giulia M."), a stable pseudonym and the evidence link. The
      // recruiter opens the link, writes to the student on InTransparency, and
      // the full contact arrives once the student says yes.
      const [firstName, ...rest] = String(data.candidateName).split(' ')
      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: firstName,
          last_name: rest.join(' ') || data.candidatePseudonym,
          applications: [{ job_id: Number(process.env.GREENHOUSE_JOB_ID) }],
          website_addresses: [{ value: data.url, type: 'other' }],
          tags: ['InTransparency', data.decisionLabel],
          custom_fields: [
            { name_key: 'intransparency_match_id', value: data.matchId },
            { name_key: 'intransparency_match_score', value: data.matchScore },
          ],
        }),
      })
    
      return new Response('ok', { status: 200 })
    }

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

    Le push natif est disponible en bêta : ajoutez une clé API TeamTailor dans les réglages recruteur. Si vous préférez le construire : 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

    Le push natif est disponible en bêta : ajoutez une clé API Ashby dans les réglages recruteur et le relais devient inutile. Si vous préférez le construire : POST vers /candidate.create, puis /candidate.addApplication.