Documentation: all sections

Asset attestation

Saxeo Attestation never says "trust us". It says: here is what we checked, how we checked it, when we checked it, and what the evidence shows.

You give it an asset identifier. It reads the sources it can reach, decides a status for each claim, and stores a signed, versioned record carrying the sha256 of every byte it read. Anyone can re-run the calls and check the signature without a Saxeo account.

What "verified" means here, and what it does not

This is the most important section on the page, so it is first.

VERIFIED means: Saxeo performed the listed checks, by the listed methods, at the listed time, and they agreed. Nothing more.

It does not mean the asset is sound, solvent, legally issued, correctly described, or a good idea. Saxeo is not an auditor. This is not an audit, not a rating, and never investment advice. Every record carries that sentence in its own signed payload, so it cannot be separated from the claim it qualifies.

Three rules follow from that, and they are enforced in code, not by convention:

  1. Nothing is invented. A source that is not configured or cannot be reached yields UNAVAILABLE for the claims that depend on it. There is no fallback value, no last-known figure presented as current, and no default market-price vendor assumed into existence.
  2. An issuer's word is never a check. Anything an issuer declared — backing value, yield, maturity — is recorded as UNVERIFIED, with the issuer named as the source. A declared backing figure is never proof of reserves.
  3. Payment cannot move a status. A check costs the same whatever it finds; a DISCREPANCY costs exactly what a VERIFIED costs. Reading a record, its history and its evidence is free, so nobody ever has a financial reason to leave a discrepancy unread.

The six statuses

VERIFIEDWhat it meansThe listed checks ran by the listed methods and agreed, inside the freshness window.
PARTIALLY_VERIFIEDWhat it meansSome claims verified, at least one did not. Read the per-claim statuses; this headline is not a summary of the weakest one.
UNVERIFIEDWhat it meansNothing independent supports this. Usually an issuer's own statement, recorded as a statement.
STALEWhat it meansChecked, but outside its freshness window. Shown labelled as old — never re-presented as current.
DISCREPANCYWhat it meansTwo sources that should agree do not, beyond the stated tolerance.
UNAVAILABLEWhat it meansA required source was unreachable or is not configured. No figure is published in this state.

A DISCREPANCY in any claim becomes the headline status of the whole record, whatever else passed. That is deliberate: a disagreement is the one thing that must never be averaged away.

Identifiers

EVM tokenExampleevm:1:0xdac17f958d2ee523a2206206994597c13d831ec7
Solana mintExamplesolana:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
Saxeo Vault assetExamplevault:va_0123456789abcdef
Bare addressExample0xdac17f… together with chain_id

ISIN, CUSIP and FIGI identifiers are refused, with an explanation. Saxeo has no data source for them on this deployment, and answering with a page of UNAVAILABLE claims after charging for the check would be worse than an honest error.

On-chain checks run against the RPCs the operator configured for payments. An asset on a chain this deployment has no RPC for is not refused — every on-chain claim comes back UNAVAILABLE, naming the missing chain, because "we cannot check this here" is itself something you need to know.

Running a check

curl -s https://www.saxeonetwork.tech/__api/v1/attestations/check \
  -H "authorization: Bearer $SAXEO_KEY" \
  -H 'content-type: application/json' \
  -d '{
        "asset": "evm:1:0xdac17f958d2ee523a2206206994597c13d831ec7",
        "expected_supply": "88306226684053103",
        "tolerance_bps": 0
      }'
assetMeaningThe identifier, in one of the forms above. Required.
chain_idMeaningRequired only when asset is a bare 0x address.
expected_supplyMeaningAn issuer-declared supply in raw base units, reconciled against the chain.
tolerance_bpsMeaningReconciliation tolerance, 010000. Defaults to 0 — exact.
freshness_secsMeaningHow long this record stays current, 60 s to 30 days.
vault_asset_idMeaningLink a Saxeo Vault asset so the issuer's declared facts join the record. Issuer-only.

What gets checked

identityHoweth_getCode (is there a contract at all?) plus symbol(), name(), decimals(). An address with no code is a DISCREPANCY, not a pass.
supplyHowtotalSupply(), decoded as an exact uint256 — a supply too large for any Rust primitive is still exact, because it is carried as a decimal string.
admin_controlHowowner() and the EIP-1967 admin storage slot.
upgradeabilityHowThe EIP-1967 implementation slot: is this a proxy, and to what?
pause_stateHowpaused(), where the contract exposes it.
token_authoritiesHowSolana: mintAuthority and freezeAuthority — live, or revoked.
supply_reconciliationHowExact integer comparison of a declared supply against the chain.
issuer, declared_backing, yield, maturityHowRead from a linked Vault entry. Always UNVERIFIED: they are the issuer's own word.
custodyHowAnswered on every record, and the honest answer today is UNAVAILABLE — no custodian feed is configured.

Every claim carries its own limitations list saying what it does not establish. Some of those are the point:

Reconciliation, and why rounding cannot hide anything

Where a declared figure can be compared against an independent one, the comparison is exact integer cross-multiplication:

|reported − expected| × 10000  ≤  |expected| × tolerance_bps

No division, so no rounding can widen the tolerance. A tolerance of 0 means exactly equal — a difference of one unit against a quintillion is a DISCREPANCY, which is the whole point. The deviation shown on the record is a display value — the one figure here that division produces — and it is rounded up, so a displayed deviation is never smaller than the real one.

An expected of zero against a non-zero reported is a DISCREPANCY at every tolerance: a percentage of zero is undefined, and "we expected none and found some" is a disagreement, not a pass.

Freshness

Every claim carries verified_at, a window, and the stale_after timestamp derived from them. Past that timestamp a read reports STALEthe record is not rewritten, it is labelled. status is what is true now; status_at_check is what was true when the check ran. Both are returned.

A DISCREPANCY does not decay into STALE as it ages. Ageing never downgrades a disagreement into something milder.

Evidence

curl -s "https://www.saxeonetwork.tech/__api/v1/attestations/$ASSET_ID/evidence" \
  -H "authorization: Bearer $SAXEO_KEY"

Each entry names the source, when it was read, and the sha256 of the exact bytes that came back. Pass ?include_body=true to get the bytes themselves.

The bytes are stored encrypted at rest (AES-GCM, the same envelope discipline as the rest of Saxeo) and are never logged. They are opened only to answer the owner's own read. The store is content-addressed, so two records that read the same chain state share one entry — which is what makes "is this the same reading you showed me before?" answerable by hash equality.

Versioning

Records are versioned, never overwritten. A re-check writes a new row and marks the old one superseded; there is no update path that changes a status, a claim, or an evidence reference after the fact.

curl -s "https://www.saxeonetwork.tech/__api/v1/attestations/$ASSET_ID/history" \
  -H "authorization: Bearer $SAXEO_KEY"

An old record is returned exactly as it was signed, so "what did Saxeo say last Tuesday, and does that record still verify?" always has an answer.

The public view

GET /v1/assets/{assetId}/verification

No account, no key, no attribution. It serves the newest record whose every source is publicly re-readable on-chain, and shows neither who ran the check nor how many times.

A record that draws on an issuer declaration or sealed Vault data has no public view at all and returns 404. That is decided when the record is written, not by stripping fields on the way out.

The rendered version lives at /attest/{assetId} — it verifies the signature live on load and prints the exact RPC call behind every claim.

Webhooks

attestation.verifiedWhenThe headline became VERIFIED — first time, or a recovery. An unchanged verified record is silent.
attestation.discrepancyWhenA claim disagrees with what it was reconciled against.
attestation.staleWhenThe record this check replaced had already passed its freshness window.
attestation.contract_changedWhenContract state moved: an implementation upgrade, an ownership change, a pause flipping, an authority appearing.
attestation.source_changedWhenThe set of sources behind a claim moved — a feed appeared, or stopped answering.

Payloads are content-free: ids, the status and the version. The claims and their evidence stay behind your own authenticated read.

Verifying a record

The record is signed with the same key that signs every Saxeo receipt, so it verifies through the endpoint you already use:

curl -s https://www.saxeonetwork.tech/__api/v1/receipts/verify \
  -H 'content-type: application/json' \
  -d '{"receipt":"<record>","signature":"<signature>"}'

Then check the recovered address against the gateway's published signing key at GET /v1/receipts/pubkey. And re-read the sources: every claim names the exact call behind it, so you can run them against any node and compare.

Not built

Stated plainly, so nobody assumes otherwise: