KyroKyro Docs

Safe integration flow

The decision-first flow, cache semantics and refresh discipline for production integrations.

Kyro has one recommended integration shape: check the decision, act on the verdict, mint a receipt when you need proof. Every other endpoint is evidence you can consult when a verdict needs context. This page walks the flow and the data semantics that keep it safe.

Decision first

GET /api/v1/decision/{wallet}?useCase= is the entry point. It answers 200 for every valid wallet address, known or not. When Kyro has never seen the wallet the response is a conservative baseline verdict, never a 404 and never a guess.

  • reasons drive the verdict. warnings are advisory coverage notes and never change it. See Reason and warning codes.
  • A baseline verdict tells you evidence is missing, not that the wallet is bad. Missing evidence alone never produces a block.

When you hit a baseline for a wallet you care about:

  1. Start indexing with intake: POST /api/v1/intake/{wallet}.
  2. Poll GET /api/v1/score/{wallet} until cacheStatus is cached.
  3. Re-run the decision. The verdict now rests on committed evidence.

Which read when

SurfaceUse it for
DecisionA verdict with a recommended limit. The default for payments, marketplaces, escrow and lending.
ScoreThe raw 0 to 100 score with component breakdown, for building your own policy on top.
Interaction graphObserved counterparties from saved chain snapshots. Display and investigation evidence, score-neutral.
Trust graphVerified relationship evidence: attestation-backed edges between registered identities.

What cacheStatus means

ValueMeaningWhat to do
cachedA committed snapshot backs the answer.Trust the verdict at its stated freshness.
indexing_requiredNo committed evidence yet. The answer is a conservative baseline.Run intake, poll the score until cached, then re-check.

Committed evidence older than 24 hours adds the DATA_STALE reason to decisions. The freshness object also carries lastIndexedAt and refreshInProgress so you can see exactly what backs a verdict.

Reading the interaction graph honestly

GET /api/v1/interaction-graph/{wallet} is anonymous, database-only and side-effect-free: it reads persisted snapshots and never starts a scan.

  • metrics: null is not zero. A node with metrics: null means no countable evidence is captured for that counterparty yet: the snapshot predates stats capture or the evidence is Arc aggregate-only. A node with a metrics object carries real saved counts.
  • An empty graph is not proof of isolation. Check coverage.status first: not_indexed means Kyro has no snapshot at all and partial means some chains are missing. Only a complete scan with zero nodes supports "no observed counterparties".
  • lowerBound: true means "at least". A counted chain hit a provider history cap or some contributing chains have no captured stats. basis reports how many chains were counted, are pending capture or are unavailable.

Refresh discipline

POST /api/v1/interaction-graph/{wallet}/refresh re-indexes a wallet through the same pipeline as intake. Four rules keep it cheap and safe:

  1. It needs an API key. Anonymous calls answer 401 NOT_ALLOWED. A wallet Kyro has never seen can be indexed once anonymously through intake instead.
  2. Fresh means free and done. A snapshot committed within the last 60 minutes answers 200 with status: fresh and a retryAfterSeconds. Nothing starts and nothing is charged.
  3. Refreshes are single-flight. Concurrent requests for the same wallet join the run already in flight: 202 with status: indexing, free. Firing more POSTs never speeds anything up.
  4. Poll the GET, do not re-POST. After a 202 with status: started (5 units, against the daily refresh cap for a re-index or the daily intake cap for a wallet's first index), poll GET /api/v1/interaction-graph/{wallet} with backoff until coverage reports the new snapshot. Per-plan caps are on the refreshInteractionGraph reference page.

You rarely need manual refresh

Kyro re-indexes registered wallets on a rolling daily cadence, so scores and graphs for registered identities stay current without integrator action. This is current product behavior, not a contract term: build against the freshness fields in each response rather than assuming a schedule. Manual refresh is for on-demand freshness, for example right before releasing a large escrow.

Observation is not trust

The interaction graph records what happened on chain: deduplicated counterparties with saved counts. It is score-neutral and it is not an endorsement. A high transaction count with a wallet proves contact, not confidence. verifiedKyroPeer: true on a node means the separate Trust Graph also contains that wallet; observation alone never creates a trust edge, a metric or a score contribution.

Verified attestations are instant trust evidence

Trust edges come only from verified attestations: a real Arc transaction, both wallets participating, verified on chain, accepted by the counterparty. Once verification and acceptance complete, the edge is trust evidence immediately. No re-index or refresh run is needed for it to appear in GET /api/v1/trust/{wallet}. Verified attestations also feed the verifiedAttestations and capped propagatedTrust score components. See Trust graph for the full verification rules.

Where to go next

On this page