peaq Explorer

Developers — peaq Explorer API

Public read-only JSON API for the peaq Mainnet (a Polkadot-SDK / Substrate Layer-1). Used by this explorer and freely consumable by external apps, native mobile clients, servers, and AI assistants.

Start here — use the JSON API, not the HTML

This explorer is a client-rendered single-page app: HTML pages are a shell that JavaScript fills in inside the browser. A non-browser client that fetches an HTML page will not see the data. Don't scrape the HTML — call the JSON API below, which returns plain JSON. Every figure on the site comes from an /api/* endpoint. (This developer page is the exception: it is server-rendered on purpose.)

BehaviorWhat to do
HTML pages sit behind Cloudflare, which may challenge or block clients that look like abusive bots. A naive server-side fetch of an HTML page can come back empty or challenged.Request the /api/* JSON endpoints instead — the supported path for automated clients. Send a descriptive User-Agent and respect the Cache-Control headers.
The API is open to non-browser clients at the origin. CORS is a browser-only mechanism, so a caller that sends no Origin header (native app, server, script, AI agent) is always allowed by the app.Call the API directly from servers and native apps. Only browser callers from other web origins need to be added to ALLOWED_ORIGINS.

Chain data (read-only, public)

Chain inspection (read-only, polkadot.js-style)

Generic access to runtime metadata, storage and constants at any block, so on-chain claims can be verified independently. Backed by an archive node, so historical queries work.

Read-only by construction — only api.query, api.consts and allowlisted read RPCs are reachable; nothing here can submit an extrinsic.

Send storage keys as strings. A u64 key like 9223372036854775808 (2⁷³) exceeds JavaScript's MAX_SAFE_INTEGER; a client that parses it as a number queries 9223372036854776000 instead — a different key whose empty result reads like confirmation. Responses echo args back so you can check.

Verify against hex, not human. toHuman() abbreviates hashes (an all-zero H256 shows as 0x0000…0000) and group-separates integers, so every response carries human, JSON and hex together, plus a count for Vec results.

There is an interactive UI for this at /chain-state, with shareable deep links (?pallet=&item=&args=&at=).

curl 'https://peaqexplorer.pathrocknetwork.org/api/decode/12250870?method=submit_snapshot'
curl 'https://peaqexplorer.pathrocknetwork.org/api/state/ocex/validatorSetId?at=12250870'
curl 'https://peaqexplorer.pathrocknetwork.org/api/state/ocex/authorities?args=6280&at=12250870'

Price feed, governance & email

Price providers are pluggable via the PRICE_PROVIDERS env var (csv; default coingecko, a keyless public API).

Schema — GET /api/network-info

{
  "networkInfo": {
    "activeEra": number,              // current staking era index
    "avgValidatorCommission": number, // mean active-validator commission, %
    "avgApy": number,                 // headline AVG APY %, commission-adjusted
    "avg_apy": number,                // snake_case alias of avgApy
    "validators":  { "active": number, "total": number },
    "nominators":  { "active": number, "total": number },
    "maxActiveStake": number,         // largest active-validator total stake, PEAQ
    "minStake": number,               // minimum active stake, PEAQ
    "averageStake": number,           // mean active-validator stake, PEAQ
    "avgStakePerAccount": number,     // total bonded / staking accounts, PEAQ
    "totalIssuance": number,          // total PEAQ issuance
    "totalBonding": number,           // total PEAQ bonded for staking
    "totalBondingPercent": number,    // totalBonding / totalIssuance, %
    "totalUnbonding": number,         // total PEAQ currently unbonding
    "totalStakeChange": number,       // net stake change vs previous era, PEAQ
    "lastEraRewardsTotal": number     // total rewards paid last era, PEAQ
  },
  "lastSync": number,                 // epoch ms when networkInfo was computed
  "status": "Synced" | "Stale" | "Initializing" | "Error",
  "chainHead": {
    "value": number,                  // best block number
    "lastAdvanceAt": number,          // epoch ms the head last advanced
    "staleSeconds": number,           // seconds since the head last advanced
    "isStale": boolean                // true if the head looks stuck
  }
}

AVG APY is returned directly (avgApy, and the avg_apy alias), derived as avgApy = 23.09 × (1 − avgValidatorCommission / 100), where 23.09% is the chain's nominal maximum APY at its target staking ratio.

Errors & addresses

Failures return a 4xx/5xx status with { "error": "<message>" }. Endpoints that depend on the chain RPC return 503 with { "error": "rpc not connected" } during RPC outages — treat 503 as "retry with backoff", not permanent. Paths that take an :address expect peaq SS58 (prefix 42, addresses start with 5…); the server normalizes all forms to the chain prefix, so other SS58 forms usually resolve too.

Caching tiers

Hot endpoints carry Cache-Control in three tiers — don't poll faster than max-age: short (blocks/transactions/events: max-age=5), medium (wallet/validators/network-info/price-latest: max-age=30), long (price-history/staking-rewards/holders: max-age=300).

Quick examples

curl https://peaqexplorer.pathrocknetwork.org/api/network-info
curl https://peaqexplorer.pathrocknetwork.org/api/price-latest
curl 'https://peaqexplorer.pathrocknetwork.org/api/price-history?days=30'