What the benchmark measures
Three signals, three metrics. Each metric is a rate over the rows that returned a definite verdict — rows where TruthFactor returnedtrusted: null are excluded from that metric’s
denominator (see the verdict model).
In verdict terms, every metric is
#(trusted = true) / #(trusted is true or false) for that
signal. A trusted: null row neither counts for nor against the rate — it simply did not
resolve, and is dropped from that metric only.
Before you start
1
An API key with the three premium signals enabled
An admin of an active account mints the key from the dashboard; the See Authentication. If a signal comes back rejected for
want of a grant, your account does not yet have the premium tier — contact your account
manager.
tf_live_… secret is
shown once. Confirm the key is live and pointed at the right account:2
Credits
Budget roughly 1 credit per returned verdict.
rows × signals is the ceiling; rows
that do not resolve a given signal cost less.3
Your cohort as a CSV
One row per phone. The fields you supply decide which signals can run:
1. Submit the batch
POST /api/v1/signals with up to 5000 inputs per batch. Set skip_cache: true so you
measure a fresh resolution rather than a cached verdict.
202 straight away:
The run is asynchronous. A large batch that places automated verification calls can take
up to ~an hour to complete. Submit the whole cohort as one batch and poll gently.
2. Poll for results
status stays pending and completed_datetime is null until every item is terminal. The
batch is done when completed_datetime is non-null (status flips to complete). Each
data[] item carries your correlation_id, the echoed input, an item status, and a
signals map of {trusted, confidence} per signal:
{ "trusted": null, "confidence": null }
(an unresolved item also carries an unresolved_reason). Exclude those from that metric’s
denominator — see the verdict model for why null is never a false.
3. Compute the metrics
For each signal, over the rows with a definite (true/false) verdict:
- Connectivity =
#(trusted = true)/#(trusted = true or false) - Name match =
#(trusted = true)/#(trusted = true or false) - Profile match =
#(trusted = true)/#(trusted = true or false)
correlation_id and, per signal, build a
confusion matrix of the TruthFactor verdict against your label:
- Agreement — the share of rows where both sides have a definite verdict and they match. Report it on that definite overlap only.
- Variance — the difference between TruthFactor’s headline rate and your own on the same cohort.
- Decide up front how you treat blank or unknown ground-truth cells — counting them as a negative versus excluding them changes the rate materially. Be consistent across all three signals and state the choice alongside the result.
Coverage — how much input you need
A metric is only meaningful if enough rows actually resolve. Coverage is the share of inputs that came back with a definite (non-null) verdict for a signal — and it varies a lot by signal. The figures below are from a real 250-row North America benchmark run:
Profile match is the one to plan around. Providing an
email address on each row increases
profile-match coverage substantially; without emails, profile match returns null on roughly
44% of rows in this cohort.
Size the input for the resolved sample you need
Your usable sample for a metric isrows × coverage. Size the input so the resolved count —
not the submitted count — is large enough to be statistically meaningful. Because profile match
resolves at ~56% versus connectivity’s ~95%, you need roughly 2× the rows to reach the same
resolved-sample size:
These rates are from a North America cohort and vary by region — coverage and latency
differ from one region to the next. TruthFactor will publish per-region coverage rates as more
benchmarks run. Treat the figures above as a planning guide, and measure your own cohort’s
coverage from the first run.
Caveats
- Name match needs a real first and last name. A LinkedIn slug alone is not enough — enrich names before you submit, or name match will resolve on far fewer rows than connectivity.
- Profile match has a thin denominator. A verdict exists only where the profile exposes the
data to compare against, so report it directionally on small cohorts and supply
emailto lift coverage. - Region changes coverage. Coverage and latency vary from one region to the next, so measure your own cohort’s coverage rather than assuming the North America figures.
- Use
skip_cache: truefor a benchmark, so you measure a fresh resolution rather than a cached verdict from an earlier run.