On this page
  • Overview

  • Conventions

  • Response envelope

  • Pagination

  • Sorting

  • Amounts and units

  • Errors

  • Status

  • Blocks

  • List

  • Get a block

  • By hash

  • Transactions

  • Get a tx

  • Raw tx

  • Addresses

  • Rich list

  • Get an address

  • Tx history

  • UTXOs

  • Mempool

  • Snapshot

  • Fee histogram

  • Timeline

  • Per-block snapshot

  • Superblocks

  • List

  • Get one

  • CPIDs

  • Researcher detail

  • Blocks staked

  • Leaderboard

  • Polls

  • List

  • Get a poll

  • Beacons

  • History per CPID

  • MRC requests

  • List

  • Summary

  • Daily activity

  • Wait distribution

  • Bid vs. payout

  • Staker take

  • Network

  • Current snapshot

  • History

  • Difficulty history

  • Metrics

  • Bucketed time series

  • Magnitude leaderboard

  • Research / block split

  • Beacon flux

  • Staker mix

  • Fee percentiles

  • Wealth distribution

  • Cohort retention

  • Beacon survival

  • Search

API Reference

A public, auth-free JSON:API for the Gridcoin chain. Every block, transaction, address, claim, superblock, poll, and beacon view that powers the dashboard you're reading.

Overview

The Gridcoin Explorer exposes a public, no-auth, read-only JSON:API covering every block, transaction, address, claim, superblock, poll and beacon the indexer has observed. The same data drives the web dashboard you are looking at. Anything visible in the UI is available to your code at one of the endpoints below.

Base URLs

  • Mainnet: https://explorer.gridcoin.club/api

    The canonical Gridcoin chain.

  • Testnet: https://testnet-explorer.gridcoin.club/api

    A separate stack indexing the Gridcoin testnet wallet. Same shape, separate data.

The two stacks are isolated; the testnet API will never return mainnet data and vice versa. The active stack identifies itself in the meta.network field of every response.

Quick test

Request · bash
curl 'https://explorer.gridcoin.club/api/status'
Response — 200 OK · json
{
"data": {
"type": "status",
"id": "now",
"attributes": {
"service": "grc-explorer",
"version": "1.0.0",
"network": "mainnet",
"indexer": {
"status": "live",
"lastIndexedHeight": 89281,
"lastIndexedHash": "a5296f58a974...",
"tipHeight": 89281
}
}
},
"meta": { "network": "mainnet", "version": "1.0.0" }
}

Authentication

None. The API is read-only and public; sending an Authorization header has no effect.

Rate limits

Per-IP, 60-second sliding window:

  • Reads: 1800 / minute

    Every endpoint listed below counts toward this bucket.

  • Search: 300 / minute

    Limit on the federated /search endpoint specifically.

Conventions

Every endpoint follows the same envelope, query-parameter shape and unit conventions. Read this section once and the rest of the reference is repetition.

Response envelope

Single resources return a single data object; collections return a data array. Both shapes carry a meta object at the top level. List endpoints include meta.count with the total matching record count, and every response includes meta.network and meta.version.

Single resource · json
{
"data": {
"type": "blocks",
"id": "89281",
"attributes": { /* ... */ }
},
"meta": { "network": "testnet", "version": "1.0.0" }
}
Collection · json
{
"data": [
{ "type": "blocks", "id": "89281", "attributes": { /* ... */ } },
{ "type": "blocks", "id": "89280", "attributes": { /* ... */ } }
],
"meta": { "count": 89282, "network": "testnet", "version": "1.0.0" }
}

Pagination

  • page[size]: items per page

    Default 25, maximum 100. Values above 100 are silently capped.

  • page[number]: zero-indexed page number

    Offset is computed as page[number] × page[size].

  • page[offset]: absolute record offset

    Skip N records before returning results. Mutually exclusive with page[number].

Sorting

List endpoints accept a sort=field parameter for ascending order or sort=-field for descending. Unspecified sort falls back to the natural order documented per endpoint (typically newest-first by height or timestamp).

Amounts and units

  • GRC strings

    Returned as decimal strings (e.g. "12.34567890") to keep precision intact across JSON. Never parse with parseFloat into a hot calculation; treat as strings or use a BigNumber library.

  • Halford

    Some lower-level fields (notably percentile responses, raw-tx fee fields) ship as halford: the integer count of one hundred-millionths of a GRC (1 GRC = 100,000,000 halford). Divide by 100,000,000 for GRC, or compare halford-to-halford directly.

  • Timestamps

    Block / claim / beacon timestamps are Unix seconds (Number). Mempool timestamps are Unix seconds. The web frontend formats these locally; the API never returns ISO strings for these fields.

  • Heights and txids

    Heights are integers. Block hashes and tx ids are 64-character lowercase hex.

Errors

Errors are returned with the appropriate HTTP status code and a JSON:API errors array. Successful responses never include this array; errors never include a data field.

Response — 404 Not Found · json
{
"errors": [
{
"status": 404,
"title": "Block not found"
}
]
}

Common status codes

  • 200 OK

    Successful read.

  • 302 Found

    Used by hash-lookup endpoints to redirect to the canonical resource (e.g. /blocks/hash/:hash → /blocks/:height).

  • 400 Bad Request

    A query parameter failed validation. Common causes: malformed cohort string, non-integer page size, unsupported granularity.

  • 404 Not Found

    The requested resource does not exist.

  • 429 Too Many Requests

    Rate limit exhausted. Retry-After header indicates how long until your bucket refills.

  • 503 Service Unavailable

    The indexer or its wallet RPC is unreachable. Transient. Retry with backoff.

Status

Health, version, and indexer cursor. Useful for client-side backoff: indexer.tipHeight - indexer.lastIndexedHeight tells you how far behind the chain tip the explorer currently is.

GET/api/status

Service health

Request · bash
curl 'https://explorer.gridcoin.club/api/status'
Response — 200 OK · json
{
"data": {
"type": "status",
"id": "now",
"attributes": {
"service": "grc-explorer",
"version": "1.0.0",
"network": "testnet",
"indexer": {
"status": "live",
"lastIndexedHeight": 89281,
"lastIndexedHash": "a5296f58a974...",
"tipHeight": 89281,
"reorgDepth": 0
},
"mempoolSnapshotsFromHeight": 89200
}
}
}

indexer.status is one of backfilling, live, or reorg. mempoolSnapshotsFromHeight is the earliest block for which /api/blocks/:height/mempool-snapshotreturns rows; nullif the deployment hasn't captured any yet. Older heights return empty.

Blocks

Block headers and aggregate metadata. Heights are 0-indexed; hash is the standard double-SHA256 block hash returned as 64 lowercase hex chars.

List blocks

GET/api/blocks

Newest first

Default sort is -height. Supports the common page[size] and page[number] parameters.

Request · bash
curl -g 'https://explorer.gridcoin.club/api/blocks?page[size]=2'
Response — 200 OK · json
{
"meta": { "count": 89282 },
"data": [
{
"type": "blocks",
"id": "89281",
"attributes": {
"height": 89281,
"hash": "a5296f58a974686e7356da9b5931650b9fdfbf77958a125489b663a7c074d438",
"prevHash": "16b6ec49ad073391...",
"time": 1775914221,
"txCount": 1,
"isPos": true,
"isSuperblock": false,
"isMrc": false,
"minerAddress": "S6XqhSVj...",
"stakerCpid": "ab12...c34d"
}
},
{
"type": "blocks",
"id": "89280",
"attributes": { /* ... */ }
}
]
}

isMrcis true when the block's claim included any MRC payouts. Combined with isSuperblock it lets a list view tag the row visually without an extra round-trip.

Get a block by height

GET/api/blocks/:height

Block detail

Returns the block plus embedded transactions and (for staking blocks) the claim payload, the same shape the dashboard's block detail page consumes. The claim object also carries mrc_foundation_fees and mrc_staker_feeswhen the block bundled MRC payouts — the chain's own accounting of how the bid fees were split between the Foundation and the staker.

Request · bash
curl 'https://explorer.gridcoin.club/api/blocks/89281'
Response — 200 OK (excerpt) · json
{
"data": {
"type": "blocks",
"id": "89281",
"attributes": {
"height": 89281,
"hash": "a5296f58a974...",
"prevHash": "16b6ec49ad07...",
"merkleRoot": "fa01b3...",
"time": 1775914221,
"version": 13,
"difficulty": "0.18272300",
"size": 412,
"txCount": 1,
"isPos": true,
"isSuperblock": false,
"minerAddress": "S6XqhSVj...",
"stakerCpid": "ab12...c34d",
"mint": "5.00000000",
"moneySupply": "123456789.00000000"
}
},
"transactions": [
{ "txId": "56886c5134...", "isCoinbase": false, "isCoinstake": true,
"totalOut": "5.00000000", "fee": "0.00000000" }
],
"claim": { "cpid": "ab12...c34d", "organization": "world community grid",
"client_version": "5.4.10.0", "block_subsidy": "0",
"research_subsidy": "5.00000000", "magnitude": 12.34, "is_mrc": false,
"mrc_foundation_fees": "0", "mrc_staker_fees": "0" },
"mrcs": [],
"tipHeight": 89281,
"meta": { "network": "testnet", "version": "1.0.0" }
}

Lookup by hash

GET/api/blocks/hash/:hash

302 redirect

Redirects to the canonical /api/blocks/:height URL. Useful when you have a hash from a logging system or chain analysis tool. Pass -L so curl follows the redirect for you.

Request · bash
curl -L 'https://explorer.gridcoin.club/api/blocks/hash/a5296f58a974686e7356da9b5931650b9fdfbf77958a125489b663a7c074d438'

Transactions

Transaction detail with resolved input addresses, output values, and confirmation status.

Get a transaction

GET/api/transactions/:tx_id

With resolved vins

Vin entries are joined against tx_outputson the indexer side so each input arrives with its source address and value already resolved. No extra round-trips needed for "who sent this".

Request · bash
curl 'https://explorer.gridcoin.club/api/transactions/56886c5134ace2589d8cd0d49a61c8b6f6ca9e7135636bf76956537a9602a222'
Response — 200 OK (excerpt) · json
{
"data": {
"type": "transactions",
"id": "56886c5134ace2589d8cd0d49a61c8b6f6ca9e7135636bf76956537a9602a222",
"attributes": {
"txId": "56886c5134...",
"blockHeight": 89281,
"time": 1775914221,
"size": 224,
"fee": "0.00010000",
"totalIn": "100.00000000",
"totalOut": "99.99990000",
"isCoinbase": false,
"isCoinstake": true,
"vins": [
{ "vinN": 0, "prevTx": "ab12...", "prevVout": 1,
"address": "S6XqhSVj...", "value": "100.00000000" }
],
"vouts": [
{ "voutN": 0, "value": "0.00000000", "address": null,
"scriptType": "nonstandard", "isSpent": false, "spentInTx": null },
{ "voutN": 1, "value": "99.99990000", "address": "S6XqhSVj...",
"scriptType": "pubkey", "isSpent": false, "spentInTx": null }
],
"mrc": null,
"confirmations": 5
}
}
}

When the transaction is an MRC request, the response carries an mrc object alongside vins / voutswith the request's parsed contract body — cpid, researchSubsidy, feeOffered, magnitude, lastBlockHash, signature, firstSeen, blockHeight / blockTime when confirmed. null for non-MRC txs.

Lookup tiers: indexed transactions table, then mempool. Random / unknown txids return 404; tx_id must be 64 lowercase hex characters or the request 400s at the edge.

Raw transaction

GET/api/transactions/:tx_id/raw

Hex + decoded

Returns the raw hex serialization plus the daemon's decoded JSON for the transaction. This call is lazy: it hits the wallet daemon on demand rather than serving from the indexer cache, so it can be slower than other reads. Script ASMs are cleaned up to fix the daemon's decimal-encoding of small data pushes.

Request · bash
curl 'https://explorer.gridcoin.club/api/transactions/56886c5134ace2589d8cd0d49a61c8b6f6ca9e7135636bf76956537a9602a222/raw'
Response — 200 OK (excerpt) · json
{
"data": {
"type": "raw_transactions",
"id": "56886c5134...",
"attributes": {
"hex": "0100000001ab12...",
"decoded": { "txid": "56886c5134...", "vin": [/*...*/], "vout": [/*...*/] }
}
}
}

Addresses

Per-address running balances, transaction history, and UTXO set. The list endpoint is the rich-list view (top-N by current balance).

Rich list

GET/api/addresses

Sorted by balance desc

Default page[size]=100, max 1000. The addresses table carries an index on balance DESC so this is a cheap top-N read regardless of total row count.

Request · bash
curl -g 'https://explorer.gridcoin.club/api/addresses?page[size]=10'
Response — 200 OK (excerpt) · json
{
"meta": { "count": 12345, "network": "testnet", "version": "1.0.0" },
"data": [
{
"type": "addresses",
"id": "S6XqhSVj...",
"attributes": {
"address": "S6XqhSVj...",
"balance": "1234.56789012",
"totalReceived": "5000.00000000",
"totalSent": "3765.43210988",
"txCount": 42,
"firstSeenBlock": 12345,
"lastSeenBlock": 89281
}
}
]
}

Get an address

GET/api/addresses/:address

Balance + counters

Returns the current-state mirror plus a pendingBalance derived from the live mempool.

Request · bash
curl 'https://explorer.gridcoin.club/api/addresses/S6XqhSVj4eSAoRshrYVcCcdtdqejZ7nApu'
Response — 200 OK · json
{
"data": {
"type": "addresses",
"id": "S6XqhSVj...",
"attributes": {
"address": "S6XqhSVj...",
"balance": "1234.56789012",
"totalReceived": "5000.00000000",
"totalSent": "3765.43210988",
"txCount": 42,
"firstSeenBlock": 12345,
"lastSeenBlock": 89281
}
},
"pendingBalance": "0.50000000"
}

Transaction history

GET/api/addresses/:address/transactions

Per-tx deltas

Paginated, newest-first. Each row carries the net delta this address experienced in that transaction.

Request · bash
curl -g 'https://explorer.gridcoin.club/api/addresses/S6XqhSVj4eSAoRshrYVcCcdtdqejZ7nApu/transactions?page[size]=25'
Response — 200 OK (excerpt) · json
{
"meta": { "count": 42 },
"data": [
{
"type": "address_transactions",
"id": "56886c5134...:0",
"attributes": {
"txId": "56886c5134...",
"blockHeight": 89281,
"time": 1775914221,
"delta": "100.00000000",
"fee": "0.00010000",
"isCoinstake": false
}
}
]
}

UTXOs

GET/api/addresses/:address/utxos

Unspent outputs

Returns every output for this address where spent_in_height IS NULL.

Request · bash
curl 'https://explorer.gridcoin.club/api/addresses/S6XqhSVj4eSAoRshrYVcCcdtdqejZ7nApu/utxos'
Response — 200 OK (excerpt) · json
{
"data": [
{
"type": "utxos",
"id": "56886c5134...:1",
"attributes": {
"txId": "56886c5134...",
"voutN": 1,
"value": "100.00000000",
"blockHeight": 89281,
"scriptType": "pubkeyhash"
}
}
]
}

Mempool

Every mempool entry carries firstSeen, confirmedAt, and evictedAt timestamps.

Snapshot

GET/api/mempool

Current pending tx set

Active mempool = txs where neither confirmedAt nor evictedAt is set.

Request · bash
curl -g 'https://explorer.gridcoin.club/api/mempool?page[size]=100'
Response — 200 OK (excerpt) · json
{
"meta": { "count": 4 },
"data": [
{
"type": "mempool_txs",
"id": "56886c5134...",
"attributes": {
"txId": "56886c5134...",
"firstSeen": 1775914000,
"feeEstimate": "0.00010000",
"size": 224,
"vinCount": 1,
"voutCount": 2,
"isMrc": false
}
}
]
}

isMrc flags rows whose tx is an MRC request — see the dedicated /api/mrc-requests namespace for per-MRC details and dashboards.

Fee histogram

GET/api/mempool/fee-histogram

Pending tx fee distribution

Bucketed by fee-per-KB (halford). Updates every 5 seconds.

Request · bash
curl 'https://explorer.gridcoin.club/api/mempool/fee-histogram'
Response — 200 OK · json
{
"data": {
"type": "fee_histogram",
"id": "now",
"attributes": {
"buckets": [
{ "feePerKb": 1000, "count": 14 },
{ "feePerKb": 5000, "count": 7 },
{ "feePerKb": 10000, "count": 2 }
]
}
}
}

Timeline

GET/api/mempool/timeline

Mempool size over time

Query parameters

  • hours: window length

    Default 6, max 168 (7 days).

  • step: bucket size in seconds

    Server-side downsample. 0 (default) returns one point per sample.

Request · bash
curl 'https://explorer.gridcoin.club/api/mempool/timeline?hours=6&step=300'
Response — 200 OK (excerpt) · json
{
"data": {
"type": "mempool_timeline",
"id": "6h:300s",
"attributes": {
"from": 1775892000, "to": 1775914000,
"step": 300,
"points": [
{ "ts": 1775892000, "size": 3, "feeMedian": "0.00010000" },
{ "ts": 1775895600, "size": 7, "feeMedian": "0.00012000" },
{ "ts": 1775899200, "size": 5, "feeMedian": "0.00010000" }
]
}
}
}

Per-block snapshot

GET/api/blocks/:height/mempool-snapshot

What was pending when the block landed

At every block commit the indexer freezes the active mempool set (txs first-seen ≤ block.time, not yet confirmed/evicted by then) and stores it as a per-block snapshot. Useful for studying tx ordering, fee priority, and how long pending txs waited before inclusion. wasIncludedflags the txs this same block then confirmed — derived from the block's parsed tx-id list, not from confirmed_at (which has racing writers).

Coverage window:snapshots only exist for blocks the indexer ingested after the snapshot machinery was deployed — blocks before the cutoff return zero rows. Mempool observations can't be reconstructed from chain alone, so a re-ingest from genesis won't backfill them. The cutoff is also exposed as mempoolSnapshotsFromHeight on /api/status for programmatic discovery.

Request · bash
curl 'https://explorer.gridcoin.club/api/blocks/3170876/mempool-snapshot'
Response — 200 OK (excerpt) · json
{
"data": {
"type": "mempool_snapshot",
"id": "3170876",
"attributes": {
"blockHeight": 3170876,
"blockHash": "e66fac1f9bb3...",
"blockTime": 1778233328,
"capturedAt": 1778233337,
"count": 1,
"includedCount": 1,
"totalFees": "0.001",
"totalSize": 245,
"txs": [
{
"txId": "18ef7aee...",
"firstSeen": 1778233310,
"feeEstimate": "0.001",
"size": 245,
"vinCount": 1,
"voutCount": 2,
"wasIncluded": true
}
]
}
}
}

Superblocks

Gridcoin's superblocks anchor the magnitude payouts. Every superblock height carries a quorum hash and the full per-CPID magnitude table.

List

GET/api/superblocks

Newest first

Paginated. Returns the same headline counters that the dashboard superblocks page consumes.

Request · bash
curl -g 'https://explorer.gridcoin.club/api/superblocks?page[size]=20'
Response — 200 OK (excerpt) · json
{
"meta": { "count": 1234 },
"data": [
{
"type": "superblocks",
"id": "89000",
"attributes": {
"height": 89000,
"quorumHash": "ab12cd34...",
"totalMagnitude": 1235.5,
"cpidCount": 421,
"projectCount": 12
}
}
]
}

Get one

GET/api/superblocks/:height

With magnitude table

Returns the superblock plus the full cpid → magnitude table. Large CPID counts (mainnet superblocks may carry several thousand entries), so pull on demand only, not on every page load.

Request · bash
curl 'https://explorer.gridcoin.club/api/superblocks/89000'
Response — 200 OK (excerpt) · json
{
"data": {
"type": "superblocks",
"id": "89000",
"attributes": {
"height": 89000,
"quorumHash": "ab12cd34...",
"totalMagnitude": 1235.5,
"cpidCount": 421,
"projectCount": 12,
"payloadSize": 6543
}
},
"magnitudes": [
{ "cpid": "ab12...c34d", "magnitude": 12.34 },
{ "cpid": "ef56...7890", "magnitude": 11.21 }
]
}

CPIDs

Researcher views: claim history, magnitude over time, beacon records, and blocks staked.

Researcher detail

GET/api/cpids/:cpid

Aggregate view

Bundles claims (last 50), magnitudes (last 100 superblocks), beacons, and the count of blocks staked by this CPID.

Request · bash
curl 'https://explorer.gridcoin.club/api/cpids/ab12cd34ef567890ab12cd34ef567890'
Response — 200 OK (excerpt) · json
{
"data": {
"type": "cpids",
"id": "ab12cd34ef567890ab12cd34ef567890",
"attributes": {
"cpid": "ab12cd34ef567890ab12cd34ef567890",
"magnitude": 12.34,
"blocksStaked": 87,
"lastSeenBlock": 89281
}
},
"claims": [
{ "blockHeight": 89281, "researchSubsidy": "5.00000000",
"magnitude": 12.34, "isMrc": false }
],
"magnitudes": [
{ "superblockHeight": 89000, "magnitude": 12.34 }
],
"beacons": [
{ "blockHeight": 88000, "address": "S6XqhSVj...",
"expiration": 1791000000, "status": "active" }
],
"mrcs": [
{ "txId": "4f0d7710...", "researchSubsidy": "1228.01",
"feeOffered": "0.01093607", "firstSeen": 1776612237,
"blockHeight": 3154442, "blockTime": 1776612240,
"status": "confirmed", "waitSeconds": 3 }
]
}

mrcscarries this CPID's MRC request history (last 100, newest first). status is pending | confirmed | evicted; waitSeconds is blockTime − firstSeen for confirmed requests we observed enter mempool, nullotherwise.

Blocks staked

GET/api/cpids/:cpid/blocks

Paginated

One row per block this CPID staked, joined to the matching claim for subsidy + magnitude. Newest-first.

Request · bash
curl -g 'https://explorer.gridcoin.club/api/cpids/ab12cd34ef567890ab12cd34ef567890/blocks?page[size]=25'
Response — 200 OK (excerpt) · json
{
"meta": { "count": 87 },
"data": [
{
"type": "cpid_blocks",
"id": "89281",
"attributes": {
"blockHeight": 89281,
"time": 1775914221,
"researchSubsidy": "5.00000000",
"magnitude": 12.34,
"isMrc": false
}
}
]
}

Leaderboard with rank-delta

GET/api/cpids/leaderboard

Top-N + Δ

Top researchers by current magnitude with an optional rank delta against an earlier moment. Powers the dashboard's ↑3 / ↓7 / NEW column.

Query parameters

  • limit: top-N size

    Default 20, max 100.

  • at: anchor for "current"

    Default = latest indexed superblock. Allows historical leaderboards.

  • compare_at: delta anchor

    Unix-seconds. Each row gets rankThen / rankDelta / isNew computed against the leaderboard at that moment.

Request · bash
curl 'https://explorer.gridcoin.club/api/cpids/leaderboard?limit=20&compare_at=1773408000'
Response — 200 OK · json
{
"data": [
{
"type": "cpid_leaderboard",
"id": "ab12...c34d",
"attributes": {
"cpid": "ab12...c34d",
"rank": 1,
"magnitude": 124.5,
"rankThen": 4,
"rankDelta": 3,
"isNew": false
}
},
{
"type": "cpid_leaderboard",
"id": "ef56...7890",
"attributes": {
"cpid": "ef56...7890",
"rank": 2,
"magnitude": 110.0,
"rankThen": null,
"rankDelta": null,
"isNew": true
}
}
],
"meta": {
"currentSuperblockHeight": 89000,
"compareSuperblockHeight": 85800,
"limit": 20
}
}

Polls

Governance polls and their tallies. Decoded from the contract payload at index time, so this returns rich data without any extra RPC round-trips.

List polls

GET/api/polls

Paginated, optionally active-only

Pass ?active=1 to filter to currently open polls (end_time > now). Default sort is -block_height.

Request · bash
curl 'https://explorer.gridcoin.club/api/polls?active=1'
Response — 200 OK (excerpt) · json
{
"meta": { "count": 234 },
"data": [
{
"type": "polls",
"id": "646a3e84a4c5e6a8...",
"attributes": {
"id": "646a3e84a4c5e6a8...",
"title": "Should the protocol upgrade to v13?",
"blockHeight": 88000,
"startTime": 1773000000,
"endTime": 1775914000,
"responseType": 1,
"voteWeight": "magnitude",
"active": true
}
}
]
}

Get a poll

GET/api/polls/:poll_id

Poll + options + tally

Returns the poll metadata, the option list, and the current vote tally per option. The tally is derived on read from votes, so reorgs and late-arriving votes are reflected without manual recomputation.

Request · bash
curl 'https://explorer.gridcoin.club/api/polls/646a3e84a4c5e6a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2'
Response — 200 OK (excerpt) · json
{
"data": {
"type": "polls",
"id": "646a3e84a4c5e6a8...",
"attributes": {
"title": "Should the protocol upgrade to v13?",
"question": "Vote yes to enable v13 features at block 100000.",
"blockHeight": 88000,
"startTime": 1773000000,
"endTime": 1775914000,
"responseType": 1,
"voteWeight": "magnitude",
"active": true,
"totalVotes": 21,
"totalWeight": "165.50"
}
},
"options": [
{ "id": 0, "label": "Yes",
"tally": { "votes": 14, "weight": "120.50" } },
{ "id": 1, "label": "No",
"tally": { "votes": 7, "weight": "45.00" } }
]
}

Beacons

Beacon advertisements link a CPID to an address. Each beacon row carries block_height, expiration, and a superseded_at_height sentinel that closes the row when a newer beacon for the same CPID lands.

Beacon history

GET/api/beacons/:cpid

Full history per CPID

Status is derived on read:

Status logic
if status === "revoked" -> "revoked"
else if superseded_at_height set -> "superseded"
else if expiration > evalTime -> "active"
else -> "expired"
Request · bash
curl 'https://explorer.gridcoin.club/api/beacons/ab12cd34ef567890ab12cd34ef567890'
Response — 200 OK (excerpt) · json
{
"data": [
{
"type": "beacons",
"id": "56886c5134...",
"attributes": {
"cpid": "ab12cd34ef567890ab12cd34ef567890",
"address": "S6XqhSVj...",
"blockHeight": 88000,
"time": 1773000000,
"expiration": 1791000000,
"supersededAtHeight": null,
"status": "active"
}
}
]
}

MRC requests

Manual Researcher Compensation: a researcher submits an MRC request transaction with a small bid fee, and a future staker bundles the payout into the next block's claim. Endpoints below cover both pending requests (caught in mempool) and confirmed ones (matched to a block via tx_id).

Status taxonomy is the same across all routes: confirmed — staker bundled the payout (block_height set); evicted — never confirmed, mempool tx fell out; pending — neither, still waiting for inclusion. waitSeconds is blockTime − firstSeen for confirmed requests the explorer actually saw enter mempool, and null for historical replay rows where firstSeen = blockTime.

List MRC requests

GET/api/mrc-requests

Paginated, filterable

Query parameters

  • cpid: filter by researcher CPID (32 hex)

    Optional. Combines with status.

  • status: pending | confirmed | evicted

    Optional. Omit for all.

  • page[size], page[offset]

    Standard pagination. Sort is firstSeen DESC.

Request · bash
curl -g 'https://explorer.gridcoin.club/api/mrc-requests?status=confirmed&page[size]=2'
Response — 200 OK (excerpt) · json
{
"meta": { "count": 18 },
"data": [
{
"type": "mrc_request",
"id": "4f0d7710c3ae6fd8b3c88a03863e2ce14b2eaf6362acff45dbb400356466fa9f",
"attributes": {
"txId": "4f0d7710...",
"version": 1,
"cpid": "0ca9e97f18b87e18cbcd9dc98bb37864",
"clientVersion": "v5.5.0.0",
"organization": "Darren Steer",
"researchSubsidy": "1228.01444214",
"feeOffered": "0.01093607",
"magnitude": 0,
"magnitudeUnit": 0,
"lastBlockHash": "0d648484af1f7b...",
"payToAddress": "n3ofNpzf1cwRG8...",
"firstSeen": 1776612237,
"blockHeight": 3154442,
"blockTime": 1776612240,
"status": "confirmed",
"waitSeconds": 3
}
}
]
}

Summary

GET/api/mrc-requests/summary

Lifetime + 24h totals

Request · bash
curl 'https://explorer.gridcoin.club/api/mrc-requests/summary'
Response — 200 OK · json
{
"data": {
"type": "mrc_summary",
"id": "now",
"attributes": {
"confirmedCount": 18,
"confirmedResearchTotal": "27842.13",
"confirmedFeeTotal": "1.834",
"last24hCount": 0,
"last24hResearchTotal": "0",
"distinctCpids": 5,
"pendingCount": 0,
"evictedCount": 0
}
}
}

Daily activity

GET/api/mrc-requests/timeline

Confirmed-MRC count + payouts per day

Query parameters

  • days: window length

    Default 30, max 365.

Request · bash
curl 'https://explorer.gridcoin.club/api/mrc-requests/timeline?days=30'
Response — 200 OK (excerpt) · json
{
"data": {
"type": "mrc_timeline",
"id": "last_30d",
"attributes": {
"days": 30,
"samples": [
{ "ts": 1773014400, "count": 1, "researchTotal": "1228.01",
"feeTotal": "0.01093607", "distinctCpids": 1 }
]
}
}
}

Wait-time distribution

GET/api/mrc-requests/wait-distribution

Histogram of mempool wait

Buckets the blockTime − firstSeen delta for confirmed MRCs the explorer observed enter mempool. Historical replay rows (where firstSeen == blockTime) are excluded so the distribution reflects real wait times only.

Query parameters

  • days: window length

    Default 90, max 730.

Request · bash
curl 'https://explorer.gridcoin.club/api/mrc-requests/wait-distribution?days=90'
Response — 200 OK · json
{
"data": {
"type": "mrc_wait_distribution",
"id": "last_90d",
"attributes": {
"days": 90,
"buckets": [
{ "label": "<30s", "count": 12 },
{ "label": "30s–1m", "count": 4 },
{ "label": "1–5m", "count": 1 },
{ "label": "5–15m", "count": 0 },
{ "label": "15m–1h", "count": 0 },
{ "label": "1–6h", "count": 0 },
{ "label": ">6h", "count": 0 }
],
"p50Seconds": 8,
"p95Seconds": 47
}
}
}

Bid fee vs. requested payout

GET/api/mrc-requests/bid-vs-payout

Sample of (research, fee) pairs

Returns up to limit recent confirmed MRCs as raw scatter points so a client can render the fee-market shape without re-aggregating. Capped server-side at 5000.

Query parameters

  • days: window length

    Default 30, max 365.

  • limit: max points returned

    Default 500, max 5000.

Request · bash
curl 'https://explorer.gridcoin.club/api/mrc-requests/bid-vs-payout?days=30&limit=500'
Response — 200 OK (excerpt) · json
{
"data": {
"type": "mrc_bid_vs_payout",
"id": "last_30d",
"attributes": {
"days": 30,
"limit": 500,
"points": [
{ "researchSubsidy": "1228.01", "feeOffered": "0.01093607",
"blockTime": 1776612240,
"cpid": "0ca9e97f18b87e18cbcd9dc98bb37864" }
]
}
}
}

Staker take

GET/api/mrc-requests/staker-take

Daily fee splits at the block level

Aggregates claims.mrc_staker_fees and claims.mrc_foundation_feesper UTC day. Source is the chain's own fee-split accounting (block-level), not derivable from per-request feeOffered alone. Only days that bundled at least one MRC are returned.

Query parameters

  • days: window length

    Default 30, max 365.

Request · bash
curl 'https://explorer.gridcoin.club/api/mrc-requests/staker-take?days=30'
Response — 200 OK (excerpt) · json
{
"data": {
"type": "mrc_staker_take",
"id": "last_30d",
"attributes": {
"days": 30,
"samples": [
{ "ts": 1773014400, "stakerTotal": "0.00821205",
"foundationTotal": "0.00272402", "mrcBlocks": 1 }
]
}
}
}

Network

Live network health (peer count, mempool size, difficulty, tip vs indexed-height delta) plus a 7-day rolling time series of the same.

Current snapshot

GET/api/network

Cached every 15s

Request · bash
curl 'https://explorer.gridcoin.club/api/network'
Response — 200 OK · json
{
"data": {
"type": "network_stats",
"id": "now",
"attributes": {
"tipHeight": 89281,
"tipHash": "a5296f58...",
"indexedHeight": 89281,
"indexerStatus": "live",
"difficulty": "0.18272300",
"peerCount": 18,
"mempoolSize": 0,
"netVersion": 70016,
"rpcVersion": 70016
}
}
}

History

GET/api/network/history

Time series

Query parameters

  • hours: window length

    Default 1, max 168 (7 days).

  • endAt: right-edge of the window, unix-seconds

    Default = now.

  • step: server-side downsample

    Bucket size in seconds, mean per bucket. 0 (default) = no downsample.

Request · bash
curl 'https://explorer.gridcoin.club/api/network/history?hours=24&step=300'
Response — 200 OK (excerpt) · json
{
"data": {
"type": "network_history",
"id": "24h:300s",
"attributes": {
"from": 1775828000, "to": 1775914000,
"step": 300,
"points": [
{ "ts": 1775828000, "tipHeight": 89200, "peerCount": 16,
"mempoolSize": 0, "difficulty": "0.18120000" },
{ "ts": 1775828300, "tipHeight": 89205, "peerCount": 17,
"mempoolSize": 1, "difficulty": "0.18180000" }
]
}
}
}

Difficulty history

Per-day network difficulty across the entire indexed chain. Backed by a daily-bucket aggregate over blocks.difficulty (min/max/avg + first/last block of the day), so the whole-chain response is microseconds to compute regardless of chain length. Powers the /network/difficulty dashboard page.

GET/api/network/difficulty

Daily aggregates

Query parameters

  • range: all or year

    Default "all". When "year", a single calendar year is returned and "year" must be supplied.

  • year: four-digit year

    Required when range=year. Ignored otherwise.

Request · bash
curl 'https://explorer.gridcoin.club/api/network/difficulty?range=year&year=2024'
Response — 200 OK (excerpt) · json
{
"data": {
"type": "difficulty_history",
"id": "year:2024",
"attributes": {
"range": "year",
"year": 2024,
"points": [
{
"ts": 1704067200,
"date": "2024-01-01",
"min": "0.18012400",
"max": "0.19884100",
"open": "0.18402300",
"close": "0.19103500",
"avg": 0.18712,
"samples": 942
}
]
}
}
}

Decimal-typed columns (min, max, open, close) are returned as strings so the long-tail precision survives JSON.parse. avg is a float (the daily sum / count divide is already lossy). samplesis the block count for the day — gives a rough "thinness" signal for early-PoW days.

Metrics

Pre-aggregated rollups for the dashboard charts. Every endpoint here reads from a manually-maintained table, so a chart that would otherwise scan every transaction is just an indexed lookup.

Bucketed time series

GET/api/metrics

Funds-flow / tx-count chart

Query parameters

  • granularity

    "5min" or "1h" (default "5min"). Indexer maintains 1d/1w/1mo buckets too; query directly for those if needed.

  • hours: window

    Default 12, max 168.

Request · bash
curl 'https://explorer.gridcoin.club/api/metrics?granularity=1h&hours=24'
Response — 200 OK (excerpt) · json
{
"data": {
"type": "metric_buckets",
"id": "1h:24h",
"attributes": {
"granularity": "1h", "hours": 24,
"from": 1775828000, "to": 1775914000,
"points": [
{ "bucketTs": 1775828400, "txCount": 32,
"valueMoved": "12345.67890000", "feeTotal": "0.00210000" },
{ "bucketTs": 1775832000, "txCount": 41,
"valueMoved": "23456.78900000", "feeTotal": "0.00280000" }
]
}
}
}

Magnitude leaderboard with sparklines

GET/api/metrics/leaderboard/magnitude

Top-N + history

Top researchers by current magnitude, each with a 14-superblock sparkline.

Request · bash
curl 'https://explorer.gridcoin.club/api/metrics/leaderboard/magnitude?limit=20'
Response — 200 OK (excerpt) · json
{
"data": [
{
"type": "magnitude_leaderboard",
"id": "ab12...c34d",
"attributes": {
"cpid": "ab12...c34d",
"magnitude": 124.5,
"rank": 1,
"history": [120.0, 122.5, 124.5]
}
}
]
}

Research / block reward split

GET/api/metrics/research-split

Last N hours

Request · bash
curl 'https://explorer.gridcoin.club/api/metrics/research-split?hours=168'
Response — 200 OK (excerpt) · json
{
"data": {
"type": "research_split",
"id": "168h",
"attributes": {
"hours": 168,
"blockReward": "1234.50000000",
"researchReward": "5678.90000000",
"researchShare": 0.821
}
}
}

Beacon flux

GET/api/metrics/beacon-flux

Active / new / expired counts

Request · bash
curl 'https://explorer.gridcoin.club/api/metrics/beacon-flux'
Response — 200 OK (excerpt) · json
{
"data": {
"type": "beacon_flux",
"id": "now",
"attributes": {
"active": 421,
"newLast24h": 3,
"expiringNext24h": 5,
"expiredLast24h": 2,
"supersededLast24h": 1
}
}
}

Researcher vs investor staking

GET/api/metrics/staker-mix

Last N blocks ratio

blocks default 1000, min 100, max 10000.

Request · bash
curl 'https://explorer.gridcoin.club/api/metrics/staker-mix?blocks=1000'
Response — 200 OK (excerpt) · json
{
"data": {
"type": "staker_mix",
"id": "blocks=1000",
"attributes": {
"blocks": 1000,
"researchers": 712,
"investors": 288,
"researcherShare": 0.712
}
}
}

Fee percentiles

GET/api/metrics/fee-percentiles

p50 / p95 / p99 over time

Reads pre-computed fee_percentiles rows maintained by FeePercentileJob. Granularity: 5min | 1h | 1d; window via hours (default 24, max 168).

Request · bash
curl 'https://explorer.gridcoin.club/api/metrics/fee-percentiles?granularity=1h&hours=24'
Response — 200 OK (excerpt) · json
{
"data": {
"type": "fee_percentiles_series",
"id": "1h:24h",
"attributes": {
"granularity": "1h", "hours": 24,
"from": 1775830000, "to": 1775914000,
"points": [
{ "bucketTs": 1775830800, "p50": "1024", "p95": "5400", "p99": "12000", "txCount": 14 },
{ "bucketTs": 1775834400, "p50": "1100", "p95": "5800", "p99": "13500", "txCount": 11 }
]
}
}
}

Wealth distribution

GET/api/metrics/wealth-distribution

Snapshot

GET/api/metrics/wealth-distribution/series

Time series

Gini coefficient and top-1% / top-10% / top-100 concentration shares. Snapshots are written daily by WealthSnapshotJob; the series endpoint accepts from and to unix-seconds (defaults to last 365 days).

Request · bash
# Snapshot
curl 'https://explorer.gridcoin.club/api/metrics/wealth-distribution'
# Time series, last 90 days
curl 'https://explorer.gridcoin.club/api/metrics/wealth-distribution/series?from=1768262400'
Response — 200 OK (snapshot, excerpt) · json
{
"data": {
"type": "wealth_distribution",
"id": "now",
"attributes": {
"ts": 1775914000,
"addressesWithBalance": 12345,
"totalSupply": "123456789.00000000",
"gini": "0.7421",
"top1pctShare": "0.4520",
"top10pctShare": "0.7800",
"top100Share": "0.5210"
}
}
}
Response — 200 OK (series, excerpt) · json
{
"data": {
"type": "wealth_distribution_series",
"id": "from=1768262400",
"attributes": {
"from": 1768262400, "to": 1775914000,
"points": [
{ "ts": 1768262400, "gini": "0.7401",
"top1pctShare": "0.4500", "top10pctShare": "0.7780" },
{ "ts": 1768348800, "gini": "0.7405",
"top1pctShare": "0.4510", "top10pctShare": "0.7790" }
]
}
}
}

CPID cohort retention

GET/api/metrics/cpid-cohort-retention

Per-cohort curve

Query parameters

  • cohort (required)

    YYYY-MM. The month CPIDs were first seen claiming.

  • horizon

    Months forward to follow. Default 12, max 36.

Request · bash
curl 'https://explorer.gridcoin.club/api/metrics/cpid-cohort-retention?cohort=2024-01&horizon=12'
Response — 200 OK (excerpt) · json
{
"data": {
"type": "cpid_cohort_retention",
"id": "2024-01:12",
"attributes": {
"cohort": "2024-01",
"horizon": 12,
"cohortSize": 87,
"points": [
{ "monthOffset": 0, "bucketTs": 1704067200, "active": 87 },
{ "monthOffset": 1, "bucketTs": 1706745600, "active": 71 },
{ "monthOffset": 2, "bucketTs": 1709251200, "active": 64 }
]
}
}
}

Beacon survival funnel

GET/api/metrics/beacon-survival

Cohort survival

For each cohort month: how many beacons advertised, confirmed, renewed, expired. Computed from the full beacon table; currently covers the last 12 cohort months.

Request · bash
curl 'https://explorer.gridcoin.club/api/metrics/beacon-survival'
Response — 200 OK (excerpt) · json
{
"data": [
{
"type": "beacon_survival",
"id": "2024-01",
"attributes": {
"cohort": "2024-01",
"advertised": 12,
"confirmed": 11,
"renewed": 9,
"expired": 2
}
}
]
}

Live, event-driven Gridcoin blockchain explorer · mainnet.

Made with by @gridcat · Part of Gridcoin Club ↗ · Terms