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.)
| Behavior | What 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)
GET /api/blocks— most recent blocksGET /api/block/:number— single block with extrinsics + eventsGET /api/events— most recent on-chain eventsGET /api/transactions— most recent transactionsGET /api/transactions/older?before=<n>— pagination further backGET /api/extrinsic/:block/:txHash— single-extrinsic detailGET /api/validators— full validator set with stake + commissionGET /api/validator/:address— per-validator era historyGET /api/holders— top-balance accountsGET /api/account/:address— account-level summaryGET /api/network-info— network metrics (schema below)GET /api/search/:query— block / extrinsic / account lookupGET /api/staking-rewards/:address— per-address reward historyGET /api/staking-rewards-status— reward-backfill progressGET /api/wallet/:address— wallet dashboard payload (balances, staking incl.activeStakedPlancku128 string, unpaid rewards, recent activity)
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.
GET /api/rpc/metadata— every pallet with its storage items (key arity + types), constants, calls, events, errorsGET /api/state/:pallet/:item— read any storage item.?args=keys,?at=block number/hash,?entries=1to list a map (capped)GET /api/consts/:pallet/:item— runtime constants;?at=supportedGET /api/runtime— runtime spec/impl version;?at=supportedGET /api/decode/:block— every extrinsic decoded argument by argument (name, type, human, JSON, raw hex). Filters?section=?method=?index=; matching ignores case and underscoresPOST /api/rpc/call— allowlisted read-only RPC methods
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
GET /api/price-latest— current PEAQ price, last-sync, and abySourcemap (one entry per configured provider;coingeckolive by default)GET /api/price-history?days=N— daily price series (N capped at 4000); each row tagged with itssourceGET /api/council— council members, motions, runners-upGET /api/treasury— treasury balance + proposals (open + historical)GET /api/democracy— referenda + public proposalsGET /api/governance/latest— most-recent OPEN referendum / proposalGET /api/governance/calendar— unified governance timelineGET /api/discussions,GET /api/discussions/:id— governance discussion threadsPOST /api/email/subscribe,GET /api/email/confirm,GET /api/email/unsubscribe,GET|POST /api/email/preferences— email alerts
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'