Starkscan

Prepared staking API

Finalized staking summaries, history, validators, delegators, activity, coverage, and SDK usage.

Prepared staking API

Starkscan serves staking from a prepared, finalized read model. Requests do not call an RPC provider, scan raw events, fetch historical prices, or enumerate the complete chain at request time. Directory, detail, activity, and summary responses declare source: finalized_prepared_staking_snapshot; the metric-series route declares source: finalized_prepared_staking_snapshot_series. Every response includes typed coverage.

Routes

RoutePurpose
GET /v1/{chain}/stakingChain-wide totals, liveness/effectiveness, token totals, and coverage.
GET /v1/{chain}/staking/metrics/seriesFinalized per-token stake history for 30d, 90d, ytd, or all.
GET /v1/{chain}/staking/validatorsBounded validator page.
GET /v1/{chain}/staking/validators/{address}Validator detail, token pools, rewards, and address history.
GET /v1/{chain}/staking/validators/{address}/delegatorsBounded delegator page.
GET /v1/{chain}/staking/activityTransaction-linked activity, optionally filtered by validator.
GET /v1/{chain}/staking/address/{address}One address's prepared positions and bounded activity history.

Use these plural canonical routes. Singular /staking/validator... paths are compatibility surfaces and are not the preferred client contract.

Paged routes default to limit=25 and cap it at 100. nextCursor is opaque: pass it back unchanged and restart pagination when filters change.

The validator directory is ordered across the complete prepared snapshot by exact STRK stake descending, with unavailable STRK amounts last and stable address/generation ties. This is not cross-asset staking power: BTC and other assets are never added to STRK. Cursors bind the ordering and snapshot; restart when a cursor expires.

The directory refuses snapshots exceeding its 4,096-validator ranking bound with HTTP 503, code staking_directory_capacity_exceeded, and Retry-After: 60 rather than returning a partially ranked population. This requires operator review; retrying does not expand capacity. Invalid cursor anchors return HTTP 400, not an empty end-of-directory page.

Validator names may come from reviewed public identity metadata, separately from finalized protocol facts. The mainnet registry records full validator (not pool or reward) addresses, source links, and review dates. Names and logos are not ownership verification or endorsements. Unknown identities remain unlabeled in the API; the frontend shows “Unknown validator” and the address. Commission, balances, APR and liveness are never imported from a public name directory.

Coverage is part of the result

coverage.status is prepared, catching_up, or unavailable. Inspect reasonCode, materializedThroughBlock, sourceLatestFinalizedBlock, lagBlocks, gapIntervals, outstandingMaterializationIntervals, metricDefinitionVersion, and lastSuccessfulRunAtIso before making a completeness claim.

sourceLatestFinalizedBlock and lagBlocks are frozen with the prepared snapshot. They describe the gap when that snapshot was published, not the current chain head. If publication stops, that gap can remain small while the snapshot grows hours old. Compare lastSuccessfulRunAtIso with the current time; the dashboard marks publication more than five minutes old as delayed.

All staking facts are finalized-only. A successful HTTP response does not turn catching_up, a declared gap, or an unavailable metric into complete data.

The metric series has its own historyCoverage. SN_MAIN history before the first sealed snapshot is reconstructed offline from exact finalized validator self/delegated position activity; each point's sourceKind says replayed_position_activity or sealed_prepared_snapshot. Pool-member positions are not added a second time. The migration refuses reconciliation gaps and verifies the replayed totals against every token in the first sealed snapshot. Missing buckets are gaps, never zeroes. stakedRaw is the end-of-bucket stock. stakedInRaw and stakedOutRaw are the positive and negative parts of the net stock change, not gross deposits or withdrawals. Exit intent does not remove stake.

valuationUsd is an additive, nullable decimal from a direct historical USD quote no later than the bucket end for a completed bucket, or request time for an in-progress bucket. Its valuationSourceId, valuationProviderAssetId, and valuationAtIso identify the exact source, provider asset, and quote time. The quote must match an enabled exact token mapping and the token's decimals. A missing direct quote returns null, including for BTC wrappers without exact provider coverage; no current price or underlying-token estimate is substituted. valuationCoverage reports each returned token's priced and unpriced point counts and unpriced intervals. Native stakedRaw and decimals remain authoritative; never interpret an unpriced asset as worth zero or call a mixed-asset USD sum complete when a token has a missing quote.

Serving stays explicitly bounded. hour granularity requires one token; all requires week granularity; and an unfiltered ytd request requires week granularity. All responses fail closed if they would exceed 20,000 items rather than returning a partial series. There is no request-time chain or provider call.

Amounts, ratios, and unavailable metrics

  • Token amounts are decimal raw-unit strings. Apply the accompanying decimals only for display.
  • Ratios are exact { numeratorRaw, denominatorRaw } values. Do not convert to floating point before business logic.
  • A null liveness, effectiveness, concentration, reward, or stake value is not zero. Read its adjacent metricValueReason, liveness reason, accounting reason, or yield reason.
  • tokensTruncated, addressHistoryTruncated, and positionsTruncated are explicit bounds, not display hints.
  • Reward accounting can be unavailable when stake-time coverage, reward-token scope, or position history is incomplete.

TypeScript SDK

import { createExplorerApi } from '@starkscan/sdk';

const api = createExplorerApi({
  baseUrl: 'https://api.starkscan.co',
  apiKey: process.env.STARKSCAN_API_KEY,
});

const summary = await api.getStakingSummary('SN_MAIN');
if (summary.coverage.status !== 'prepared') {
  throw new Error(`staking coverage: ${summary.coverage.reasonCode}`);
}

const page = await api.getStakingValidators('SN_MAIN', undefined, 25);
const history = await api.getStakingMetricSeries('SN_MAIN', {
  range: '90d',
  granularity: 'day',
  token: '0x4718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d',
});

The SDK also provides getStakingMetricSeries, getStakingValidator, getStakingDelegators, getStakingActivity, and getStakingAddress. It validates the prepared source, coverage shape, raw integer strings, and mutually exclusive call-path availability states.

Use the API reference for exact schemas and API discovery for the current caller-specific route and rate-limit contract.

On this page