Sommaire

v1 · Bêta

API Partenaire

Intégration de l'API Candidate Intelligence

Donnez plus de confiance aux recruteurs avant les entretiens

Lancez des rapports Candidate Intelligence directement dans votre ATS pour vérifier les informations candidat, détecter des signaux inattendus et générer des questions d'entretien en quelques secondes.

Demander l'accès API

Idéal pour

Systèmes de suivi des candidatures (ATS)

CRM de recrutement

Sites d'emploi

Plateformes de talents internes

Cabinets de chasse de têtes

Éditeurs de solutions RH

Avantages partenaire

Pourquoi intégrer Candidate Intelligence ?

Offrez à vos clients un contexte supplémentaire avant les entretiens tout en créant de la valeur au sein de votre plateforme.

📈

Renforcer l'engagement des recruteurs

Gardez les recruteurs dans votre ATS grâce à la vérification des candidats, la préparation d'entretien et des insights de recrutement directement dans les profils.

💰

Créer une nouvelle source de revenus

Proposez des rapports Candidate Intelligence à vos clients et générez des revenus récurrents via le programme partenaire.

Différencier votre plateforme

Démarquez-vous des ATS et solutions de recrutement concurrentes avec des capacités Candidate Intelligence intégrées.

🔍

Aucune recherche supplémentaire

Aidez les recruteurs à découvrir des informations pertinentes au-delà du CV sans quitter leur flux de travail.

🎯

Améliorer la qualité du recrutement

Aidez recruteurs et hiring managers à prendre des décisions plus éclairées grâce à un contexte au-delà du CV, des constats vérifiés, des risques potentiels et les points à valider.

Intégration rapide

L'implémentation typique ne nécessite que quelques endpoints API et peut être réalisée en moins d'une journée.

Parcours d'intégration

1

Obtenir l'approbation et recevoir une clé API

Demandez l'accès à TieTalent. Une fois approuvé, vous recevez une clé API pour votre intégration.

2

Ajouter un bouton dans les profils candidats

Ajoutez un bouton « Lancer Intelligence » dans les profils candidats. Au clic, il devient « En cours... » pendant la génération. Une fois prêt, le rapport s'ouvre automatiquement et le bouton devient « ✕ Fermer le rapport ». À la fermeture, il repasse à « Voir le rapport Intelligence » pour rouvrir un rapport déjà généré.

3

Appeler l'API TieTalent au clic

POST vers /api/v1/analyses avec les données candidat, client (recruteur) et langue. Utilisez vos propres identifiants externes sur client.id et candidate.id.

4

TieTalent génère le rapport

L'analyse s'exécute en arrière-plan. Utilisez GET /api/v1/analyses/{id} à la fois pour le polling tant que le statut est queued ou processing (attendez au moins 10 secondes entre les requêtes: voir Retry-After) et pour récupérer le rapport terminé lorsque le statut est completed. Appelez DELETE sur le même chemin pour annuler si le recruteur quitte le profil.

5

Optionnel : précalcul à la shortlist

Lorsqu'un candidat est shortlisté (ou passe à une étape avancée du pipeline), envoyez POST avec mode: "precompute" pour que la génération puisse se terminer avant le clic du recruteur. Stockez l'id renvoyé et faites un GET à l'ouverture, ou POST live au clic. Le live crée toujours un nouvel id mais réutilise rapidement le contenu cache valide. Ne déclenchez pas le précalcul à la première ouverture du profil. Voir Analyses précalculées.

6

Afficher le rapport dans le profil candidat

Affichez le JSON du rapport dans votre interface (voir Types de rapport et champs), ou ouvrez le rapport hébergé complet via le lien signé de metadata.pdf_download_url: la vue hébergée propose aussi l'export PDF.

Performances et latence

Candidate Intelligence est conçu pour offrir une expérience réactive directement dans les flux de travail des recruteurs.

Action

Temps de réponse typique

Rapport existant trouvé (copie cache live ou réutilisation précalcul)

< 1 seconde

Ouvrir un rapport précalculé (après précalcul terminé)

Instantané (GET completed)

Génération d'un nouveau rapport

30–60 secondes

Logique de réutilisation des rapports

Les rapports sont identifiés de façon unique par plateforme + entreprise + candidat.

Le cache est limité par recruteur : votre clé API identifie l'intégration partenaire, et client.id identifie le recruteur (utilisateur) au sein de votre plateforme. Des client.id différents ne partagent pas le cache, même avec la même clé API.

Même client + même empreinte candidat → contenu cache réutilisé instantanément (live : nouvel id d'analyse avec metadata.cached ; précalcul : même id d'analyse)
Entreprise cliente différente + même candidat → nouveau rapport généré et facturé séparément
Même entreprise cliente + candidat différent → nouveau rapport généré et facturé

Champs de la clé de cache

candidate.idVotre identifiant candidat externe
candidate.first_name + candidate.last_nameNom du candidat (normalisé)
candidate.companyEntreprise actuelle (normalisée)
candidate.locationLocalisation (normalisée)
candidate.roleRôle ou intitulé du poste (normalisé)
report_typeType de rapport résolu (le défaut de votre partenaire, ou la surcharge report_type par appel). Un report_type différent de celui d'un rapport mis en cache précédemment est toujours un cache miss: un nouveau rapport du type demandé est généré.

Hors clé de cache

candidate.cvTexte de CV optionnel: utilisé uniquement lors d'exécutions fraîches. Modifier seul le CV n'invalide pas le cache.
languageLangue du rapport demandée. Utilisez force_refresh: true si vous avez besoin d'un rapport dans une autre langue.

Les rapports en cache sont réutilisés pendant 6 mois. Les analyses terminées plus anciennes ne sont pas renvoyées depuis le cache.

Forcer l'actualisation

Définissez force_refresh: true sur POST /api/v1/analyses pour ignorer le cache et exécuter le pipeline complet: enrichissement, signaux en direct et génération du rapport LLM.

Omettez force_refresh ou définissez-le à false pour autoriser la réutilisation du cache (par défaut).

Quand définir force_refresh: true

Le recruteur demande explicitement une intelligence mise à jour ou actualisée

Seul le texte du CV a changé tandis que les champs du profil sont restés identiques

Vous avez besoin d'un rapport dans une langue différente d'une exécution en cache précédente

Vous souhaitez relancer l'enrichissement et les signaux en direct indépendamment du cache

Requête d'analyse fraîche

{
  "language": "en",
  "client": {
    "id": "client_company_123",
    "first_name": "Jane",
    "last_name": "Smith",
    "company": "Acme Recruiting"
  },
  "candidate": {
    "id": "candidate_456",
    "first_name": "John",
    "last_name": "Doe",
    "company": "Example Company",
    "location": "London, UK",
    "role": "Software Engineer"
  },
  "force_refresh": true
}

Authentification

Approbation requise : les clés API sont délivrées uniquement aux plateformes partenaires approuvées. Incluez votre clé à chaque requête ; ne l'exposez jamais dans du code côté client ni dans des dépôts publics.

En-têtes HTTP

X-API-Key: ats_your_api_key_here
Content-Type: application/json

Créer une analyse

Champs optionnels du corps : candidate.cv (CV en texte brut, utilisé uniquement lors d'exécutions fraîches), force_refresh (booléen, false par défaut (voir Forcer l'actualisation), report_type ("hr" ou "agency", surcharge le défaut de votre partenaire pour cet appel uniquement) voir Types de rapport et champs) et mode: "precompute" (voir Analyses précalculées ; pour le lot, candidates à la place de candidate).

POST/api/v1/analyses
{
  "language": "en",
  "client": {
    "id": "client_company_123",
    "first_name": "Jane",
    "last_name": "Smith",
    "company": "Acme Recruiting"
  },
  "candidate": {
    "id": "candidate_456",
    "first_name": "John",
    "last_name": "Doe",
    "company": "Example Company",
    "location": "London, UK",
    "role": "Software Engineer",
    "cv": "Optional plain-text CV content…"
  },
  "force_refresh": false
}

force_refresh (optionnel, false par défaut) ignore la réutilisation des rapports et génère toujours un nouveau rapport: le nouveau rapport est facturé. Omettez-le sauf si le recruteur demande explicitement une actualisation.

202 Accepted

L'en-tête Location pointe vers GET /api/v1/analyses/{id}. Retry-After: 10 indique quand effectuer le prochain polling.

202 Accepted
{
  "id": "cmqp23kgg00067gk0rh6jol5o",
  "status": "queued",
  "candidate_id": "candidate_456",
  "created_at": "2026-06-29T12:00:00.000Z"
}

Analyses précalculées

Le précalcul génère un rapport Candidate Intelligence à l'avance (par exemple lorsqu'un candidat est shortlisté) pour que le recruteur attende moins souvent 30–60 secondes. Stockez l'id d'analyse renvoyé et faites un GET à l'ouverture, ou POST une création live normale au clic. Le live renvoie toujours un nouvel id, mais réutilise le contenu cache valide en moins d'une seconde.

Utilisez le même endpoint POST /api/v1/analyses avec mode: "precompute". Il n'existe pas d'URL précalcul séparée. Polling et récupération utilisent le même GET /api/v1/analyses/{id} que pour les exécutions live.

Déclencheurs recommandés

Candidat shortlisté

Changement d'étape pipeline vers une phase avancée / prête pour entretien

Ne pas déclencher sur

  • Première ouverture de profil: exclu pour des raisons de confidentialité/RGPD et de coût après revue produit

Comportement

  • Renvoie immédiatement 202 Accepted avec un id d'analyse: pas de connexion longue ni de signaux préliminaires streamés à la création.
  • Idempotent : si le même partenaire + client (recruteur) + empreinte candidat a déjà une exécution en cours ou un rapport en cache valide (mêmes règles de réutilisation sur 6 mois que le live), l'id d'analyse existant est renvoyé et aucune nouvelle génération n'est démarrée.
  • Les POST live (hors précalcul) créent toujours un nouvel id d'analyse ; la réutilisation du cache live copie le rapport sur ce nouvel id (inchangé).
  • force_refresh: true optionnel ignore la réutilisation du cache completed pour le précalcul (même sémantique que le live). Une exécution en cours pour la même empreinte est toujours renvoyée au lieu de démarrer un doublon.

Précalcul pour un candidat

Envoyez mode: "precompute" avec les mêmes objets client et candidate qu'une création live. La forme de réponse correspond au corps 202 Accepted live.

POST/api/v1/analyses
{
  "mode": "precompute",
  "language": "en",
  "client": {
    "id": "client_company_123",
    "first_name": "Jane",
    "last_name": "Smith",
    "company": "Acme Recruiting"
  },
  "candidate": {
    "id": "candidate_456",
    "first_name": "John",
    "last_name": "Doe",
    "company": "Example Company",
    "location": "London, UK",
    "role": "Software Engineer"
  }
}

Précalcul par lot

Envoyez mode: "precompute" avec candidates (tableau) au lieu de candidate. Fournissez exactement l'un de candidate ou candidates. Maximum 50 candidats par requête.

POST/api/v1/analyses
{
  "mode": "precompute",
  "language": "en",
  "client": {
    "id": "client_company_123",
    "first_name": "Jane",
    "last_name": "Smith",
    "company": "Acme Recruiting"
  },
  "candidates": [
    {
      "id": "candidate_456",
      "first_name": "John",
      "last_name": "Doe",
      "company": "Example Company",
      "location": "London, UK",
      "role": "Software Engineer"
    },
    {
      "id": "candidate_789",
      "first_name": "Alex",
      "last_name": "Nguyen",
      "company": "Example Company",
      "location": "Berlin, DE",
      "role": "Product Manager"
    }
  ]
}

202 Accepted (lot)

202 Accepted
{
  "items": [
    {
      "id": "cmqp23kgg00067gk0rh6jol5o",
      "status": "queued",
      "candidate_id": "candidate_456",
      "created_at": "2026-06-29T12:00:00.000Z"
    },
    {
      "id": "cmqp23kgg00067gk0rh6jol5p",
      "status": "queued",
      "candidate_id": "candidate_789",
      "created_at": "2026-06-29T12:00:00.000Z"
    }
  ]
}

Interrogez ou récupérez chaque id renvoyé via GET /api/v1/analyses/{id}. Lorsque le statut est completed, report et metadata sont renseignés: c'est ainsi que vous récupérez le rapport prêt.

Le précalcul est plafonné par partenaire (1 000 exécutions net-new par jour UTC et 10 en cours). Dépasser un plafond renvoie 429 Too Many Requests avec l'erreur precompute-cap-exceeded et Retry-After. Les hits cache ou in-flight ne comptent pas pour ces plafonds. Les exécutions live en sont exemptées.

Obtenir une analyse (polling et récupération)

Utilisez GET /api/v1/analyses/{id} avec le même en-tête X-API-Key et l'id de la réponse de création (ou de précalcul). Ce seul endpoint sert à la fois au polling des exécutions en cours et à la récupération du rapport terminé.

Lorsque le statut est completed, la réponse inclut l'objet report complet ainsi que metadata (y compris pdf_download_url). Il n'existe pas d'endpoint « get report » séparé: arrêtez le polling et affichez ou ouvrez cette payload. Voir Analyse terminée pour un exemple complet.

Tant que le statut est queued ou processing, chaque réponse GET inclut Retry-After: 10: attendez au moins 10 secondes avant la requête suivante.

Arrêtez le polling lorsque le statut est completed, failed ou canceled.

GET/api/v1/analyses/{id}
{
  "id": "cmqp23kgg00067gk0rh6jol5o",
  "status": "processing",
  "candidate_id": "candidate_456",
  "stage": "enrichment",
  "created_at": "2026-06-29T12:00:00.000Z",
  "updated_at": "2026-06-29T12:00:20.000Z",
  "quick_signal": {
    "level": "Green",
    "reason": "Identity supported by multiple matching signals.",
    "identityConfidence": "Medium"
  },
  "signals": [
    {
      "statement": "Senior engineer at Example Company since 2021.",
      "sourceType": "web",
      "sourceUrl": "https://example.com/…",
      "reliability": "High"
    }
  ],
  "report": null,
  "metadata": null,
  "error": null
}

Champs renseignés pendant le traitement

quick_signalSignal d'identité préliminaire (Green, Orange ou Red) avec une courte explication: disponible dès le début de l'enrichissement.
signalsSignaux web en direct découverts pendant l'enrichissement. Le tableau s'enrichit au fur et à mesure des recherches externes.
stageÉtape actuelle du pipeline : identity → enrichment → report → done.
reportRapport Candidate Intelligence complet: renseigné uniquement lorsque le statut est completed. C'est la payload du rapport à afficher ou stocker.
metadataMétadonnées du rapport: renseignées uniquement lorsque le statut est completed. Incluent le lien signé vers le rapport hébergé (pdf_download_url) et les indicateurs de réutilisation cached / cached_at.

Valeurs de statut

queuedAcceptée et en attente de démarrage.
processingEn cours: interrogez pour les mises à jour de quick_signal, signals et stage.
completedRapport prêt: utilisez cette réponse GET comme rapport récupéré (report et metadata sont renseignés).
failedAnalyse échouée: error est renseigné.
canceledAnalyse annulée via DELETE /api/v1/analyses/{id} ou état terminal d'annulation atteint.

Annuler une analyse

DELETE /api/v1/analyses/{id} arrête une analyse en file d'attente ou en cours lorsqu'un recruteur quitte le profil candidat ou ferme un rapport en génération. Utilisez le même en-tête X-API-Key que pour POST et GET.

Si l'analyse est déjà completed, failed ou canceled, l'endpoint renvoie la ressource actuelle sans modification: aucun frais supplémentaire ni effet de bord.

DELETE/api/v1/analyses/{id}
// Aucun corps de requête: en-tête X-API-Key uniquement

200 OK

Renvoie la ressource d'analyse avec le statut canceled. Des quick_signal ou signals partiels peuvent être présents si l'annulation a eu lieu en cours de pipeline. Arrêtez le polling dès que le statut est canceled.

200 OK
{
  "id": "cmqp23kgg00067gk0rh6jol5o",
  "status": "canceled",
  "candidate_id": "candidate_456",
  "stage": "enrichment",
  "created_at": "2026-06-29T12:00:00.000Z",
  "updated_at": "2026-06-29T12:00:25.000Z",
  "quick_signal": null,
  "signals": [],
  "report": null,
  "metadata": null,
  "error": null
}

Webhooks de rapport prêt

Comme alternative au polling, TieTalent peut envoyer une notification HTTP signée vers un point de terminaison enregistré pour votre intégration dès qu'une analyse atteint un état final: report_ready quand un rapport est terminé (analyse en direct, précalcul ou réutilisation en cache comptent toutes) ou report_failed en cas d'échec définitif.

Les webhooks complètent le polling, ils ne le remplacent jamais. Considérez GET /api/v1/analyses/{id} comme la source faisant autorité à tout moment et conservez le polling comme solution de secours pour tout événement manqué.

Les points de terminaison webhook sont enregistrés, tournés et surveillés pour vous par TieTalent: il n'y a pas de configuration en libre-service pour les partenaires. Contactez votre interlocuteur d'intégration pour ajouter ou modifier un point de terminaison.

Types d'événements

report_readyUn rapport final est prêt: couvre les analyses en direct, les précalculs et les réutilisations en cache.
report_failedL'analyse a atteint un échec définitif.

Enveloppe de l'événement

Chaque livraison est un objet JSON structuré comme les exemples ci-dessous. id est généré une seule fois par événement et réutilisé à chaque nouvelle tentative de ce même événement: utilisez-le comme clé d'idempotence pour la déduplication.

api_environment reflète le label de la clé API qui a authentifié l'analyse (Production, Staging ou Test): la même valeur affichée dans votre liste de clés API admin. Une clé ne livre jamais qu'au point de terminaison webhook enregistré sous son propre label.

payload report_ready
{
  "id": "evt_1a2b3c4d5e6f7890",
  "type": "report_ready",
  "created_at": "2026-07-30T14:45:21.650Z",
  "api_environment": "Production",
  "data": {
    "analysis_id": "cmqp23kgg00067gk0rh6jol5o",
    "candidate_id": "candidate_456",
    "client_id": "client_company_123",
    "status": "completed",
    "report_url": "https://intelligence.tietalent.com/api/v1/analyses/cmqp23kgg00067gk0rh6jol5o",
    "pdf_download_url": "https://intelligence.tietalent.com/api/ats/reports/cmqp23kgg00067gk0rh6jol5o/pdf?sig=…"
  }
}
payload report_failed
{
  "id": "evt_9f8e7d6c5b4a3210",
  "type": "report_failed",
  "created_at": "2026-07-30T14:45:21.650Z",
  "api_environment": "Production",
  "data": {
    "analysis_id": "cmqp23kgg00067gk0rh6jol5p",
    "candidate_id": "candidate_789",
    "client_id": "client_company_123",
    "status": "failed",
    "report_url": "https://intelligence.tietalent.com/api/v1/analyses/cmqp23kgg00067gk0rh6jol5p",
    "pdf_download_url": null,
    "error_code": "internal_error"
  }
}

Champs de data

analysis_idLe même id que vous récupéreriez via GET /api/v1/analyses/{id}.
candidate_idVotre propre candidate.id de la requête d'origine: pas un identifiant interne TieTalent.
client_idVotre propre client.id de la requête d'origine.
statuscompleted ou failed, correspondant au statut de la ressource d'analyse.
report_urlL'URL authentifiée GET /api/v1/analyses/{id}: récupérez-la avec votre X-API-Key pour obtenir le rapport complet.
pdf_download_urlLe lien signé du rapport hébergé, identique à metadata.pdf_download_url sur la réponse GET. Présent sur report_ready, null sur report_failed.
error_codePrésent uniquement sur les événements report_failed: un code stable et lisible par machine. N'expose jamais un fournisseur d'IA interne ni un détail d'infrastructure.
Ceci est uniquement un pointeur "prêt" léger: aucun corps de rapport, aucun verdict, et aucune donnée PII candidat ne transite dans le webhook. Récupérez le rapport complet via le GET authentifié existant en utilisant les ids ci-dessus.

Vérifier la signature

Chaque livraison porte un en-tête X-CI-Signature au format ci-dessous. Le contenu signé est {timestamp}.{raw_request_body}, HMAC-SHA256 avec le secret whsec_... émis pour votre point de terminaison.

En-tête X-CI-Signature

X-CI-Signature: t=1732963521,v1=5d6f2c8a9e1b7340c6a2f5e8b1d9a047c3b6e2f1a8d5c9b4e7f2a1d6c3b8e5f0

Pendant une fenêtre de rotation de secret, l'en-tête peut porter deux valeurs v1=: une signée avec le secret sortant, une avec le secret entrant. Acceptez une correspondance avec l'une ou l'autre.

Rejetez toute livraison dont l'horodatage t= diffère de plus de 5 minutes de votre propre horloge: c'est votre défense contre les attaques par rejeu.

Vérification de la signature (pseudocode)

function isValidSignature(header, rawBody, secret, toleranceSeconds = 300) {
  const parts = Object.fromEntries(
    header.split(",").map((part) => part.split("=").map((s) => s.trim())),
  );
  const timestamp = Number(parts.t);
  if (Math.abs(Date.now() / 1000 - timestamp) > toleranceSeconds) return false;

  const expectedSignature = hmacSha256Hex(secret, `${timestamp}.${rawBody}`);
  const candidateSignatures = header
    .split(",")
    .filter((part) => part.startsWith("v1="))
    .map((part) => part.slice(3));

  return candidateSignatures.some((signature) => timingSafeEqual(signature, expectedSignature));
}

Sémantique de livraison

  • Livraison au moins une fois: une réponse 2xx en moins de 5 secondes compte comme un succès ; toute autre réponse déclenche une nouvelle tentative avec backoff exponentiel et jitter, environ 10 tentatives sur environ 24 heures, puis l'événement passe en dead-letter.
  • Les livraisons dupliquées et hors ordre sont normales: dédupliquez sur id et ne supposez jamais d'ordre entre les événements.
  • Si un webhook est manqué, retardé ou dupliqué, votre polling existant garde votre état cohérent avec le GET authentifié.

Analyse terminée

Retournée lorsque le statut est completed. Le rapport ci-dessous est un exemple de type hr et il est abrégé: consultez Types de rapport et champs pour la liste complète des champs et l'exemple de type agency.

Rapport frais (metadata.cached: false)

JSON200 OK
{
  "id": "clx_analysis_id",
  "status": "completed",
  "candidate_id": "candidate_456",
  "stage": "done",
  "created_at": "2026-06-29T12:00:00.000Z",
  "updated_at": "2026-06-29T12:00:45.000Z",
  "quick_signal": {
    "level": "Green",
    "reason": "Identity supported by multiple matching signals.",
    "identityConfidence": "Medium"
  },
  "signals": [
    {
      "statement": "…",
      "sourceType": "web",
      "sourceUrl": "https://example.com/…",
      "reliability": "High"
    }
  ],
  "report": {
    "report_type": "hr",
    "candidateName": "John Doe",
    "profileHeadline": "Software Engineer",
    "profileCompany": "Example Company",
    "profileLocation": "London, UK",
    "sourcesCheckedCount": 24,
    "identity": {
      "status": "Confirmed",
      "confidence": "High",
      "confidenceReason": "…",
      "risk": { "level": "Low", "reason": "…" }
    },
    "recommendation": {
      "decision": "Go with validation",
      "confidence": "Medium",
      "confidenceNote": "Identity verified · signals consistent",
      "reason": "…",
      "nextStepPills": [
        { "variant": "confirmed", "label": "Role and tenure verified" },
        { "variant": "validate", "label": "Validate team leadership scope" }
      ]
    },
    "bottomLine": {
      "headline": "…",
      "detail": "…"
    },
    "keyTakeaways": {
      "standsOut": [{ "label": "…", "detail": "…" }],
      "needsChecking": [{ "label": "…", "detail": "…" }]
    },
    "surprisingInsights": [
      { "title": "…", "text": "…", "source": "…", "polarity": "Favorable" }
    ],
    "externalBackgroundAssessment": [
      { "claim": "…", "summary": "…", "sourceReference": "…", "evidenceBadge": "high" },
      { "claim": "…", "summary": "…", "evidenceBadge": "not_found" }
    ],
    "externalProfileTags": [
      { "kind": "catalog", "id": "linkedin_verified" },
      { "kind": "catalog", "id": "no_adverse_signals" }
    ],
    "roleFit": {
      "bestSuited": ["…"],
      "considerCarefully": ["…"]
    },
    "interviewQuestions": [{ "question": "…", "hint": "Explores: …" }],
    "alertLevel": "Green",
    "externalDataConfidence": "Medium"
  },
  "metadata": {
    "report_id": "clx_analysis_id",
    "candidate_id": "candidate_456",
    "language": "en",
    "generated_at": "2026-06-29T12:00:45.000Z",
    "pdf_download_url": "https://intelligence.tietalent.com/api/ats/reports/{id}/pdf?sig=…",
    "cached": false,
    "cached_at": null,
    "report_type": "hr"
  },
  "error": null
}

Rapport en cache (metadata.cached: true)

JSON200 OK
{
  "id": "clx_new_analysis_id",
  "status": "completed",
  "candidate_id": "candidate_456",
  "stage": "done",
  "created_at": "2026-07-15T12:00:00.000Z",
  "updated_at": "2026-07-15T12:00:00.500Z",
  "quick_signal": { "…": "…" },
  "signals": [{ "…": "…" }],
  "report": { "…": "…" },
  "metadata": {
    "report_id": "clx_new_analysis_id",
    "candidate_id": "candidate_456",
    "language": "en",
    "generated_at": "2026-07-15T12:00:00.500Z",
    "pdf_download_url": "https://intelligence.tietalent.com/api/ats/reports/{id}/pdf?sig=…",
    "cached": true,
    "cached_at": "2026-07-15T12:00:00.500Z",
    "report_type": "hr"
  },
  "error": null
}

L'objet metadata

metadata.pdf_download_url est un lien signé qui ouvre le rapport TieTalent hébergé complet (le même design de rapport que l'application web) ; l'export PDF est téléchargeable depuis cette vue. Traitez ce lien comme confidentiel: toute personne qui le détient peut ouvrir le rapport.

metadata.cached vaut true lorsqu'un rapport existant a été réutilisé au lieu d'en générer un nouveau (voir la Logique de réutilisation des rapports) ; cached_at porte alors l'horodatage de la réutilisation, sinon il vaut null.

metadata.report_type (hr ou agency) indique quelle structure de rapport suit l'objet report: voir Types de rapport et champs. Il est défini une fois pour votre intégration par TieTalent et ne peut pas être modifié par requête.

Verdicts et compatibilité

report.recommendation.decision est le verdict principal du rapport. Il s'agit toujours de l'une des quatre valeurs ci-dessous.

recommendation.decision: valeurs possibles

"Proceed with confidence"
"Go with validation"
"Requires Validation (Signals flagged)"
"Requires Validation (Insufficient data)"

Associez chaque verdict à l'un des trois états d'interface :

Mapping suggéré (JavaScript)

function toUiState(decision) {
  switch (decision) {
    case "Proceed with confidence":
      return "proceed";
    case "Go with validation":
      return "validation";
    case "Requires Validation (Signals flagged)":
    case "Requires Validation (Insufficient data)":
      return "requires_validation";
    default:
      return "requires_validation";
  }
}
Bonne pratique : effectuez un switch sur la chaîne complète avec une valeur par défaut sûre requires_validation afin qu'une valeur inattendue se dégrade proprement au lieu de casser votre interface.

Types de rapport et champs

Chaque compte partenaire dispose d'un report_type par défaut (hr ou agency) défini pour vous par TieTalent lors de l'approbation de votre intégration (hr par défaut). Vous pouvez le surcharger pour un appel unique: voir ci-dessous. Le type utilisé pour un rapport donné est toujours renvoyé dans metadata.report_type et report.report_type. Les noms de champs sont en camelCase.

Compatibilité ascendante : de nouveaux champs peuvent être ajoutés à chaque type de rapport au fil du temps. Ignorez les champs inconnus et traitez tout champ comme nullable, sauf ceux listés dans Champs principaux ci-dessous.

Surcharge par appel

Passez un champ optionnel report_type ("hr" ou "agency") sur POST /api/v1/analyses pour utiliser ce type pour un seul appel, quel que soit le défaut de votre compte partenaire. Omettez-le pour conserver votre valeur par défaut. La surcharge n'est pas persistée: elle s'applique uniquement à cet appel. Une valeur invalide renvoie 400 Bad Request avec l'erreur invalid-report-type. report_type fait aussi partie de la clé de cache : demander un type différent de celui d'un rapport mis en cache précédemment pour le même candidat déclenche toujours un nouveau rapport.

Requête avec surcharge de report_type

{
  "language": "en",
  "client": {
    "id": "client_company_123",
    "first_name": "Jane",
    "last_name": "Smith",
    "company": "Acme Recruiting"
  },
  "candidate": {
    "id": "candidate_456",
    "first_name": "John",
    "last_name": "Doe",
    "company": "Example Company",
    "location": "London, UK",
    "role": "Software Engineer"
  },
  "report_type": "agency"
}

Champs principaux (présents sur les deux types de rapport)

report_typehr ou agency: la structure suivie par cet objet rapport.
candidateNameNom du candidat tel que résolu par l'analyse.
profileHeadline / profileCompany / profileLocationLignes d'en-tête pour l'affichage: poste/titre, entreprise actuelle et localisation. Optionnel.
sourcesCheckedCountNombre de résultats de recherche externes consultés pour le rapport. Optionnel.
identityRésolution d'identité: status (Confirmed, Likely, Ambiguous, Unknown), confidence, confidenceReason et risk (level, reason).
recommendationLe verdict: decision (voir Verdicts et compatibilité), confidence, reason, evidence[], confidenceNote (court titre d'évidence) et nextStepPills[] (pastilles d'état d'évidence avec variant et label).
bottomLineLe verdict d'ouverture du rapport: headline (une phrase décisive) et detail (1-2 phrases de contexte à l'appui).
keyTakeawaysListes standsOut[] et needsChecking[] d'éléments (label, detail).
surprisingInsightsJusqu'à 3 cartes (title, text, source, polarity): polarity vaut Favorable ou Concern.
externalBackgroundAssessmentLignes du tableau de preuves (claim, summary, evidenceBadge, sourceReference?) confrontant les affirmations du CV/profil aux signaux externes: inclusif des lacunes : une ligne avec evidenceBadge not_found signifie qu'aucun signal externe n'a été trouvé pour cette affirmation.
externalProfileTagsTags catalogue uniquement, des groupes source_presence et adverse_signal_status: voir Tags ci-dessous.
alertLevelNiveau d'alerte global: Green, Yellow, Orange ou Red.
externalDataConfidenceConfiance dans les données externes du rapport: High, Medium ou Low.

Champs propres à hr

Présents uniquement lorsque report_type vaut hr. Absents (pas null, absents) sur les rapports agency.

roleFitbestSuited[] et considerCarefully[]: contextes de rôle/organisation adaptés à ce profil vs. contextes nécessitant davantage de validation.
interviewQuestionsQuestions d'entretien suggérées: (question, hint).

Champs propres à agency

Présents uniquement lorsque report_type vaut agency. Absents (pas null, absents) sur les rapports hr.

bestFitTagsTags catalogue décrivant où se situe ce profil: voir Tags ci-dessous.
takeItForward« À savoir avant de donner suite »: worthItFor[] (raisons en phrases simples) et reflectionQuestions[] (question, answer).

Exemple d'objet rapport hr

report (report_type: "hr")

{
  "report_type": "hr",
  "candidateName": "John Doe",
  "profileHeadline": "Software Engineer",
  "profileCompany": "Example Company",
  "profileLocation": "London, UK",
  "sourcesCheckedCount": 24,
  "identity": {
    "status": "Confirmed",
    "confidence": "High",
    "confidenceReason": "…",
    "risk": { "level": "Low", "reason": "…" }
  },
  "recommendation": {
    "decision": "Go with validation",
    "confidence": "Medium",
    "confidenceNote": "Identity verified · signals consistent",
    "reason": "…",
    "nextStepPills": [
      { "variant": "confirmed", "label": "Role and tenure verified" },
      { "variant": "validate", "label": "Validate team leadership scope" }
    ]
  },
  "bottomLine": {
    "headline": "…",
    "detail": "…"
  },
  "keyTakeaways": {
    "standsOut": [{ "label": "…", "detail": "…" }],
    "needsChecking": [{ "label": "…", "detail": "…" }]
  },
  "surprisingInsights": [
    { "title": "…", "text": "…", "source": "…", "polarity": "Favorable" }
  ],
  "externalBackgroundAssessment": [
    { "claim": "…", "summary": "…", "sourceReference": "…", "evidenceBadge": "high" },
    { "claim": "…", "summary": "…", "evidenceBadge": "not_found" }
  ],
  "externalProfileTags": [
    { "kind": "catalog", "id": "linkedin_verified" },
    { "kind": "catalog", "id": "no_adverse_signals" }
  ],
  "roleFit": {
    "bestSuited": ["…"],
    "considerCarefully": ["…"]
  },
  "interviewQuestions": [{ "question": "…", "hint": "Explores: …" }],
  "alertLevel": "Green",
  "externalDataConfidence": "Medium"
}

Exemple d'objet rapport agency

report (report_type: "agency")

{
  "report_type": "agency",
  "candidateName": "John Doe",
  "profileHeadline": "Software Engineer",
  "profileCompany": "Example Company",
  "profileLocation": "London, UK",
  "sourcesCheckedCount": 24,
  "identity": {
    "status": "Confirmed",
    "confidence": "High",
    "confidenceReason": "…",
    "risk": { "level": "Low", "reason": "…" }
  },
  "recommendation": {
    "decision": "Go with validation",
    "confidence": "Medium",
    "confidenceNote": "Identity verified · signals consistent",
    "reason": "…",
    "nextStepPills": [
      { "variant": "confirmed", "label": "Role and tenure verified" },
      { "variant": "validate", "label": "Validate team leadership scope" }
    ]
  },
  "bottomLine": {
    "headline": "…",
    "detail": "…"
  },
  "keyTakeaways": {
    "standsOut": [{ "label": "…", "detail": "…" }],
    "needsChecking": [{ "label": "…", "detail": "…" }]
  },
  "surprisingInsights": [
    { "title": "…", "text": "…", "source": "…", "polarity": "Favorable" }
  ],
  "externalBackgroundAssessment": [
    { "claim": "…", "summary": "…", "sourceReference": "…", "evidenceBadge": "high" },
    { "claim": "…", "summary": "…", "evidenceBadge": "not_found" }
  ],
  "externalProfileTags": [
    { "kind": "catalog", "id": "linkedin_verified" },
    { "kind": "catalog", "id": "no_adverse_signals" }
  ],
  "bestFitTags": [
    { "kind": "catalog", "id": "sales_leadership" },
    { "kind": "catalog", "id": "b2b_saas" }
  ],
  "takeItForward": {
    "worthItFor": ["…"],
    "reflectionQuestions": [{ "question": "…", "answer": "…" }]
  },
  "alertLevel": "Green",
  "externalDataConfidence": "Medium"
}

Énumérations

Valeurs d'enum

identity.status                        Confirmed | Likely | Ambiguous | Unknown
*.confidence                           High | Medium | Low
identity.risk.level                    Low | Medium | High
nextStepPills[].variant                confirmed | validate | partial | insufficient | conflict
surprisingInsights[].polarity          Favorable | Concern
externalBackgroundAssessment[]
  .evidenceBadge                       high | single | validate | not_found
alertLevel                             Green | Yellow | Orange | Red

Tags

externalProfileTags et bestFitTags sont exclusivement des tags catalogue pour cette API (chaque tag porte un id stable en snake_case sur lequel vous pouvez faire un switch. Les ids de tags sont des valeurs API stables et ne sont pas localisés) associez-leur vos propres libellés ou affichez l'id humanisé.

Structure d'un tag

// externalProfileTags and bestFitTags are catalog-only for this API:
// every tag is a stable snake_case id from the catalogs below.
{ "kind": "catalog", "id": "linkedin_verified" }

externalProfileTags: ids catalogue par groupe

// group: source_presence
linkedin_verified · press_coverage_found · podcast_appearances
company_registry_confirmed · funding_database_found · alumni_record_confirmed
personal_website_found · speaking_engagements_found · published_content_found
social_media_presence · patent_or_ip_record_found · industry_body_membership

// group: adverse_signal_status
no_adverse_signals · adverse_signal_flagged · multiple_adverse_signals

bestFitTags: ids catalogue par groupe (rapports agency uniquement)

// group: functional_strength
fundraising_leadership · brand_and_partnerships · team_leadership
operational_execution · product_strategy · commercial_development
technical_execution · external_representation · content_and_thought_leadership
data_and_analytics · legal_and_compliance · finance_and_pnl_ownership
business_development · go_to_market_strategy · sales_leadership

// group: sector_fit
sustainability_sector · luxury_and_lifestyle · b2b_saas
purpose_driven_business · early_stage_startup · enterprise · healthcare
fintech · deep_tech · consumer_and_retail · education
proptech_and_real_estate · logistics_and_supply_chain · international_markets

// group: organisation_type
founder_stage_company · scale_up_series_a_c · large_enterprise
turnaround_or_transformation · ngo_or_non_profit · pe_or_vc_backed
family_business

// group: role_type
c_suite_or_founder_role · senior_leadership · individual_contributor
external_facing_role · operational_role · player_coach

// group: geographic_fit
switzerland · dach_region · western_europe · north_america
asia_pacific · middle_east · latin_america · international

Envoyer un avis sur un rapport

POST /api/v1/analyses/{id}/feedback permet à vos recruteurs de noter un rapport terminé (de 1 à 5 étoiles, avec des tags optionnels et un texte libre optionnel) afin que TieTalent puisse suivre la qualité des rapports de votre côté de l'intégration.

L'endpoint effectue un upsert sur client.id et l'id du rapport : envoyer à nouveau une requête pour le même client et le même rapport écrase la note, les tags et le texte précédents: il n'y a pas d'historique des révisions.

POST/api/v1/analyses/{id}/feedback
{
  "client": {
    "id": "client_company_123",
    "first_name": "Jane",
    "last_name": "Smith",
    "company": "Acme Recruiting"
  },
  "rating": 4,
  "feedback": "Helped me shortlist quickly, would have liked more sourcing links.",
  "tags": ["saved_me_time", "good_signal_quality"]
}

Champs de la requête

clientRequis. Même objet client que POST /api/v1/analyses: identifie lequel de vos utilisateurs donne son avis.
ratingRequis. Entier de 1 à 5.
feedbackOptionnel. Commentaire libre, jusqu'à 2000 caractères.
tagsOptionnel. Jusqu'à 5 identifiants de tags canoniques du catalogue ci-dessous: des valeurs invalides ou une note hors plage renvoient une erreur 4xx explicite.

Catalogue des tags de feedback

Les tags sont regroupés par tranche de note et changent selon la note envoyée: construisez votre propre interface, mais n'envoyez que les identifiants canoniques afin que les avis restent analysables entre les langues.

Identifiants de tags canoniques par tranche de note

// 1-2 stars
missing_info · something_was_wrong · signals_felt_weak
too_generic · hard_to_trust

// 3 stars
useful_but_missing_detail · right_idea_wrong_emphasis
some_signals_felt_off · wanted_more_sources

// 4-5 stars
saved_me_time · helped_me_decide · good_signal_quality
easy_to_read · trustworthy

200 OK

Renvoie l'avis enregistré, avec la note, les tags et le texte actuellement en base pour ce client et ce rapport.

200 OK
{
  "report_id": "cmqp23kgg00067gk0rh6jol5o",
  "rating": 4,
  "feedback": "Helped me shortlist quickly, would have liked more sourcing links.",
  "tags": ["saved_me_time", "good_signal_quality"],
  "updated_at": "2026-07-21T12:00:00.000Z"
}

Confidentialité et sécurité

Les rapports sont des outils d'aide à la décision uniquement et ne doivent pas servir de seule base aux décisions d'embauche. Un examen humain et une évaluation indépendante sont toujours requis.
Chaque intégration partenaire est isolée par clé API: vous ne pouvez accéder qu'aux analyses créées avec vos identifiants.
Utilisez client.id et candidate.id pour associer les analyses aux enregistrements de votre ATS.
Le texte de CV optionnel dans la requête est utilisé pour l'analyse et n'est pas stocké comme document distinct ; le rapport généré (qui peut refléter le contenu du CV) est conservé chiffré afin de pouvoir être restitué à votre intégration.
Les données sont stockées dans une infrastructure en région UE avec chiffrement au repos.
Candidate Intelligence fournit des recommandations et signaux de validation mais ne prend pas de décisions d'embauche automatisées au nom des utilisateurs.
Le traitement des données respecte les principes de minimisation et de limitation des finalités.

⚖️ Avis de conformité IA

Candidate Intelligence est conçu pour accompagner la prise de décision des recruteurs, pas pour la remplacer. Les décisions d'embauche restent de la responsabilité de l'employeur et doivent toujours inclure un examen humain et une supervision appropriés.

Programme partenaire

Commencez à intégrer Candidate Intelligence

Demandez l'accès et nous activerons vos identifiants API partenaire. L'intégration prend généralement moins d'une journée.