---
title: "Candidate Score - Evaluate Pre-Extracted Pair"
method: POST
path: "/candidate-score/evaluate"
tags: ["Exato - Candidate Score"]
---

# Candidate Score - Evaluate Pre-Extracted Pair

`POST /candidate-score/evaluate`

Scores an already-extracted candidate against an already-extracted job position. Mode 1 (with jd_extraction_json): 0-100 score. Mode 2 (without): dual heatmap matrices. PDF: send render_html=true and the report PDF is stored at d.exa.to/{uid}.pdf. It is produced AFTER the response by default, so allow a few seconds on a sync call; on an async call it already exists once the poll reports the run complete. While a render is still in flight the PDF endpoint answers success_with_remarks rather than the bytes. Send options.generate_pdf_sync=true to make a sync call wait for it instead. Fetching a stored result: pass uid + exec_mode=result, and send include_html_report=false when you only read the structured fields — the report string is ~90% of a full body and omitting it changes nothing about the stored row or the PDF.

## Query parameters

- `test_mode` boolean
- `lightweight` boolean

## Response `200`

Success

- CandidateScoreEvaluateResponse — CandidateScoreEvaluateResponse
  - `ApiResultType` 'Success' | 'SuccessWithRemarks' | 'InvalidInput' | 'DataUnavailable' | 'NotFound' | 'InvalidParameters' | 'UnsupportedCombination' | 'RemoteUnavailable' | 'Timeout' | 'RetryLimitReached' | 'RemoteError' | 'InProgress' | 'InsufficientCredits' | 'ConcurrentLimitReached' | 'TransactionUnavailable' | 'AccessDenied' | 'TransactionCancelled' | 'Created' | 'Updated' | 'Deleted' | 'InternalError' | 'ValidationFailed' | 'Conflict' | 'ResourceLocked' | 'PendingApproval' | 'Approved' | 'Rejected' | 'Cancelled' | 'Paused' | 'Resumed' — Novo tipo de resultado unificado para queries e operações administrativas. Substitui TransactionResultType com melhor semântica.
  - `BalanceInBrl` number, double — Saldo atual em BRL.
  - `BalanceInCredits` integer — Saldo atual em créditos.
  - `DataSourceCategory` string — Categoria da fonte de dados
  - `Date` string, date-time — Data da transação.
  - `ElapsedTimeInMilliseconds` integer — Tempo de execução (em milisegundos).
  - `HasPdf` boolean — Indica que existe PDF de comprovante do resultado.
  - `Message` string — Mensagem.
  - `OriginalFilesUrl` string — Url para download dos arquivos originais da transação (quando disponíveis).
  - `OutdatedResult` boolean — Indica que o resultado é datado.
  - `PdfUrl` string — Url para download do arquivo de comprovante em PDF da transação (quando disponível).
  - `ResultSubtype` string — Subtipo específico do resultado para fornecer contexto adicional (ex: 'duplicate_name', 'invalid_cpf').
  - `ResultTypeCode` integer — Código numérico do resultado (compatível com TransactionResultTypeCode mas extensível).
  - `TotalCost` number, double — Internal use only.
  - `TotalCostInCredits` integer — Custo total da transação em créditos.
  - `TransactionResultType` 'Success' | 'SuccessWithRemarks' | 'InvalidInputData' | 'UnavailableData' | 'EntityNotFound' | 'InvalidParameters' | 'ParametersNotSupported' | 'RemoteSystemUnavailable' | 'Timeout' | 'AttemptsLimitReached' | 'RemoteSystemError' | 'AsyncExecutionInProgress' | 'AwaitingExecution' | 'BirthDateRequired' | 'InsufficientBalance' | 'SimultaneousTransactionsLimitReached' | 'TransactionUnavailable' | 'AccessDenied' | 'TransactionCancelled' | 'InternalError' — <table class="transaction"><thead><tr><th>TransactionResultType Code</th><th>TransactionResultType</th><th>Definitivo</th><th>Faturavel</th><th>Erro</th></tr></thead><tbody><tr><td>1</td><td>Sucesso</td><td>Verdadeiro</td><td>Verdadeiro</td><td>Falso</td></tr><tr><td>2</td><td>Sucesso parcial ou com observações</td><td>Verdadeiro</td><td>Verdadeiro</td><td>Falso</td></tr><tr><td>3</td><td>Entrada ou documento inválido</td><td>Verdadeiro</td><td>Falso</td><td>Verdadeiro</td></tr><tr><td>4</td><td>Dados não disponíveis</td><td>Verdadeiro (no dia)</td><td>Falso</td><td>Falso</td></tr><tr><td>5</td><td>Entidade ou documento inexistente/não encontrado</td><td>Verdadeiro</td><td>Verdadeiro</td><td>Falso</td></tr><tr><td>6</td><td>Parâmetros de entrada inválidos</td><td>Verdadeiro</td><td>Falso</td><td>Verdadeiro</td></tr><tr><td>7</td><td>Combinação de parâmetros não suportados</td><td>Verdadeiro</td><td>Falso</td><td>Verdadeiro</td></tr><tr><td>8</td><td>Fonte de dados ou sistema remoto indisponível</td><td>Falso</td><td>Falso</td><td>Verdadeiro</td></tr><tr><td>9</td><td>Limite de tempo esgotado</td><td>Falso</td><td>Falso</td><td>Verdadeiro</td></tr><tr><td>10</td><td>Limite de tentativas atingido</td><td>Falso</td><td>Falso</td><td>Verdadeiro</td></tr><tr><td>11</td><td>Erro na fonte de dados ou sistema remoto</td><td>Falso</td><td>Falso</td><td>Verdadeiro</td></tr><tr><td>12</td><td>Transação em execução</td><td>Falso</td><td>Falso</td><td>Falso</td></tr><tr><td>101</td><td>Saldo em créditos insuficiente, entre em contato</td><td>Falso</td><td>Falso</td><td>Verdadeiro</td></tr><tr><td>102</td><td>Limite de transações simultâneas atingido, entre em contato</td><td>Falso</td><td>Falso</td><td>Verdadeiro</td></tr><tr><td>103</td><td>Transação não disponível, entre em contato</td><td>Falso</td><td>Falso</td><td>Verdadeiro</td></tr><tr><td>104</td><td>Credenciais inválidas ou acesso negado, entre em contato</td><td>Falso</td><td>Falso</td><td>Verdadeiro</td></tr><tr><td>105</td><td>Transação cancelada, entre em contato</td><td>Falso</td><td>Falso</td><td>Verdadeiro</td></tr><tr><td>255*</td><td>Erro interno não esperado, entre em contato</td><td>Verdadeiro (no dia)</td><td>Falso</td><td>Verdadeiro</td></tr><tr><td>* Consulta em manutenção, tente refazer mais tarde ou entre em contato com a Direct Digital para notificação do problema</td></tr></tbody></table>
  - `TransactionResultTypeCode` integer — Código do tipo de resultado da transação.
  - `UniqueIdentifier` string — Identificador único da transação. Recomendado armazenar para controle e depuração.
  - `Result` CandidateScoreResult — CandidateScoreResult
    - `ScoringMode` string — WithJd or WithoutJd
    - `DataOrigin` string — LinkedIn or Resume
    - `TotalScore` integer — Overall score 0-100 (Mode 1)
    - `ExperienceScore` integer — Experience fit 0-100
    - `SkillsScore` integer — Skills match 0-100
    - `EducationScore` integer — Education match 0-100
    - `CertificationsScore` integer — Certifications match 0-100
    - `LocationScore` integer — Location match 0-100
    - `LanguagesScore` integer — Languages proficiency match 0-100
    - `VirtualRecruiterAssessment` string — LLM-generated qualitative assessment (Mode 1)
    - `Differentiators` DifferentiatorResult[] — Unstated-but-present candidate attributes (Mode 1). 0-5 entries: language/cert/education/experience the candidate exhibits that the JD did NOT ask for but may matter to the role.
      - `Text` string — One-sentence pt-BR description, ≤ 180 chars
      - `Category` string — Idioma | Formação | Certificação | Experiência | Outro
    - `Overqualified` OverqualifiedAssessmentResult — OverqualifiedAssessmentResult
      - `IsOverqualified` boolean — True when the candidate is materially over-qualified for this role (seniority gap ≥ 2 levels, tenure ≥ 1.5× JD baseline, or terminal education materially exceeds JD).
      - `Reason` string — pt-BR rationale (≤ 180 chars, one sentence) naming the trigger that fired. Empty when is_overqualified=false.
    - `RequirementsGate` RequirementsGateResult — RequirementsGateResult
      - `Status` string — met | not_verified | not_met | no_must_requirements. 'partial' on a must does not trip the gate (evidence exists with gaps; the score already prices it). not_verified means a must could not be proven from the documents (absence of evidence), never that the candidate lacks it.
      - `MustTotal` integer — Number of must-priority JD requirements evaluated.
      - `MustMet` integer — Musts judged met.
      - `MustPartial` integer — Musts judged partially met.
      - `MustNotFound` integer — Musts with no evidence either way in the candidate documents.
      - `MustContradicted` integer — Musts with explicit contrary evidence in the candidate documents.
      - `Unmet` UnmetRequirementResult[] — Every must with status not_found or contradicted, in JD order.
        - `Text` string — Requirement text as stated in the JD.
        - `Status` string — not_found | contradicted.
    - `Requirements` RequirementResult[] — Judged JD requirements checklist the gate is derived from (Mode 1). Each entry carries text, priority (must/should/could; null when the text didn't join to the JD or the run predates priority stamping) and status (met | partial | not_found | contradicted; legacy runs may carry 'miss'; pre-filter gated pairs carry 'not_evaluated'). Null when the run carries no checklist (Mode 2).
      - `Text` string — Requirement text as stated in the JD.
      - `Priority` string — must | should | could. Null when the requirement text didn't join to the JD's key requirements or the run predates priority stamping.
      - `Status` string — met | partial | not_found | contradicted ('miss' on legacy runs; 'not_evaluated' on pre-filter gated pairs).
    - `FunctionalAreaMatrix` MatrixResult — MatrixResult
      - `RowLabels` string[] — Row axis labels (functional areas or industry verticals)
      - `ColumnLabels` string[] — Column axis labels (seniority levels)
      - `Cells` MatrixCellResult[] — Matrix cells with scores. Cells scoring below the matrix visibility threshold are omitted.
        - `Row` integer
        - `Col` integer
        - `RowLabel` string
        - `ColLabel` string
        - `Score` integer
        - `CrossReferenceTags` string[]
    - `IndustryVerticalMatrix` MatrixResult — MatrixResult
      - `RowLabels` string[] — Row axis labels (functional areas or industry verticals)
      - `ColumnLabels` string[] — Column axis labels (seniority levels)
      - `Cells` MatrixCellResult[] — Matrix cells with scores. Cells scoring below the matrix visibility threshold are omitted.
        - `Row` integer
        - `Col` integer
        - `RowLabel` string
        - `ColLabel` string
        - `Score` integer
        - `CrossReferenceTags` string[]
    - `CandidateName` string — Candidate name
    - `TotalCareerYears` number, double — Total career years
    - `ExperienceCount` integer — Number of experience entries
    - `HtmlReport` string — Self-contained A4 HTML report. PDF input, not a web page: render it with a Chromium-based engine. A browser or wkhtmltopdf ignores the @page rules and flattens it into one continuous column.
    - `ElapsedTimeMs` integer — Processing time in ms
    - `LlmCalls` integer — Number of LLM API calls
    - `TotalInputTokens` integer — Total input tokens across all LLM calls
    - `TotalOutputTokens` integer — Total output tokens across all LLM calls
    - `ExtractionElapsedMs` integer — Extraction phase time in ms
    - `ScoringElapsedMs` integer — Scoring phase time in ms
    - `ExtractionProvider` string — Provider used for extraction (Haiku/Mercury/Haiku (fallback))
    - `ExtractionModel` string — Model ID used for extraction
    - `ScoringProvider` string — Provider that actually performed scoring, with a " (fallback)" suffix when a higher-priority provider failed first. Read this and scoring_model to tell a primary answer from a degraded one: both are resolved per attempt, unlike precision_preset, which echoes what was requested.
    - `ScoringModel` string — Model ID that ANSWERED the scoring call, resolved per attempt — so on a fallback it names the rung that replied, not the preset's primary. It is not an echo of the request; precision_preset is. Pair it with scoring_provider, whose " (fallback)" suffix says a descent happened.
    - `TaxonomyMode` string — Taxonomy mode (Full/Compact)
    - `PrecisionPreset` string — Precision preset this result was produced under: Turbo | Fast | Balanced | Precise | Maximum | Bulk | BulkSelfHosted | BulkGlobal | BulkFast | BalancedGoogle | Express. Read scoring_model for the model that actually answered, which differs from the preset's primary when a fallback fired.
    - `CacheCreationTokens` integer — Total cache creation tokens (Anthropic)
    - `CacheReadTokens` integer — Total cache read tokens (Anthropic)
    - `EducationsExtracted` integer — Number of education entries extracted
    - `CodesNormalized` integer — Taxonomy codes normalized by post-processing
    - `ClassificationsGapFilled` integer — Industry verticals gap-filled by CNPJ/catalog lookup
    - `ExtractionJsonParseStrategy` string — JSON parse strategy for extraction (direct/code_block/brace_extraction)
    - `ScoringJsonParseStrategy` string — JSON parse strategy for scoring (direct/code_block/brace_extraction)
    - `InconsistencyFindings` InconsistencyFindingResult[] — Inconsistency findings (null when SUB 19105 didn't run)
      - `RuleId` integer — Stable numeric ID of the rule (matches InconsistencyRuleCode enum value)
      - `RuleCode` string — Symbolic rule code (e.g. A1_ExperienceVsAge)
      - `Category` string — Tier classification (InternalLogical/CrossSource/DossierCrossValidation/DocumentIntegrity)
      - `Severity` string — Severity tier (Info/Warning/Critical)
      - `Headline` string — One-line pt-BR summary
      - `Detail` string — Detailed pt-BR explanation
      - `EvidenceExcerpt` string — Optional pt-BR excerpt from the source
      - `RecommendedAction` string — Optional pt-BR recommended action for the recruiter
      - `Metadata` DictionaryStringString — Dictionary<String,String>
    - `InconsistencyAggregateRag` string — Aggregate RAG indicator (Green/Amber/Red). Null when SUB 19105 didn't run.
    - `InconsistencyCriticalCount` integer — Number of Critical findings
    - `InconsistencyWarningCount` integer — Number of Warning findings
    - `InconsistencyInfoCount` integer — Number of Info findings
    - `InconsistencyDetectionElapsedMs` integer — Inconsistency detection phase time in ms
    - `FeedbackLetterPtBr` string — Validated pt-BR feedback letter (40-100 words). Null when SUB 19106 didn't run or failed validation.
    - `FeedbackLetterWordCount` integer — Word count of the rendered feedback letter (40-100 when Success=true; the prompt targets 70-100 with a strength-recognition sentence, 50-75 without one).
    - `FeedbackLetterSuccess` boolean — True when SUB 19106 generated AND validated the letter. False when cosmetic failure (validator/chain). Null when SUB 19106 didn't run.
    - `FeedbackLetterFailureReason` string — Categorized failure when Success=false (chain_exhausted / validator_word_count / validator_banned_phrase / validator_exclamation / empty_response / missing_candidate_name / missing_gap_anchors / no_client_available / exception / cancelled). Null when Success=true or SUB didn't run.
    - `FeedbackLetterRoleNamedInGreeting` string — Exact role title used in the greeting; null when include_role_in_greeting=false or no role available.
    - `FeedbackLetterStrengthAnchorUsed` string — Strength anchor referenced in the recognition sentence; null when omitted (request flag or graceful omission).
    - `FeedbackLetterGapAnchorsUsed` string[] — Gap anchors (1-2) referenced in the gap sentence; empty array when SUB didn't run.
    - `FeedbackLetterProvider` string — Provider that produced the letter (display label, includes '(fallback)' suffix when a fallback hop succeeded). Null when SUB didn't run.
    - `FeedbackLetterModel` string — Model ID that produced the letter (e.g. claude-haiku-4-5). Null when SUB didn't run.
    - `FeedbackLetterElapsedMs` integer — SUB 19106 phase time in ms. Null when SUB didn't run.
    - `FeedbackLetterInputTokens` integer — Letter LLM call input tokens. Null when SUB didn't run.
    - `FeedbackLetterOutputTokens` integer — Letter LLM call output tokens. Null when SUB didn't run.
    - `PreFilterEvaluated` boolean — Whether the pre-filter stage ran on this pair.
    - `PreFilterGated` boolean — Whether the pre-filter short-circuited LLM scoring + cosmetic SUBs.
    - `PreFilterEstimatedInternalScore` number, double — Calibrated cosine projection of internal_score (0.0-1.0).
    - `PreFilterThreshold` number, double — Threshold applied to the estimate (0.0-1.0).
    - `PreFilterMatcherVersion` string — Funnel document embedder tag (e.g. 'embeddinggemma-300m-onnx-int8-sts-v1').
    - `PreFilterFormulaVersion` string — Funnel calibrator version (e.g. 'funnel-cosine-isotonic-gbm-stage1-2026-06-03').
    - `PreFilterElapsedMs` integer — Pre-filter call time in ms. Null when the stage didn't run.
    - `CandidateExtractionLlm` LlmStepResult — LlmStepResult
      - `Model` string — Model ID sent in the API request (e.g. claude-haiku-4-5).
      - `ProviderLabel` string — Display label of the resolved provider (includes '(fallback)' suffix when a fallback hop succeeded).
      - `DisplayName` string — Friendly display name from the client.
      - `VendorName` string — Company that created the model (Anthropic, OpenAI, Inception, DeepInfra).
      - `BackendName` string — API platform the model is called through (Anthropic, Bedrock, OpenAI).
      - `InputTokens` integer — Input tokens for this step.
      - `OutputTokens` integer — Output tokens for this step.
      - `ReasoningTokens` integer — Reasoning tokens (GPT-5 / Gemini thinking / DeepSeek V4 think-mode). Counted toward billable output. Zero for non-reasoning calls.
      - `CacheCreationTokens` integer — Tokens written to prompt cache (Anthropic cache_creation_input_tokens). Zero elsewhere.
      - `CacheReadTokens` integer — Tokens read from prompt cache (Anthropic cache_read_input_tokens or OpenAI cached_tokens).
      - `ElapsedMs` integer — Wall-clock time spent in this SUB, including post-LLM normalization.
      - `JsonParseStrategy` string — JSON parse strategy used (direct / code_block / brace_extraction). Null for free-form text steps (SUB 19106).
      - `UsedStructuredOutputs` boolean — True when the call used response_format=json_schema/json_object. Null when not tracked by the SUB.
      - `DerivedCostUsd` number, double — Per-call cost in USD (uncached worst-case). Null when the rate card has no entry for the (vendor, backend, model) tuple.
    - `JdExtractionLlm` LlmStepResult — LlmStepResult
      - `Model` string — Model ID sent in the API request (e.g. claude-haiku-4-5).
      - `ProviderLabel` string — Display label of the resolved provider (includes '(fallback)' suffix when a fallback hop succeeded).
      - `DisplayName` string — Friendly display name from the client.
      - `VendorName` string — Company that created the model (Anthropic, OpenAI, Inception, DeepInfra).
      - `BackendName` string — API platform the model is called through (Anthropic, Bedrock, OpenAI).
      - `InputTokens` integer — Input tokens for this step.
      - `OutputTokens` integer — Output tokens for this step.
      - `ReasoningTokens` integer — Reasoning tokens (GPT-5 / Gemini thinking / DeepSeek V4 think-mode). Counted toward billable output. Zero for non-reasoning calls.
      - `CacheCreationTokens` integer — Tokens written to prompt cache (Anthropic cache_creation_input_tokens). Zero elsewhere.
      - `CacheReadTokens` integer — Tokens read from prompt cache (Anthropic cache_read_input_tokens or OpenAI cached_tokens).
      - `ElapsedMs` integer — Wall-clock time spent in this SUB, including post-LLM normalization.
      - `JsonParseStrategy` string — JSON parse strategy used (direct / code_block / brace_extraction). Null for free-form text steps (SUB 19106).
      - `UsedStructuredOutputs` boolean — True when the call used response_format=json_schema/json_object. Null when not tracked by the SUB.
      - `DerivedCostUsd` number, double — Per-call cost in USD (uncached worst-case). Null when the rate card has no entry for the (vendor, backend, model) tuple.
    - `ScoringLlm` LlmStepResult — LlmStepResult
      - `Model` string — Model ID sent in the API request (e.g. claude-haiku-4-5).
      - `ProviderLabel` string — Display label of the resolved provider (includes '(fallback)' suffix when a fallback hop succeeded).
      - `DisplayName` string — Friendly display name from the client.
      - `VendorName` string — Company that created the model (Anthropic, OpenAI, Inception, DeepInfra).
      - `BackendName` string — API platform the model is called through (Anthropic, Bedrock, OpenAI).
      - `InputTokens` integer — Input tokens for this step.
      - `OutputTokens` integer — Output tokens for this step.
      - `ReasoningTokens` integer — Reasoning tokens (GPT-5 / Gemini thinking / DeepSeek V4 think-mode). Counted toward billable output. Zero for non-reasoning calls.
      - `CacheCreationTokens` integer — Tokens written to prompt cache (Anthropic cache_creation_input_tokens). Zero elsewhere.
      - `CacheReadTokens` integer — Tokens read from prompt cache (Anthropic cache_read_input_tokens or OpenAI cached_tokens).
      - `ElapsedMs` integer — Wall-clock time spent in this SUB, including post-LLM normalization.
      - `JsonParseStrategy` string — JSON parse strategy used (direct / code_block / brace_extraction). Null for free-form text steps (SUB 19106).
      - `UsedStructuredOutputs` boolean — True when the call used response_format=json_schema/json_object. Null when not tracked by the SUB.
      - `DerivedCostUsd` number, double — Per-call cost in USD (uncached worst-case). Null when the rate card has no entry for the (vendor, backend, model) tuple.
    - `FeedbackLetterLlm` LlmStepResult — LlmStepResult
      - `Model` string — Model ID sent in the API request (e.g. claude-haiku-4-5).
      - `ProviderLabel` string — Display label of the resolved provider (includes '(fallback)' suffix when a fallback hop succeeded).
      - `DisplayName` string — Friendly display name from the client.
      - `VendorName` string — Company that created the model (Anthropic, OpenAI, Inception, DeepInfra).
      - `BackendName` string — API platform the model is called through (Anthropic, Bedrock, OpenAI).
      - `InputTokens` integer — Input tokens for this step.
      - `OutputTokens` integer — Output tokens for this step.
      - `ReasoningTokens` integer — Reasoning tokens (GPT-5 / Gemini thinking / DeepSeek V4 think-mode). Counted toward billable output. Zero for non-reasoning calls.
      - `CacheCreationTokens` integer — Tokens written to prompt cache (Anthropic cache_creation_input_tokens). Zero elsewhere.
      - `CacheReadTokens` integer — Tokens read from prompt cache (Anthropic cache_read_input_tokens or OpenAI cached_tokens).
      - `ElapsedMs` integer — Wall-clock time spent in this SUB, including post-LLM normalization.
      - `JsonParseStrategy` string — JSON parse strategy used (direct / code_block / brace_extraction). Null for free-form text steps (SUB 19106).
      - `UsedStructuredOutputs` boolean — True when the call used response_format=json_schema/json_object. Null when not tracked by the SUB.
      - `DerivedCostUsd` number, double — Per-call cost in USD (uncached worst-case). Null when the rate card has no entry for the (vendor, backend, model) tuple.
    - `TotalLlmCostUsd` number, double — Sum of derived per-stage costs in USD using the uncached-worst-case formula. Null when no stage has a rated backend.
    - `InterviewChecklistSuccess` boolean — Whether SUB 19107 (interview checklist split call) succeeded. Null when the SUB didn't run.
    - `InterviewChecklistSkippedByGate` boolean — True when the deterministic NonMatchChip gate suppressed the checklist without an LLM call (internal_score at/below the minimum-adherence threshold).
    - `InterviewChecklistItemCount` integer — Number of checklist items produced (0 on a gate skip). Null when the SUB didn't run.
    - `InterviewChecklistProvider` string — Provider that produced the checklist (display label, includes '(fallback)' suffix when a fallback hop succeeded). Null when the SUB didn't run or the gate skipped.
    - `InterviewChecklistModel` string — Model ID that produced the checklist. Null when the SUB didn't run or the gate skipped.
    - `InterviewChecklistElapsedMs` integer — SUB 19107 phase time in ms (runs parallel with the letter SUB). Null when the SUB didn't run.
    - `InterviewChecklistInputTokens` integer — Checklist LLM call input tokens. Null when the SUB didn't run or the gate skipped.
    - `InterviewChecklistOutputTokens` integer — Checklist LLM call output tokens. Null when the SUB didn't run or the gate skipped.
    - `SalaryScore` integer — Salary compatibility match 0-100. The seventh factor of the rubric; published from 2026-08-17, having been computed all along and dropped at the DTO boundary while its six siblings were carried.
    - `Factors` CandidateScoreFactor[] — The seven rubric factors (Mode 1). ALWAYS seven entries in canonical order, including factors this JD does not weigh — `score` is null rather than 0 on those, because a zero would claim the candidate scored badly on something nobody asked about. Each row carries name, key, score, reasoning, weight, role and counts. Null in Mode 2 or when the pre-filter gated the pair.
      - `Name` string — Canonical factor name as the scoring math keys it (Experiência, Competências, Formação, Idiomas, Localização, Certificações, Compatibilidade Salarial).
      - `Key` string — Stable ASCII key for matching without an accented string. Closed set: experiencia | competencias | formacao | idiomas | localizacao | certificacoes | salarial.
      - `Score` integer — 0-100. NULL when this factor carries no score, because the JD did not ask for it or the model omitted it. Never 0 as a stand-in: a zero is a statement about the candidate, an absent score is a statement about the vacancy.
      - `Reasoning` string — The model's written justification for this factor. Null on a row it did not emit — there is no rationale for a judgment never made.
      - `Weight` number, double — Weight this factor carries in the aggregate (0.30 experiência, 0.25 competências, 0.15 formação, 0.10 idiomas, 0.10 localização, 0.05 certificações, 0.05 salarial). Published so a caller recomputing the total does not keep its own copy.
      - `Role` string — required | differential | not_requested. Tri-state on purpose: a differential is a bonus axis where meeting it helps and missing it is never a penalty, so rendering it the same as not_requested tells the reader the vacancy does not care about something it treats as a plus. Null on runs predating formula 1.5.0.
      - `DifferentialMet` boolean — Set only when role=differential: whether the candidate demonstrably meets it. False or null withholds the bonus and never applies a penalty.
      - `Counts` boolean — Whether this factor entered the renormalized aggregate — the deterministic gate behind `role`.
    - `InterviewChecklist` CandidateScoreChecklistItem[] — The interview checklist questions (Mode 1). Null when SUB 19107 did not run or the NonMatchChip gate suppressed it — distinguishable from an empty list on purpose, so a consumer draws nothing rather than an empty control. `purpose` is RECRUITER-facing: do not render it anywhere a candidate may read it.
      - `Question` string — The interview question, pt-BR.
      - `Purpose` string — verify_strength | probe_gap | clarify_ambiguity. RECRUITER-FACING: do not render it anywhere a candidate may read it, on screen or in print. A candidate who sees 'probe_gap' beside a question feels pre-judged before the interview starts.

---

[API](https://skmtc.dev/directdigital/apis/backend-apis.md) · [All operations](https://skmtc.dev/directdigital/apis/backend-apis/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/directdigital/backend-apis/revisions/a3305895eccd/schema)
