Contents
v1 · BetaPartner API
Candidate Intelligence API Integration
Give recruiters more confidence before interviews
Run Candidate Intelligence reports directly inside your ATS to verify candidate information, surface unexpected signals, and generate interview questions in seconds.
Request API AccessBest fit for
Applicant Tracking Systems (ATS)
Recruitment CRMs
Job Boards
Internal Talent Platforms
Executive Search Firms
HR Tech Vendors
Partner Benefits
Why Integrate Candidate Intelligence?
Give your customers additional context before interviews while creating new value inside your platform.
Increase Recruiter Engagement
Keep recruiters inside your ATS by providing candidate verification, interview preparation, and additional hiring insights directly within candidate profiles.
Create a New Revenue Stream
Offer Candidate Intelligence reports to your customers and earn recurring revenue through the partner program.
Differentiate Your Platform
Stand out from competing ATS and recruitment solutions with built-in Candidate Intelligence capabilities.
No Additional Research Required
Help recruiters uncover relevant information beyond the CV without leaving their workflow.
Improve Hiring Quality
Help recruiters and hiring managers make more informed decisions by providing additional context beyond the CV, highlighting verified findings, surfacing potential risks, and identifying areas that require further validation.
Fast Integration
Typical implementation requires only a few API endpoints and can be completed in less than a day.
Integration flow
Get approved and receive an API key
Request access from TieTalent. Once approved, you receive an API key for your integration.
Add a button inside candidate profiles
Add a "Run intelligence" button within candidate profiles. When clicked, it changes to "Running..." while the report generates. Once ready, the report opens automatically and the button becomes "✕ Close report". When closed, the button reverts to "View Intelligence report" to reopen a report you have already generated.
Call the TieTalent API when clicked
POST to /api/v1/analyses with the candidate, client (recruiter), and language data. Use your own external IDs on client.id and candidate.id.
TieTalent generates the report
The analysis runs in the background. Use GET /api/v1/analyses/{id} both to poll while status is queued or processing (wait at least 10 seconds between requests; see Retry-After) and to retrieve the completed report when status is completed. Call DELETE on the same path to cancel if the recruiter leaves the profile.
Optional: precompute on shortlist
When a candidate is shortlisted (or moves to a late pipeline stage), POST with mode: "precompute" so generation can finish before the recruiter clicks. Store the returned id and GET it when opening, or still POST live on click. Live always creates a new id but reuses valid cache content quickly. Do not trigger precompute on first profile open. See Precompute analyses.
Display the report in the candidate profile
Render the report JSON in your own UI (see Report types & fields), or open the full hosted report via the signed link in metadata.pdf_download_url: the hosted view also offers the PDF export.
Performance & Latency
Candidate Intelligence is designed to provide a responsive experience directly within recruiter workflows.
Action
Typical Response Time
Existing report found (live cache copy or precompute reuse)
< 1 second
Open a precomputed report (after precompute completed)
Instant (GET completed report)
New report generation
30–60 seconds
Report reuse logic
Reports are uniquely identified by platform + company + candidate.
Cache is scoped per recruiter: your API key identifies the partner integration, and client.id identifies the recruiter (user) within your platform. Different client.id values do not share cache, even under the same API key.
metadata.cached; precompute: same analysis id)Cache key fields
candidate.idYour external candidate IDcandidate.first_name + candidate.last_nameCandidate name (normalized)candidate.companyCurrent company (normalized)candidate.locationLocation (normalized)candidate.roleRole or job title (normalized)report_typeResolved report type (your partner default, or the per-call report_type override). A different report_type than a prior cached run is always a cache miss: a fresh report of the requested type is generated.Not part of the cache key
candidate.cvOptional CV text: used only on fresh runs. Changing the CV alone does not bust cache.languageRequested report language. Use force_refresh: true when you need a report in a different language.Cached reports are reused for up to 6 months. Completed analyses older than that are not returned from cache.
Force refresh
Set force_refresh: true on POST /api/v1/analyses to skip the cache lookup and run the full analysis pipeline: enrichment, live signals, and LLM report generation.
Omit force_refresh or set it to false to allow cache reuse (default).
When to set force_refresh: true
The recruiter explicitly requests updated or refreshed intelligence
Only the CV text changed while profile fields stayed the same
You need a report in a different language than a prior cached run
You want live signals and enrichment re-run regardless of cache
Fresh analysis request
{
"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
}Authentication
HTTP headers
X-API-Key: ats_your_api_key_here Content-Type: application/json
Create analysis
Optional body fields: candidate.cv (plain-text CV, used only on fresh runs), force_refresh (boolean, default false (see Force refresh), report_type ("hr" or "agency", overrides your partner default for this call only) see Report types & fields), and mode: "precompute" (see Precompute analyses; use candidates instead of candidate for batch).
{
"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 (optional, default false) skips report reuse and always generates a fresh report. The new report is billed. Omit it unless the recruiter explicitly requests a refresh.
202 Accepted
The Location header points to GET /api/v1/analyses/{id}. Retry-After: 10 indicates when to poll next.
{
"id": "cmqp23kgg00067gk0rh6jol5o",
"status": "queued",
"candidate_id": "candidate_456",
"created_at": "2026-06-29T12:00:00.000Z"
}Precompute analyses
Precompute generates a Candidate Intelligence report ahead of time (for example when a candidate is shortlisted) so the recruiter is less likely to wait 30–60s. Store the returned analysis id and GET it when they open the report, or POST a normal live create on click. Live still returns a new id every time, but reuses valid cache content in under a second.
POST /api/v1/analyses endpoint with mode: "precompute". There is no separate precompute URL. Poll and retrieve with the same GET /api/v1/analyses/{id} as live runs.Recommended triggers
Candidate shortlisted
Pipeline stage change into a late / interview-ready stage
Do not trigger on
- First profile open: avoided for privacy/GDPR and cost reasons after product review
Behavior
- Returns
202 Acceptedwith an analysis id immediately: no long-held connection and no streamed preliminary signals on create. - Idempotent: if the same partner + client (recruiter) + candidate fingerprint already has an in-flight run or a valid cached report (same 6-month reuse rules as live), the existing analysis id is returned and no new generation starts.
- Live (non-precompute)
POSTs still create a new analysis id every time; cache reuse for live runs copies the report onto that new id (unchanged). - Optional
force_refresh: trueskips completed-cache reuse for precompute (same semantics as live). An in-flight run for the same fingerprint is still returned instead of starting a duplicate.
Single-candidate precompute
Send mode: "precompute" with the same client and candidate objects as a live create. Response shape matches the live 202 Accepted body.
{
"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"
}
}Batch precompute
Send mode: "precompute" with candidates (array) instead of candidate. Provide exactly one of candidate or candidates. Maximum 50 candidates per request.
{
"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 (batch)
{
"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"
}
]
}Poll or fetch each returned id with GET /api/v1/analyses/{id}. When status is completed, report and metadata are populated. That is how you retrieve the ready report.
Precompute is capped per partner (1,000 net-new runs per UTC day and 10 concurrent in-flight). Exceeding a cap returns 429 Too Many Requests with error precompute-cap-exceeded and Retry-After. Cache or in-flight hits do not count toward these caps. Live runs are exempt.
Get analysis (poll & retrieve report)
Use GET /api/v1/analyses/{id} with the same X-API-Key header and the id from the create (or precompute) response. This single endpoint both polls in-progress runs and returns the completed report.
When status is completed, the response includes the full report object plus metadata (including pdf_download_url). There is no separate "get report" endpoint. Stop polling and render or open that payload. See Completed analysis for a full example.
While status is queued or processing, each GET response includes Retry-After: 10. Wait at least 10 seconds before your next request.
Stop polling when status is completed, failed, or canceled.
{
"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
}Fields that populate while processing
quick_signalPreliminary identity signal (Green, Orange, or Red) with a short reason: available once enrichment begins.signalsLive web signals discovered during enrichment. The array grows as external searches complete.stageCurrent pipeline stage: identity → enrichment → report → done.reportFull Candidate Intelligence report: populated only when status is completed. This is the report payload to display or store.metadataReport metadata: populated only when status is completed. Includes the signed hosted-report link (pdf_download_url) and the cached / cached_at reuse flags.Status values
queuedAccepted and waiting to start.processingIn progress: poll for quick_signal, signals, and stage updates.completedReport ready: use this GET response as your retrieved report (report and metadata are populated).failedAnalysis failed: error is populated.canceledAnalysis was canceled via DELETE /api/v1/analyses/{id} or reached a terminal cancel state.Cancel an analysis
DELETE /api/v1/analyses/{id} stops a queued or in-progress analysis when a recruiter leaves the candidate profile or dismisses a running report. Use the same X-API-Key header as POST and GET.
If the analysis is already completed, failed, or canceled, the endpoint returns the current resource unchanged. No additional charge or side effects.
// No request body: include X-API-Key header only
200 OK
Returns the analysis resource with status canceled. Partial quick_signal or signals may be present if cancellation happened mid-pipeline. Stop polling once status is canceled.
{
"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
}Report-ready webhooks
As an alternative to polling, TieTalent can push a signed HTTP notification to an endpoint registered for your integration the moment an analysis reaches a final state: report_ready when a report completes (live, precompute, or a cached reuse all count) or report_failed on a terminal failure.
Webhooks complement polling, they never replace it. Treat GET /api/v1/analyses/{id} as authoritative at all times and keep polling in place as a fallback for anything missed.
Event types
report_readyA final report is ready: covers live runs, precompute runs, and cache-reuse completions alike.report_failedThe run reached a terminal failure.Event envelope
Every delivery is a JSON object shaped like the examples below. id is generated once per event and reused on every retry of that same event. Use it as your idempotency key when deduplicating.
api_environment mirrors the label of the API key that authenticated the run (Production, Staging, or Test): the same value shown in your admin API key list. A key only ever delivers to the webhook endpoint registered under its own label.
{
"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=…"
}
}{
"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"
}
}data fields
analysis_idThe same id you would GET via /api/v1/analyses/{id}.candidate_idYour own candidate.id from the original request: not a TieTalent-internal identifier.client_idYour own client.id from the original request.statuscompleted or failed, matching the analysis resource's status.report_urlThe authed GET /api/v1/analyses/{id} URL: fetch it with your X-API-Key to retrieve the full report.pdf_download_urlThe signed hosted-report link, same as metadata.pdf_download_url on the GET response. Present on report_ready, null on report_failed.error_codePresent only on report_failed events: a stable, machine-readable code. Never exposes an internal AI provider or infrastructure detail.Verifying the signature
Every delivery carries an X-CI-Signature header in the form below. The signed content is {timestamp}.{raw_request_body}, HMAC-SHA256 with the whsec_... secret issued for your endpoint.
X-CI-Signature header
X-CI-Signature: t=1732963521,v1=5d6f2c8a9e1b7340c6a2f5e8b1d9a047c3b6e2f1a8d5c9b4e7f2a1d6c3b8e5f0
During a secret rotation window the header may carry two v1= values: one signed with the outgoing secret, one with the incoming secret. Accept a match against either.
Reject any delivery whose t= timestamp is more than 5 minutes from your own clock: this is your replay-attack defense.
Verifying the 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));
}Delivery semantics
- At-least-once delivery: a 2xx response within 5 seconds counts as success; anything else retries with exponential backoff and jitter, roughly 10 attempts over about 24 hours, then the event is dead-lettered.
- Duplicate and out-of-order deliveries are expected: dedupe on
idand never assume delivery order across events. - If a webhook is ever missed, delayed, or duplicated, your existing polling fallback keeps your state consistent with the authed GET.
Completed analysis
Returned when status is completed. The report below is an HR-type example and abridged: see Report types & fields for the full field list and the Agency-type example.
Fresh report (metadata.cached: false)
{
"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
}Cached report (metadata.cached: true)
{
"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
}The metadata object
metadata.pdf_download_url is a signed link that opens the full hosted TieTalent report (the same report design as the web app); the PDF export can be downloaded from that view. Treat the link as confidential. Anyone holding it can open the report.
metadata.cached is true when an existing report was reused instead of generating a new one (see Report reuse logic); cached_at then carries the reuse timestamp, otherwise it is null.
metadata.report_type (hr or agency) tells you which report shape the report object follows: see Report types & fields. It is set once for your integration by TieTalent and cannot be overridden per request.
Verdicts & compatibility
report.recommendation.decision is the headline verdict of the report. It is always one of the four values below.
recommendation.decision: possible values
"Proceed with confidence" "Go with validation" "Requires Validation (Signals flagged)" "Requires Validation (Insufficient data)"
Map each verdict to one of three UI states:
Suggested mapping (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";
}
}requires_validation so any unexpected value degrades gracefully instead of breaking your UI.Report types & fields
Every partner account has a default report_type (hr or agency) set for you by TieTalent when your integration is approved (hr is the default). You can override it for a single call (see below). The type used for a given report is always echoed back as metadata.report_type and report.report_type. Field names are camelCase.
Per-call override
Pass an optional report_type field ("hr" or "agency") on POST /api/v1/analyses to use that type for a single call, regardless of your partner account's default. Omit it to keep using your default. The override is not persisted. It applies only to that call. An invalid value returns 400 Bad Request with error invalid-report-type. report_type is also part of the cache key. Requesting a different type than a prior cached run for the same candidate always triggers a fresh report.
Request with report_type override
{
"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"
}Core fields (present on both report types)
report_typehr or agency: which shape this report object follows.candidateNameCandidate name as resolved by the analysis.profileHeadline / profileCompany / profileLocationHeader lines for display: role/title, current company, and location. Optional.sourcesCheckedCountNumber of external search results consulted for the report. Optional.identityIdentity resolution: status (Confirmed, Likely, Ambiguous, Unknown), confidence, confidenceReason, and risk (level, reason).recommendationThe verdict: decision (see Verdicts & compatibility), confidence, reason, evidence[], confidenceNote (short evidence headline), and nextStepPills[] (evidence-state pills with variant and label).bottomLineThe report's opening verdict: headline (one decisive sentence) and detail (1-2 sentences of supporting context).keyTakeawaysstandsOut[] and needsChecking[] lists of (label, detail) items.surprisingInsightsUp to 3 cards (title, text, source, polarity): polarity is Favorable or Concern.externalBackgroundAssessmentEvidence table rows (claim, summary, evidenceBadge, sourceReference?) checking CV/profile claims against external signals: gap-inclusive, so a row with evidenceBadge not_found means no external signal was found for that claim.externalProfileTagsCatalog-only tags from the source_presence and adverse_signal_status groups: see Tags below.alertLevelOverall alert level: Green, Yellow, Orange, or Red.externalDataConfidenceConfidence in the external data behind the report: High, Medium, or Low.hr-only fields
Present only when report_type is hr. Absent (not null, not present) on agency reports.
roleFitbestSuited[] and considerCarefully[]: role/organisation contexts this profile suits vs. contexts needing more validation.interviewQuestionsSuggested interview questions: (question, hint).agency-only fields
Present only when report_type is agency. Absent (not null, not present) on hr reports.
bestFitTagsCatalog tags describing where this profile sits: see Tags below.takeItForward"Worth knowing if you take this forward": worthItFor[] (plain-sentence reasons) and reflectionQuestions[] (question, answer).Example hr report object
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"
}Example agency report object
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"
}Enumerations
Enum values
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 and bestFitTags are catalog-only for this API (every tag carries a stable snake_case id you can switch on. Tag ids are stable API values and are not localized) map them to your own labels or humanize the id.
Tag shape
// 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: catalog ids by group
// 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: catalog ids by group (agency reports only)
// 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
Submit feedback on a report
POST /api/v1/analyses/{id}/feedback lets your recruiters rate a completed report (1 to 5 stars, optional tags, and optional free text) so TieTalent can track report quality on your side of the integration.
The endpoint upserts on client.id plus the report id: submitting again for the same client and report overwrites the previous rating, tags and text. There is no revision history.
{
"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"]
}Request fields
clientRequired. Same client object as POST /api/v1/analyses: identifies which of your users is giving feedback.ratingRequired. Integer from 1 to 5.feedbackOptional. Free-text comment, up to 2000 characters.tagsOptional. Up to 5 canonical tag ids from the catalog below: invalid values or an out-of-range rating return a 4xx with a clear message.Feedback tag catalog
Tags are grouped by rating band and swap depending on the rating you send: render your own UI for these, but submit only the canonical ids so feedback stays analyzable across languages.
Canonical tag ids by rating band
// 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
Returns the stored feedback, echoing back the current rating, tags and text on file for that client and report.
{
"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"
}Recommended partner UI
Add a button inside candidate profiles
Add a "Run intelligence" button within candidate profiles. When clicked, it changes to "Running..." while the report generates. Once ready, the report opens automatically and the button becomes "✕ Close report". When closed, the button reverts to "View Intelligence report" to reopen a report you have already stored, without calling POST again.
No report exists
Report generating
Report is open
Report closed / exists
Privacy & security
client.id and candidate.id to map analyses to records in your ATS.⚖️ AI Compliance Notice
Candidate Intelligence is designed to support recruiter decision-making, not replace it. Hiring decisions remain the responsibility of the employer and should always include appropriate human review and oversight.
Partner Program
Start integrating Candidate Intelligence
Request access and we will activate your partner API credentials. Integration typically takes less than a day.