Sommaire

v1

API Partenaire

Intégration de l'API Talent Update

Gardez vos fiches candidats à jour

Identifiez la personne et recevez des données structurées d'expérience, de formation et de présence en ligne issues de sources publiques. Aucun CV n'est transmis à ce point d'accès.

Particulièrement adapté à

Les ATS qui rafraîchissent des fiches candidats obsolètes

Les CRM de recrutement qui enrichissent les profils avant une prise de contact

Les agences de placement qui alignent leurs données de présentation sur la réalité

Les éditeurs de logiciels RH qui ajoutent la résolution d'identité à leur offre

Les équipes qui disposent déjà d'un nom, d'un employeur ou d'un e-mail et veulent des données structurées

Déroulé de l'intégration

1

Faites approuver votre accès et recevez une clé d'API

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

2

Envoyez une demande de mise à jour

POST vers /api/v1/talent-updates avec un objet candidate contenant les éléments d'identification. Voir Champs de la requête.

3

Recevez un 202 Accepted

La réponse contient un id, un candidate_id et cached. Lorsqu'une exécution récente et terminée existe (fenêtre de sept jours), vous pouvez recevoir immédiatement status: completed et cached: true ; sinon status: pending. Conservez l'id pour l'interrogation.

4

Interrogez l'API ou attendez un webhook

GET /api/v1/talent-updates/{id} jusqu'à ce que status soit completed ou failed. Les webhooks (talent_update_ready / talent_update_failed) sont à privilégier lorsqu'ils sont configurés.

5

Écrivez les résultats dans votre ATS

Reportez identity, work_experience, education et online_presence dans votre fiche candidat. Traitez une confiance d'identité faible ou absente comme non vérifiée.

Comparaison avec Candidate Intelligence

Talent Update partage l'authentification, les webhooks et les plafonds de précalcul avec Candidate Intelligence, mais vise un résultat différent : un enrichissement de profil structuré plutôt qu'un rapport de recrutement rédigé par un modèle.

  • Pas d'objet client : uniquement candidate (ou candidates pour un précalcul par lot).
  • Pas de champs language, cv, report_type ni eu_compliant.
  • Pas de point d'accès d'annulation. Les exécutions sont de courtes recherches de profil, pas de longues analyses en SSE.
  • La réponse est constituée de champs structurés (identity, work_experience, etc.), et non d'un objet report ou d'un PDF.
  • Même en-tête X-API-Key et même signature de webhook X-CI-Signature que Candidate Intelligence.

Authentification

Transmettez votre clé d'API partenaire dans l'en-tête X-API-Key à chaque requête, exactement comme pour Candidate Intelligence.

En-têtes de la requête

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

Créer une mise à jour

Crée une mise à jour asynchrone. Le corps de la requête n'accepte que des éléments d'identification : ni CV, ni document libre, ni fichier.

Les champs facultatifs comme profile_urls et experience améliorent la précision de l'identification. Transmettez les URL de profil dès que vous en disposez.

POST/api/v1/talent-updates
{
  "candidate": {
    "id": "cand-9911",
    "first_name": "Alex",
    "last_name": "Rivera",
    "email": "alex.rivera@example-corp.com",
    "employer_website": "example-corp.com",
    "company": "Example Corp",
    "role": "Software Engineer",
    "location": "London, UK",
    "profile_urls": [
      "https://linkedin.com/in/alex-rivera-example"
    ],
    "experience": [
      {
        "company": "Previous Corp",
        "role": "Engineer",
        "start_date": "2014-01",
        "end_date": "2016-01"
      }
    ]
  }
}

Champs de la requête

candidate (objet requis)

candidate.id est toujours requis. Au moins une des combinaisons d'identification ci-dessous doit également être satisfaite.

Combinaison requise (au moins une)

Champs

Précision

A

first_name + last_name + profile_urls

La plus fiable et la moins coûteuse. Une URL de profil lève tout doute sur la personne recherchée.

B

first_name + last_name + (employer_website or company)

Fiable. L'employeur confirme qu'il s'agit bien de votre candidat et non d'un homonyme.

C

email (professionnel)

Bon. Un domaine d'entreprise nous donne l'employeur et le nom est lu dans l'adresse, donc il suffit seul. Envoyez aussi un nom lorsque vous en avez un.

D

email (personnel) + (employer_website ou company)

Bon lorsque l'adresse contient le nom, par exemple jane.doe@gmail.com. Un domaine personnel ne dit rien de l'employeur : c'est l'entreprise qui ancre la recherche, et elle est obligatoire. Envoyez aussi first_name et last_name lorsque vous les avez : une adresse comme jdoe92@ nous laisse peu d'éléments et le profil peut revenir vide.

E

employer_website + role

La plus faible, à réserver aux candidats dont vous n'avez pas le nom. Elle identifie un poste et non une personne : nous ne répondons que si une seule personne occupe ce poste, jamais au-delà d'une confiance moyenne.

idVotre identifiant pour le candidat. Renvoyé tel quel dans candidate_id ; jamais interprété par TieTalent.
first_name, last_nameNom de la personne. Même signification que sur /api/v1/analyses.
emailE-mail du candidat, professionnel ou personnel. Voir les Règles des champs.
employer_websiteDomaine ou URL complète. À privilégier sur company lorsque vous en disposez.
companyNom de l'employeur. Utilisé lorsque employer_website est absent.
rolePoste actuel ou visé. Texte libre.
locationVille et pays.
profile_urlsURL absolues (LinkedIn, GitHub, etc.). Jusqu'à 10. Le champ facultatif le plus utile pour les noms courants.
experienceExpériences que vous détenez déjà. Jusqu'à 40 entrées. Dates au format YYYY-MM ou YYYY-MM-DD.

Champs facultatifs de premier niveau

force_refreshBooléen (false par défaut). À true, ignore la réutilisation du cache et relance un enrichissement complet, en direct comme en précalcul.
mode"precompute" pour un préchargement par lot en arrière-plan. Voir Précalcul des mises à jour.

Non accepté

Ni CV, ni document libre, ni fichier à ce point d'accès.

Règles de validation

Les échecs de validation renvoient un 422 au format RFC 9457 application/problem+json. Appuyez-vous sur status et detail ; n'analysez pas le texte d'erreur libre en production.

emailUne adresse d'entreprise suffit seule. Une adresse personnelle (Gmail, Outlook et similaires) est acceptée lorsqu'elle est accompagnée de company ou employer_website, et donne de meilleurs résultats si vous envoyez aussi first_name et last_name. Une boîte fonctionnelle comme info@ ou hr@ n'est jamais le candidat : envoyez le nom et l'employeur avec elle.
employer_websiteDomaine ou URL complète. Normalisé côté serveur en nom d'hôte.
profile_urlsDoivent être des URL absolues. Jusqu'à 10 par candidat.
experienceChaque entrée exige company. Dates au format YYYY-MM ou YYYY-MM-DD.
Champs optionnelsPeuvent être omis ou envoyés à null. Les deux sont traités comme absents : "end_date": null sur un poste actuel est accepté.

Précalcul des mises à jour

Utilisez le même point d'accès POST /api/v1/talent-updates avec mode: "precompute". L'interrogation et la récupération se font via le même GET /api/v1/talent-updates/{id} que pour les exécutions en direct.

Le précalcul sert à préparer des profils en arrière-plan (par exemple lorsqu'un candidat entre dans une présélection). Les appels en direct réutilisent eux aussi les exécutions récentes terminées dans la fenêtre de sept jours, sauf si force_refresh: true.

Précalcul pour un candidat

Envoyez mode: "precompute" avec un seul objet candidate.

{
  "mode": "precompute",
  "force_refresh": false,
  "candidate": {
    "id": "cand-9911",
    "first_name": "Alex",
    "last_name": "Rivera",
    "email": "alex.rivera@example-corp.com",
    "employer_website": "example-corp.com"
  }
}

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. Chaque candidat consomme une unité de votre limite de débit par minute : un lot de 20 candidats en consomme donc 20.

{
  "mode": "precompute",
  "candidates": [
    {
      "id": "cand-9911",
      "first_name": "Alex",
      "last_name": "Rivera",
      "email": "alex.rivera@example-corp.com"
    },
    {
      "id": "cand-9912",
      "first_name": "Jordan",
      "last_name": "Lee",
      "employer_website": "acme.example",
      "role": "Product Manager"
    }
  ]
}

Comportement du cache

  • Les exécutions terminées pour le même partenaire et la même empreinte de candidat peuvent être réutilisées pendant sept jours.
  • Les exécutions réutilisées renvoient immédiatement status: completed et cached: true, en direct comme en précalcul.
  • force_refresh: true ignore la réutilisation du cache (en direct comme en précalcul). Une exécution déjà en cours pour la même empreinte est tout de même renvoyée plutôt que dupliquée.

Le volume d'usage est mesuré par vos crédits de plan ; la vitesse à laquelle vous pouvez les dépenser est mesurée par la limite de requêtes par minute de votre forfait, partagée entre les appels live, les appels precompute et l'enrichissement CSV. Les résultats servis depuis le cache et les exécutions réutilisées ne consomment aucun crédit. Un dépassement de la limite de débit renvoie 429 Too Many Requests avec l'erreur rate-limit-exceeded et un Retry-After ; réessayez après ce délai. Voir Limites de débit pour les limites par forfait et les en-têtes de réponse.

Réponse à la création

Une création réussie renvoie 202 Accepted. La réponse contient un booléen cached, ainsi que les objets additifs credits (solde restant et débit de cet appel) et plan (plan actuel). Ces champs sont non-breaking et ne nécessitent pas de changement de version. Le précalcul par lot renvoie un tableau items avec une entrée par candidat, ainsi que credits / plan au niveau racine.

Réponse pour un candidat (nouvelle exécution)

202
{
  "id": "tu_01JCXY",
  "status": "pending",
  "candidate_id": "cand-9911",
  "created_at": "2026-08-28T12:56:44.642Z",
  "cached": false,
  "credits": {
    "balance": 142,
    "plan_credits": 120,
    "rollover_credits": 22,
    "charged": 1,
    "cached": false
  },
  "plan": {
    "code": "growth",
    "cycle": "monthly",
    "credits_per_cycle": 200,
    "requests_per_minute": 300,
    "period_ends_at": "2026-10-28T12:00:00.000Z"
  }
}

Réponse pour un candidat (réponse en cache)

Lorsqu'une exécution terminée existe dans la fenêtre de réutilisation de sept jours et que force_refresh n'est pas défini, la réponse à la création peut déjà être status: completed avec cached: true. Dans ce cas, credits.charged vaut 0 et credits.cached vaut true.

202
{
  "id": "tu_01JCXY",
  "status": "completed",
  "candidate_id": "cand-9911",
  "created_at": "2026-08-28T12:56:44.642Z",
  "cached": true,
  "credits": {
    "balance": 143,
    "plan_credits": 121,
    "rollover_credits": 22,
    "charged": 0,
    "cached": true
  },
  "plan": {
    "code": "growth",
    "cycle": "monthly",
    "credits_per_cycle": 200,
    "requests_per_minute": 300,
    "period_ends_at": "2026-10-28T12:00:00.000Z"
  }
}

Réponse au précalcul par lot

202
{
  "items": [
    {
      "id": "tu_01JCXY",
      "status": "completed",
      "candidate_id": "cand-9911",
      "created_at": "2026-08-28T12:56:44.642Z",
      "cached": true,
      "credits": {
        "balance": 142,
        "plan_credits": 120,
        "rollover_credits": 22,
        "charged": 0,
        "cached": true
      },
      "plan": {
        "code": "growth",
        "cycle": "monthly",
        "credits_per_cycle": 200,
        "requests_per_minute": 300,
        "period_ends_at": "2026-10-28T12:00:00.000Z"
      }
    },
    {
      "id": "tu_01JCXZ",
      "status": "pending",
      "candidate_id": "cand-9912",
      "created_at": "2026-08-28T12:56:45.102Z",
      "cached": false,
      "credits": {
        "balance": 142,
        "plan_credits": 120,
        "rollover_credits": 22,
        "charged": 1,
        "cached": false
      },
      "plan": {
        "code": "growth",
        "cycle": "monthly",
        "credits_per_cycle": 200,
        "requests_per_minute": 300,
        "period_ends_at": "2026-10-28T12:00:00.000Z"
      }
    }
  ],
  "credits": {
    "balance": 142,
    "plan_credits": 120,
    "rollover_credits": 22,
    "charged": 1,
    "cached": false
  },
  "plan": {
    "code": "growth",
    "cycle": "monthly",
    "credits_per_cycle": 200,
    "requests_per_minute": 300,
    "period_ends_at": "2026-10-28T12:00:00.000Z"
  }
}

credits.balance est le solde restant ; plan_credits et rollover_credits sont les compartiments de solde ; charged est le nombre de crédits réservés ou débités pour cette exécution, ou null si non applicable sur GET ; credits.cached vaut true en cas de réutilisation sans nouveau débit. plan inclut code (free, starter, growth ou custom), cycle (monthly, annual ou null), credits_per_cycle et period_ends_at. Ignorez ces champs s'ils ne vous sont pas utiles.

Récupérer une mise à jour

Appelez GET /api/v1/talent-updates/{id} pour suivre l'avancement et récupérer le profil terminé.

completed avec identity.confidence: "none" signifie que l'exécution a eu lieu mais que la personne n'a pas pu être identifiée avec certitude. Tant que status vaut pending, les champs du profil sont présents mais nuls ou vides.

Valeurs de status

pendingExécution en cours. Réinterrogez après un court délai.
completedExécution terminée. Les champs du profil sont présents (les tableaux peuvent être vides).
failedL'exécution a échoué. Consultez error pour le détail.

Tant que status vaut pending

{
  "id": "tu_01JCXY",
  "status": "pending",
  "candidate_id": "cand-9911",
  "created_at": "2026-08-28T12:56:44.642Z",
  "completed_at": null,
  "error": null,
  "identity": {
    "confidence": null,
    "full_name": null,
    "headline": null,
    "current_employer": null,
    "location": null
  },
  "work_experience": [],
  "education": [],
  "online_presence": [],
  "credits": {
    "balance": 142,
    "plan_credits": 120,
    "rollover_credits": 22,
    "charged": 1,
    "cached": false
  },
  "plan": {
    "code": "growth",
    "cycle": "monthly",
    "credits_per_cycle": 200,
    "requests_per_minute": 300,
    "period_ends_at": "2026-10-28T12:00:00.000Z"
  }
}

Lorsque status vaut completed

{
  "id": "tu_01JCXY",
  "status": "completed",
  "candidate_id": "cand-9911",
  "created_at": "2026-08-28T12:56:44.642Z",
  "completed_at": "2026-08-28T12:57:26.031Z",
  "error": null,
  "identity": {
    "confidence": "high",
    "full_name": "Alex Rivera",
    "headline": "Software Engineer at Example Corp",
    "current_employer": "Example Corp",
    "location": "London, UK"
  },
  "work_experience": [
    {
      "company": "Example Corp",
      "role": "Software Engineer",
      "start_date": "2016-01",
      "end_date": null,
      "is_current": true,
      "confidence": "high"
    }
  ],
  "education": [
    {
      "institution": "Example University",
      "qualification": "Bachelor of Science",
      "confidence": "high"
    }
  ],
  "online_presence": [
    {
      "platform": "linkedin",
      "url": "https://linkedin.com/in/alex-rivera-example",
      "confidence": "high"
    }
  ],
  "credits": {
    "balance": 142,
    "plan_credits": 120,
    "rollover_credits": 22,
    "charged": 1,
    "cached": false
  },
  "plan": {
    "code": "growth",
    "cycle": "monthly",
    "credits_per_cycle": 200,
    "requests_per_minute": 300,
    "period_ends_at": "2026-10-28T12:00:00.000Z"
  }
}

Champs de la réponse

Chaque réponse GET contient la structure du profil (identity, work_experience, education, online_presence). Tant que status vaut pending, ces champs sont nuls ou vides ; lorsqu'il vaut completed, ils contiennent les données résolues. Les réponses GET incluent aussi les mêmes objets additifs credits et plan que la création.

identityconfidence (high, medium, low, none, ou null pendant le traitement), full_name, headline, current_employer, location.
work_experienceChaque entrée : company, role, start_date, end_date, is_current, confidence.
educationinstitution, qualification, confidence.
online_presenceProfils découverts qui ne figurent pas déjà dans vos profile_urls. Chaque entrée : platform, url, confidence.
creditsSolde restant et débit de cette exécution : balance, plan_credits, rollover_credits, charged, cached.
planPlan actuel : code, cycle, credits_per_cycle, period_ends_at.

Les horodatages sont en UTC avec un Z. Les dates d'emploi sont généralement au format YYYY-MM.

Énumérations

Toute énumération peut accueillir de nouvelles valeurs. Traitez une valeur inconnue comme sa voisine la plus prudente, et non comme une erreur.

statuspending, completed, failed
identity.confidencehigh, medium, low, none, null (pending)
*.confidencehigh, medium, low
plan.codefree, starter, growth, custom
plan.cyclemonthly, annual, null

Erreurs

Les réponses non 2xx utilisent application/problem+json (RFC 9457). Appuyez-vous sur status et sur les codes d'erreur stables lorsqu'ils sont présents.

Statut

Cas

401

Clé d'API absente ou invalide, clé désactivée, ou partenaire suspendu.

402

Crédits épuisés (insufficient-credits). Réessayer ne servira à rien avant un rechargement ou une montée de forfait.

404

Identifiant d'exécution inconnu, ou appartenant à un autre partenaire.

422

Requête bien formée mais ne respectant pas la combinaison requise ou les règles de champs.

429

Limite de débit dépassée (rate-limit-exceeded). Respectez Retry-After, puis réessayez.

500

Impossible de démarrer ou de terminer l'exécution. Réessayable pour les appels en direct.

Exemple de réponse d'erreur

{
  "type": "https://intelligence.tietalent.com/errors/invalid-request",
  "title": "Unprocessable Entity",
  "status": 422,
  "detail": "A personal email address needs company or employer_website with it. Send first_name and last_name too where you have them."
}

Limites de débit et versionnage

Limites de débit

Votre forfait définit la vitesse à laquelle vous pouvez appeler l'API, en requêtes par minute : Free 10, Starter 60, Growth 300. Sur un forfait Custom, la limite est définie avec vous. Une unité correspond à une unité de travail : un lot en consomme une par candidat. Candidate Intelligence, Talent Update, Bypass Monitor et l'enrichissement CSV partagent cette même réserve. Les réponses réussies et les 429 contiennent RateLimit-Limit, RateLimit-Remaining et RateLimit-Reset ; un 429 ajoute Retry-After (secondes). Appliquez un back-off exponentiel avec jitter. Voir Candidate Intelligence › Limites de débit pour la référence complète. Les crédits sont un contrôle distinct : ils mesurent combien vous pouvez consommer, pas à quelle vitesse.

Retry-After: 42

Versionnage

La version figure dans le chemin (/v1). Des champs de réponse supplémentaires (y compris credits et plan) peuvent apparaître sans changement de version.

Webhooks

L'interrogation est prise en charge, mais les webhooks sont à privilégier lorsqu'ils sont configurés. La livraison est au moins une fois ; vos gestionnaires doivent être idempotents sur l'id de l'événement. Considérez GET /api/v1/talent-updates/{id} comme la source de vérité à tout moment.

Les points de terminaison de webhook sont configurés lors de l'intégration partenaire, sur la même infrastructure que Candidate Intelligence.

Types d'événements

talent_update_readyLa mise à jour s'est terminée avec succès.
talent_update_failedLa mise à jour a échoué. Contient error_code dans data.

Vérification de la signature

Chaque livraison porte un en-tête X-CI-Signature : t=<unix>,v1=<hmac-sha256> calculé sur "{t}.{raw_body}", en HMAC-SHA256 avec votre secret whsec_.... Vérifiez la signature et rejetez les horodatages de plus de cinq minutes.

X-CI-Signature: t=<unix>,v1=<hmac-sha256>

# Signed over "{t}.{raw_body}". Reject timestamps older than five minutes.

La charge utile du webhook est un simple pointeur : result_url, talent_update_id et candidate_id. Récupérez le profil complet par un GET authentifié.

api_environment reprend le libellé de la clé d'API ayant authentifié l'exécution (Production, Staging ou Test) : la même valeur que dans votre liste de clés d'API.

talent_update_ready

{
  "id": "evt_01JDABC",
  "type": "talent_update_ready",
  "created_at": "2026-08-28T12:57:26.031Z",
  "api_environment": "Production",
  "data": {
    "candidate_id": "cand-9911",
    "status": "completed",
    "result_url": "https://intelligence.tietalent.com/api/v1/talent-updates/tu_01JCXY",
    "talent_update_id": "tu_01JCXY"
  }
}

talent_update_failed

{
  "id": "evt_01JDABD",
  "type": "talent_update_failed",
  "created_at": "2026-08-28T12:57:30.031Z",
  "api_environment": "Production",
  "data": {
    "candidate_id": "cand-9911",
    "status": "failed",
    "result_url": "https://intelligence.tietalent.com/api/v1/talent-updates/tu_01JCXY",
    "talent_update_id": "tu_01JCXY",
    "error_code": "internal_error"
  }
}

Limites connues

Publier ces limites ouvertement est ce qui rend les autres chiffres dignes de confiance.

  • L'identité n'est rapportée que lorsqu'elle est corroborée par autre chose qu'un nom. Lorsque ce n'est pas possible, identity.confidence vaut none et les tableaux sont vides : le profil d'une autre personne n'est jamais renvoyé à la place.
  • Traitez une confiance low comme non vérifiée. Elle signifie que la correspondance repose sur peu d'éléments, ce qui est fréquent pour les noms répandus.
  • Un tableau vide signifie que l'information n'est pas publiquement disponible, et non que la requête a échoué.
  • Les dates d'emploi reprennent ce que publie la source. start_date peut être null : traitez les dates comme facultatives dans vos correspondances.
  • La couverture suit ce qui est public ; elle est plus faible pour les noms très répandus et pour les régions où les données professionnelles sont moins publiées.
  • Maximum 50 candidats par requête de précalcul par lot ; maximum 10 profile_urls par candidat.

Programme Partenaire

Commencez à intégrer Talent Update

Demandez l'accès et nous activerons vos identifiants d'API partenaire pour l'enrichissement Talent Update.

Contacter le service Partenariats