> ## Documentation Index
> Fetch the complete documentation index at: https://docs.walletlink.social/llms.txt
> Use this file to discover all available pages before exploring further.

# Data quality

> How matches are attested, what the quality score means, and when a record goes stale.

Every record carries metadata about how much to trust it. Using it is optional, and for most outreach work the defaults are fine, but if you are making automated decisions you should read this page.

## Evidence classes

Responses include a `sources` array describing what kind of evidence backs the record, not which system produced it.

| Class             | Meaning                                                                                               |
| ----------------- | ----------------------------------------------------------------------------------------------------- |
| `onchain`         | Published by the address owner in an onchain record.                                                  |
| `farcaster`       | A protocol-level Farcaster account verification.                                                      |
| `attested-social` | The owner proved the wallet with a signature and the account with a sign-in, on an identity platform. |
| `manual`          | Reviewed by us directly.                                                                              |
| `aggregated`      | Correlated from a third-party identity index. Weaker than the others.                                 |

A record can carry more than one. More classes generally means more confidence, and `aggregated` on its own is the weakest position a record can be in.

## The quality score

`quality.score` is an integer from 0 to 100 combining how many identities are attached to a wallet and how strong the evidence is for each.

| Score        | Reading                                                               |
| ------------ | --------------------------------------------------------------------- |
| 70 and above | Strong. Multiple identities, or a single one with strong attestation. |
| 40 to 69     | Usable. Typically one identity with reasonable backing.               |
| Below 40     | Thin. Treat as a lead rather than a fact.                             |

The bands are guidance, not thresholds enforced anywhere in the API. Pick your own cutoff based on how expensive a wrong contact is for you.

## The `verified` flags

`twitter.verified` and `farcaster.verified` are narrower than the English word suggests, and this is the piece most likely to trip you up.

<Warning>
  `twitter.verified: false` does **not** mean the handle is unverified in the
  everyday sense. The flag is true for handles attested by an onchain record, a
  manual review, or an attested-social sign-in; the majority Farcaster-attested
  handles carry false. A handle that came from an X account verified on
  Farcaster is genuinely owner-attested, and it still reports `false`.
</Warning>

To judge attestation, read the `sources` array. To judge overall confidence, read `quality.score`. The `verified` booleans are best treated as a narrow signal meaning “attested by the strongest available route”, not as a general trust flag.

## Staleness

Records carry a freshness window, and a record is treated as stale once it passes that window or has gone more than 30 days without an update.

On [`GET /api/v1/wallet/{address}`](/api-reference/wallet) this surfaces in two places:

* `meta.stale`, a boolean in the response body.
* `X-Data-Staleness: stale` and `X-Last-Updated`, response headers, sent only when the record is stale.

Stale does not mean wrong. It means we have not re-confirmed it recently. Farcaster records refresh daily, so they rarely go stale. Onchain records are only re-read on a slower cycle, because they change rarely and reading them is expensive.

## When a handle stops being true

An attestation records what was true when the owner made it. An X handle is a
name its owner can change at any time, and changing it breaks nothing on their
side, so nothing announces it.

This has a consequence worth stating plainly, because it is the one way an
attested match can be wrong. If someone verified `@alice` and later renamed to
`@alice_eth`, an attestation that stored only the string still says `@alice`.
That name is now free, somebody else may hold it, and the record has quietly
stopped pointing at the person who made it.

## We check, and we tell you

Every X handle we hold is now resolved against X itself, and the answer travels
with the record.

```json theme={null}
"twitter": {
  "handle": "someone",
  "url": "https://x.com/someone",
  "verified": true,
  "reachable": true,
  "reachability": "live",
  "reachability_checked_at": "2026-08-17T09:41:02.000Z"
}
```

| `reachability` | Meaning                                                                                                                                                  |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `live`         | The owner attested this account, and it still reaches them.                                                                                              |
| `suspended`    | The owner attested it and X has since suspended it. Messages will not arrive.                                                                            |
| `unclaimed`    | The owner attested it and no account holds the name now, usually a rename. Somebody else may have taken it, so treat it as a lead rather than a contact. |
| `reassigned`   | The owner attested it and the name now belongs to a **different live account**. Messages would reach a stranger, not the wallet owner.                   |

The three fields are **absent, not false, when we have not checked**. That is the
same rule the verified flags follow, for the same reason.

`suspended` and `unclaimed` are kept apart because they mean different things. A
suspended account still belongs to the same person and may come back. A freed
name may already belong to somebody else, which is the only case where an old
record can point at a stranger rather than at nobody.

`reassigned` is that case, confirmed rather than suspected. Where a source
recorded the numeric account id alongside the wallet, we can compare it against
the id the name resolves to today, and a mismatch is proof the name has moved on.
It is the only state where the record looks perfectly healthy: the name resolves,
to a real and active account, and that account is not the one that attested it.
`reachable` is false for it, and the handle export leaves it out.

### What we found when we checked

We have resolved 473,215 handles against X itself, and 99.9% of the distinct handles the index holds carry a state today; new arrivals and retries join the same daily check. The shares below are of the handles that returned a state.

|                       | Share |
| --------------------- | ----- |
| Live                  | 70.1% |
| Suspended             | 20.1% |
| Name no longer in use | 9.8%  |

**Roughly a third of every attested X handle reaches nobody.** That is not a
statement about our index in particular. It is a property of the underlying
attestation: Farcaster records a verified X account as a name captured once, with
no account id and no recheck, so nothing in the protocol notices a rename or a
suspension. Any product built on those verifications carries the same third, and
without checking there is no way to know which third.

Checking does not weaken the attestation. It completes it. “The owner attested
this, and it still works” is a stronger statement than either half, and it is
one only a source that actually looked can make.

### Two more things follow from it

**We store the account id where a route provides one.** An id is permanent in a
way a name is not. Routes that carry one let us follow a rename instead of
losing it, and `attested-social` is the route that carries one today.

**We record every disagreement, and settle only the one kind that is not a
judgment call.** When two owner-attested routes name different accounts for one
wallet, that is evidence something moved. The conflicting account id is never
written beside a handle it does not belong to, and the disagreement is kept.

We settle a disagreement only where the evidence decides it, and the evidence
can decide it two ways. Where the handle we hold reaches nobody and the other
one is live on a recent check, we follow the rename. Where the handle we hold
still resolves but to a different account than the one the owner attested, the
name was freed and re-registered: “live” is true of the string and false of the
person, and we follow the owner.

In both settled cases the replaced handle is kept, so the change can be
explained rather than appearing as a correction out of nowhere. Everywhere
else, including where both accounts are live, we keep the handle the record
already had and settle nothing: a handle that still reaches its owner is never
replaced on the strength of a newer claim alone, however well that claim is
attested, because the newer claim is exactly what a stolen key would produce.

If you are running outreach on a list you enriched a while ago, re-check it
rather than assuming a handle that was attested is still live. `meta.stale` and
`X-Data-Staleness` tell you when we last re-confirmed a record.

## Found, missing, and checked

There is a distinction worth respecting between “we have never looked at this wallet” and “we looked and there was nothing”. Both return `found: false`, and `meta.checked_at` separates them:

```json theme={null}
{
  "data": null,
  "meta": { "wallet": "0x...", "found": false, "checked_at": null }
}
```

A `null` means we have no record of ever checking this address. A timestamp means we did check, on that date, and found no identities attached.

The second case is a real answer. If you are enriching a list incrementally, a wallet with a recent `checked_at` is not worth re-submitting, while a `null` is. Ignoring the distinction costs you nothing in credits, since a miss is never billed, but it does spend rate limit and wall clock rediscovering answers you already hold.

<Note>
  Wallets we have checked and found nothing for are reported as not found rather
  than as an empty record. A miss is never charged, and you also never receive a
  hollow object that looks like a match. Those are the two halves of the same
  promise: we only bill for wallets we actually resolved.
</Note>
