# How to Get Chain Statistics from the Amadeus Protocol RPC API

> Access Amadeus Protocol chain statistics via the RPC API. Retrieve block height, supply metrics, validator data, and network performance indicators with ease.

- Repository: [Amadeus Protocol/node](https://github.com/amadeusprotocol/node)
- Tags: how-to-guide
- Published: 2026-08-20

---

**The Amadeus Protocol exposes chain statistics through the `GET /api/chain/stats` HTTP RPC endpoint, which returns a comprehensive JSON payload containing block height, supply metrics, validator data, epoch information, and network performance indicators.**

The Amadeus Protocol node provides a RESTful RPC interface for querying blockchain state. Understanding how to retrieve chain statistics is essential for building monitoring dashboards, explorer applications, and automated tooling that tracks network health. The primary endpoint aggregates data from multiple internal subsystems and caches frequently-changing values for optimal performance.

## Chain Statistics Endpoint Overview

The canonical endpoint for chain statistics is `/api/chain/stats`. When invoked, the HTTP server defined in [`ex/lib/http/multiserver.ex`](https://github.com/amadeusprotocol/node/blob/main/ex/lib/http/multiserver.ex) routes this request to `API.Chain.stats/0` [lines 92-95](https://github.com/amadeusprotocol/node/blob/main/ex/lib/http/multiserver.ex#L92-L95).

This function orchestrates data collection from five distinct sources before assembling the final response.

## Data Sources and Implementation

### Chain Tip and Basic Metrics

The endpoint retrieves the canonical chain tip from `DB.Chain` and formats it using `format_entry_for_client/1` in [`ex/lib/api/api_chain.ex`](https://github.com/amadeusprotocol/node/blob/main/ex/lib/api/api_chain.ex) [lines 62-74](https://github.com/amadeusprotocol/node/blob/main/ex/lib/api/api_chain.ex#L62-L74).

This provides:
- **Current height** and **rooted height**
- **Tip hash** (Base58-encoded)
- **Current validator** and **next validator** public keys
- **Segment VR hash**

### Supply and Circulating Amounts

Supply metrics come from `NodeStatsGen.supply/0`, defined in [`ex/lib/node/node_stats_gen.ex`](https://github.com/amadeusprotocol/node/blob/main/ex/lib/node/node_stats_gen.ex) [lines 12-16](https://github.com/amadeusprotocol/node/blob/main/ex/lib/node/node_stats_gen.ex#L12-L16). This GenServer maintains a cached snapshot refreshed every **6 hours** to avoid expensive recalculation.

Available supply fields:
- `circulating` — coins in active circulation
- `total_supply` — maximum supply at current height
- `total_locked` — coins locked in contracts or staking
- `supply_computed_at_height` — block height of last calculation
- `total_supply_y3` and `total_supply_y30` — projected supplies at year 3 and year 30

### Validator Set and SOL Counters

Active validator data is served by `NodeStatsGen.validators/0` [lines 22-27](https://github.com/amadeusprotocol/node/blob/main/ex/lib/node/node_stats_gen.ex#L22-L27). This reads from an ETS table refreshed **every second**, providing near-real-time stake weights, SOL counts, and commission rates.

### Epoch-Specific Performance Data

Current epoch metrics are assembled in [`ex/lib/api/api_chain.ex`](https://github.com/amadeusprotocol/node/blob/main/ex/lib/api/api_chain.ex) [lines 78-90](https://github.com/amadeusprotocol/node/blob/main/ex/lib/api/api_chain.ex#L78-L90):

| Metric | Source Function |
|--------|-----------------|
| `emission_for_epoch` | `RDB.protocol_epoch_emission/1` |
| `diff_bits` | `API.Epoch.get_diff_bits/0` |
| `pflops` | Calculated protocol floating-point operations |
| `txs_per_sec` | Derived from recent block timing |

### Burned Fees

Total AMA burned (proxy for fees paid) comes from `API.Contract.total_burned/0` [lines 86-87](https://github.com/amadeusprotocol/node/blob/main/ex/lib/api/api_chain.ex#L86-L87), implemented in [`ex/lib/api/api_contract.ex`](https://github.com/amadeusprotocol/node/blob/main/ex/lib/api/api_contract.ex).

## Response Format

All values are encoded in human-readable formats: Base58 for hashes, floating-point decimals for coin amounts. The JSON structure follows this schema:

```json
{
  "error": "ok",
  "stats": {
    "height": 123456,
    "rooted_height": 123450,
    "tip_hash": "3vZK...",
    "tip": {},
    "tx_pool_size": 12,
    "cur_validator": "5KQ9...",
    "next_validator": "9fA...",
    "emission_for_epoch": 2500000,
    "circulating": 12345678,
    "total_supply": 200000000,
    "total_locked": 3000000,
    "validators": {},
    "supply_computed_at_height": 123400,
    "total_supply_y3": 804065972,
    "total_supply_y30": 1000000000,
    "burned": 12345.67,
    "diff_bits": 24,
    "pflops": 1.23e+03,
    "txs_per_sec": 5.6,
    "segment_vr_hash": "7bL..."
  }
}

```

## Code Examples for Querying Chain Statistics

### cURL (Command Line)

The fastest way to test the endpoint:

```bash
curl -s https://nodes.amadeus.bot/api/chain/stats | jq .

```

### JavaScript / Fetch

For browser or Node.js applications:

```javascript
const getChainStats = async () => {
  const response = await fetch('https://nodes.amadeus.bot/api/chain/stats');
  const data = await response.json();
  
  if (data.error === 'ok') {
    const { height, total_supply, txs_per_sec } = data.stats;
    console.log(`Block ${height}: ${total_supply} total supply, ${txs_per_sec} TX/s`);
    return data.stats;
  }
  throw new Error(`RPC error: ${data.error}`);
};

```

### Python / requests

```python
import requests

def fetch_chain_stats():
    url = "https://nodes.amadeus.bot/api/chain/stats"
    response = requests.get(url, timeout=10)
    response.raise_for_status()
    
    data = response.json()
    if data.get("error") != "ok":
        raise RuntimeError(f"Node returned error: {data['error']}")
    
    return data["stats"]

# Usage

stats = fetch_chain_stats()
print(f"Height: {stats['height']}, Validators: {len(stats['validators'])}")

```

### Elixir (Internal Module Call)

For node operators building internal tooling, call the implementation directly:

```elixir

# Direct module invocation bypasses HTTP overhead

stats = API.Chain.stats()
IO.inspect(stats, pretty: true)

# Access specific fields

%{height: height, circulating: circ} = stats

```

## Key Implementation Files

Understanding the source structure helps when debugging or extending functionality:

- **[`ex/lib/http/multiserver.ex`](https://github.com/amadeusprotocol/node/blob/main/ex/lib/http/multiserver.ex)** — HTTP routing and request dispatch
- **[`ex/lib/api/api_chain.ex`](https://github.com/amadeusprotocol/node/blob/main/ex/lib/api/api_chain.ex)** — Core `stats/0` implementation and response formatting
- **[`ex/lib/node/node_stats_gen.ex`](https://github.com/amadeusprotocol/node/blob/main/ex/lib/node/node_stats_gen.ex)** — Cached supply snapshots and validator ETS tables
- **[`ex/lib/api/api_contract.ex`](https://github.com/amadeusprotocol/node/blob/main/ex/lib/api/api_contract.ex)** — Burned token totals via `total_burned/0`
- **[`ex/lib/consensus/models/entry.ex`](https://github.com/amadeusprotocol/node/blob/main/ex/lib/consensus/models/entry.ex)** — Chain entry struct definitions

## Performance and Caching Characteristics

The endpoint balances freshness with efficiency through tiered caching:

1. **Supply data** — 6-hour refresh cycle (expensive recalculation)
2. **Validator sets** — 1-second ETS cache (frequent but lightweight)
3. **Tip data** — Real-time database read (authoritative source)
4. **Epoch metrics** — Computed on request using cached epoch state

This design ensures sub-100ms response times under normal load while maintaining data consistency for critical consensus values.

## Summary

- The **Amadeus Protocol RPC** exposes chain statistics via `GET /api/chain/stats`
- Data aggregates from **`API.Chain.stats/0`** with contributions from **`NodeStatsGen`** for cached values
- Response includes **height**, **supply metrics**, **validator sets**, **epoch performance**, and **burned fees**
- Supply snapshots refresh every **6 hours**; validator data updates every **second**
- Implementation spans **[`ex/lib/api/api_chain.ex`](https://github.com/amadeusprotocol/node/blob/main/ex/lib/api/api_chain.ex)**, **[`ex/lib/node/node_stats_gen.ex`](https://github.com/amadeusprotocol/node/blob/main/ex/lib/node/node_stats_gen.ex)**, and **[`ex/lib/http/multiserver.ex`](https://github.com/amadeusprotocol/node/blob/main/ex/lib/http/multiserver.ex)**

## Frequently Asked Questions

### What is the rate limit for the chain statistics endpoint?

The Amadeus Protocol node does not implement explicit rate limiting on `/api/chain/stats`, but validator data refreshes every second and supply data every six hours. Caching responses client-side for 5-10 seconds is recommended to avoid unnecessary load.

### Why does circulating supply differ from total supply minus locked?

Circulating supply excludes protocol-reserved emissions, timelocked allocations, and coins in unclaimed staking rewards that have not yet entered active circulation. The `total_locked` field represents only contract-locked amounts, not the full non-circulating balance.

### Can I run this query against a local node?

Yes. Replace `https://nodes.amadeus.bot` with your local node's HTTP endpoint (typically `http://localhost:8080` or as configured in [`multiserver.ex`](https://github.com/amadeusprotocol/node/blob/main/multiserver.ex)). Local queries bypass network latency and return identical data structures.

### How accurate is the `txs_per_sec` metric?

The value represents a rolling average over recent blocks, typically 60 seconds of chain history. It reflects successfully processed transactions, not submitted or pending mempool entries. For mempool size, reference `tx_pool_size` in the same response.