Verification levels

Every answer states how far the checking got. Three levels, and a refusal underneath them for when nothing qualifies. No level claims the number is correct.

A level is not a confidence score, a rating of the provider, or a probability that the number is right. It is a statement about one call: which checks ran, which of them could be run at all, and what the outcome was. Two calls for the same value seconds apart can come back at different levels, because the level describes the evidence available at that moment rather than a property of the data.

The checks that produce a level

Verification runs in layers, cheapest first, and stops as soon as a layer answers decisively. L1 is deterministic and runs on every call: the response parses, the schema holds, the required fields exist, the value is inside sane bounds, and the timestamp is present and recent. A response that fails L1 never reaches a level at all; the source is swapped inside the same request and the caller sees slightly higher latency.

L2 is statistical and also runs on every call, at close to zero marginal cost. It compares against an on-chain reference where one exists, against a peer answer already in the cache where one is available, and against the source's own latency distribution. A response more than four times the arm's own p90 is treated as an outlier even when the payload looks perfect, because a source that has just become slow is usually a source that is about to become wrong.

L3 is semantic and sampled rather than run per call, because it costs a model invocation. Its verdicts are cached with an expiry, so an approval is never permanent and a ban is never final.

Anchored

The answer agreed with an independent authoritative reference within tolerance. Default tolerance is 2%, computed symmetrically so neither side of the comparison is treated as the denominator of record.

On Solana the reference is a Chainlink Data Feed read from chain state. The round carries a timestamp, and that timestamp is checked against a limit derived from the heartbeat each feed publishes for itself. Mainnet feeds run heartbeats from 180s to 600sdepending on the pair, so a single global freshness limit would either reject healthy feeds or accept stale ones. The limit is per feed.

An unreachable reference fails the check rather than passing by omission. The trace distinguishes the oracle disagreeing from the oracle not answering, records which oracle answered, and states whether the read came from chain state or from an oracle's HTTPS service. Those are different claims and the trace does not blur them.

Consensus

Independent sources agreed, where independence is measured rather than assumed. Sources reading a single upstream count as one source however many names they trade under. Two exchange feeds tested at residual correlation r=0.154 are genuinely two readings. Two social providers that agreed on eleven handles byte for byte were one reading counted twice, and the engine refuses to call that consensus.

Consensus is not free. Reaching it means paying more than one source for the same value, so it is gated by the per-call spend ceiling on your plan. A call that could reach consensus with fan-out but has no budget for it is delivered at the level the single source reached, with a note saying why rather than a silent downgrade.

Single source

One source passed the structural and plausibility checks and nothing independent confirmed it. It may well be right. We could not confirm it, and the answer carries a caveat in words as well as in the level, so the warning survives into any log or interface that prints the block as it arrived.

Some types are capped here structurally. A type served by fewer than three independent providers, with no measured semantic judge, cannot prove consensus, so the catalogue reports its ceiling as single source rather than letting a caller discover it after paying.

Refused

Beneath the three is the case where nothing met the level you asked for. Set minLevelon a call and you get a refusal instead of an answer dressed above its evidence. It carries the reason, the type, the level you asked for, and a trace id. Nothing is charged.

get_verified_data({ type: "token.price", params: { token: "SOL" }, minLevel: "anchored" })

Some refusals happen before anything runs. Ask for anchored on a type or a pair no reference covers and the call is refused at the door, before a source has been paid.

Level is not the only axis

Every answer also carries origin, which says whether the source measured the number or whether we derived it by counting something the source returned. The two are orthogonal. A derived number can be anchored and a measured number can be single source. Collapsing them into one word would hide which of the two claims is being made, and only one of them has a provider standing behind it.

No level is a guarantee of correctness. Anchored means the answer agreed with a reference at a point in time, and a reference can be wrong too. What the block reports is how far the verification got, which is the only thing anyone can report honestly.