Statistics API

Use the public-testnet API origin. These endpoints describe indexed records and cached observations, not a guarantee that every external dependency or relayer is healthy.

Overall statistics

GET /api/v1/stats returns success: true with a data object:

  • overall.totalTransactions, overall.completedTransactions: sums of the overlapping chain buckets, not unique record counts. Casper-originated records contribute to both their EVM bucket and the casper aggregate.
  • overall.last24Hours.eth2casper, overall.last24Hours.casper2eth: sums of per-chain direction counts, also including the overlapping Casper aggregate. There is no total field. Use transaction-list pagination.total (with the relevant filters) for unique record counts; do not compare it for equality with these overall sums.
  • byChain: chain-keyed records with transactionsByStatus, volumes.byToken (volume, count) and last24Hours direction counts.
  • syncStates: chain-keyed lastBlock and lastSyncedAt. There is no isSynced field.

Optional chain accepts an enabled chain slug. Unknown values return 400. This filter belongs to statistics, not the transaction-list endpoint. Volumes are token-specific decimal amounts; do not add different token units as if they were one currency.

curl -fsS 'https://api.testnet.astralbeam.io/api/v1/stats?chain=sepolia'
curl -fsS 'https://api.testnet.astralbeam.io/api/v1/stats' |
  jq '.data.overall | {totalTransactions, completedTransactions, last24Hours}'

Per-chain statistics

GET /api/v1/stats/chains returns a data array. Each entry has chainId, name, shortName and stats:

Stats field Type Meaning
total_count string or number Indexed record count
completed_count string or number Completed record count
last_tx_at string or null Last record creation time
evm_chain_name string, optional Chain slug when an aggregate row exists

Counts can be database integer strings; empty-chain defaults can be numeric zero. No completion-time, success-rate or 24-hour-volume fields are returned here.

curl -fsS 'https://api.testnet.astralbeam.io/api/v1/stats/chains' |
  jq '.data[] | {chain: .shortName, total: .stats.total_count, completed: .stats.completed_count}'

Token flow

GET /api/v1/stats/token-flow returns success: true with a data object holding authoritative, deployment-independent transfer totals. Each canonical source event is stored once by the indexer, so these figures do not depend on how many relayers observed a transfer or on restarts. Shares the /stats rate limit and a 30-second cache.

  • series[]: one entry per direction, txType (lock, burn_wrapped, burn, lock_native), sourceChain, contract (EVM locker address or the Casper TokenFactory package that emitted the event; legacy for rows recorded before deployment identity was stored), evmChainId, evmChainName, tokenId and symbol. Tokens that share a symbol on different deployments are separate entries. invalidRows counts rows excluded because their stored amount was not a canonical integer.
    • sourceEvents, completedEvents: verified source events, and the subset whose destination transaction was discovered.
    • sourceAmountRaw, completedAmountRaw: exact integer strings in the source denomination.
    • sourceAmount, completedAmount: the same values as exact decimal strings in token units (no floating point).
  • coverage[]: one entry per configured scope (chain, contract) with syncedBlock, earliestObservedBlock, startBlock and complete. complete is true only when the deployment's history is provably covered from its boundary; otherwise reason explains the gap (never_synced, start_block_not_configured, rows_precede_start_block, synced_before_start_block, backlog_draining). Treat incomplete scopes as partial history, not all-time totals.
  • generatedAt: snapshot time.

These are cumulative counts and volumes. Current escrow balances and wrapped supply are contract reads served by GET /api/v1/tokens?includeLiquidity=true.

curl -fsS 'https://api.testnet.astralbeam.io/api/v1/stats/token-flow' |
  jq '.data.series[] | {dir: .direction, type: .txType, chain: .evmChainName, token: .symbol, events: .sourceEvents, completed: .completedEvents, amount: .sourceAmount}'

Health and liveness

GET /api/v1/stats/health returns top-level fields, without a data envelope:

{"success": true, "status": "healthy", "checks": {"database": "ok", "indexers": {"sepolia": true}}, "timestamp": "2026-09-08T22:46:13.506Z"}

This is an illustrative reduced response. The indexer map reflects the expected configured chain/contract set, including incomplete configurations, not arbitrary historical sync rows. A true check requires successful required discovery within five minutes. The response also includes mode (full-ingestion or degraded recovery-only) and per-chain checks.ingestion configuration/discovery details. See the readiness contract; neither readiness nor a fresh recovery-loop timestamp certifies relayer availability or resolution of parked work.

HTTP status Meaning
200 healthy Database accessible and every expected chain has configured, recent successful discovery
503 degraded Empty/partial configuration, missing sync rows, missing credentials or stale/absent required discovery
503 unhealthy Health query failed; success: false, checks.database: error

GET /livez checks process liveness only. Use dependency health for readiness/monitoring, not to restart an otherwise live API because an external chain is behind.

async function bridgeHealth() {
  const response = await fetch('https://api.testnet.astralbeam.io/api/v1/stats/health');
  const body = await response.json();
  if (![200, 503].includes(response.status)) throw new Error(`HTTP ${response.status}`);
  return { httpStatus: response.status, status: body.status, checks: body.checks };
}
curl -sS 'https://api.testnet.astralbeam.io/api/v1/stats/health' | jq '{status, checks}'

Relayer statistics

GET /api/v1/stats/relayers returns success: true and a data array, populated from stored relayer statistics. Each row contains address, balances.eth (wei string or null), balances.cspr (motes string or null), attestationsSubmitted, lastSeen and isActive.

An empty array means no stored rows are available; it is not evidence that every relayer is down. This endpoint does not return a threshold, aggregate fleet totals or recentActivity. Use operator monitoring for fleet diagnosis.

Utility probes

  • GET /api/v1/stats/casper-node: data.isUp, nullable buildVersion, chainSpecName, lastBlockHeight. A reachability failure can return HTTP 200 with isUp: false. Cached for 60 seconds.
  • GET /api/v1/stats/bridge-fee: data.casper is null or {feeMotes: string, feeCspr: number}; data.evm maps chain slugs to null or {feeWei: string, nativeCurrency: string}. Missing/null means unavailable, not free. Cached for 60 seconds; recheck the contract fee before submitting.
  • GET /api/v1/rates/{fiatId}/latest (alias /rates/{fiatId}/latest): proxies the CSPR.cloud rate response unchanged. USD is fiat ID 1 by default; other IDs require operator configuration. Unsupported IDs return 400, rate limits 429, missing configuration 503, and upstream failure 502. Successful responses are cached for 60 seconds.

results matching ""

    No results matching ""