API

Public API

SoloLuck exposes its pool data over unauthenticated, read-only endpoints — no key. Each IP address may make up to 5 requests a second, with short bursts of up to 60 more; anything faster is answered with HTTP 429 Too Many Requests. Pool-stats trackers and block explorers are welcome to poll them directly. Everything below is what the website itself renders; nothing private is exposed.

Corrected : this card used to say there was no rate limit.

GET /api/public

The full JSON the site renders. Try it: curl https://sololuck.io/api/public

FieldTypeDescription
pool_namestringPool display name.
fee_pctintFee percent taken from a solved block (0 — SoloLuck is a true 0% pool).
onlineboolWhether the pool and its Bitcoin node are up.
hashrateobjectPool hashrate over 1m, 5m, 1h, 1d as suffixed strings (K/M/G/T/P = ×10³…10¹⁵ H/s), e.g. 27.8T.
minersintDistinct payout addresses currently mining.
workersintConnected workers right now.
bestshareintBest share difficulty the pool has ever seen.
networkobjectBitcoin network difficulty, hashrate, subsidy.
netinfoobjectChain context: height, blocks to_halving / to_retarget, next subsidy.
templateobjectCurrent block template: height, next_height, tip_hash, tip_time, synced.
payoutobjectCurrent block reward breakdown: coinbasevalue, subsidy_sats, fees_sats, fee_pct.
blocksarrayBlocks SoloLuck has solved (empty until the first block).
stratumobjectConnection info: host, port_general.
historyarrayRolling 24h samples: t (time), hr (hashrate), w (workers).
generated_atstringRFC 3339 UTC timestamp the snapshot was built, e.g. 2026-07-02T09:03:01Z.
generated_at_unixintSame instant as Unix epoch seconds — use for staleness checks.
schema_versionintPublic API schema version; bumped on breaking changes.
splitobjectOperator/community honesty split: workers_operator, workers_community, miners_operator, miners_community, hashrate_operator_ths.

GET /pool/pool.status

The ckpool-native status feed (newline-delimited JSON), the format miningpoolstats and similar pool trackers recognise out of the box. curl https://sololuck.io/pool/pool.status

Its Users figure counts every user record ckpool still holds, idle ones included; /api/public's miners counts only addresses producing hashrate right now — both are correct, they answer different questions, so the two numbers will not match.

Other pools: per-coin endpoints

The Bitcoin Cash and DigiByte pools have their own feeds, in the same two forms as the Bitcoin pool:

  • Bitcoin Cash: GET /api/bch (summary JSON, the same fields as /api/stats) and GET /bch/pool/pool.status (ckpool-native)
  • DigiByte: GET /api/dgb (summary JSON, the same fields as /api/stats) and GET /dgb/pool/pool.status (ckpool-native)

They carry pool totals only — no addresses and no per-miner records — and a figure the pool has not reported is left out rather than shown as zero.

Per-address lookup

Any miner's live stats are at /users/<btc-address> (HTML) or /users/<btc-address>.json (JSON).

The bare path is content-negotiated: browsers get the HTML logbook, everything else gets ckpool's own flat JSON schema (hashrate1m…7d, lastshare, shares, bestshare, bestever, authorised, worker[]) — so BTClock-style ckpool dashboards work unchanged. An address that has never mined here returns 404, matching solo.ckpool.org.

Solo Block Record

Every solo-mined Bitcoin block found by a small or home miner that could be verified on-chain, across all public solo pools, as open data under CC BY 4.0, kept by SoloLuck. SoloLuck has not found a Bitcoin block. The same entries are on /legends, each with its own page at /legends/<height>.

  • GET /api/legends/v1/blocks.json: the rows in blocks, newest first, with the license, the method and a ready-made citation
  • GET /api/legends/v1/blocks.csv: the same rows after a header line; a missing value is an empty cell
FieldTypeDescription
heightintBlock height.
datestringDate the block was found, YYYY-MM-DD.
poolstringThe solo pool it was found on.
hardwarestringThe winning hardware, as reported.
hashrate_hsnumber or nullThe winning rig's hashrate in H/s, as the miner, the pool or the press reported it; null when none was published.
difficultynumberNetwork difficulty at that height.
reward_btcnumberThe block reward in BTC.
reward_usd_reportedstring or nullA dollar value exactly as reported at the time; null when none was.
expected_seconds_per_blocknumber or nullExpected time between blocks for that rig, in seconds: difficulty × 232 ÷ hashrate_hs.
chance_per_daynumber or nullThat rig's chance of a block on any one day: 1 − e−86400/T, where T is expected_seconds_per_block.
chance_per_day_one_inint or nullThe same chance as “1 in N”.
source_labelstringWho reported the block.
source_urlstringLink to that report.
block_urlstringThe block on mempool.space.
storystringA short account of the find.
notestring or nullA note on the entry. Where an entry rests on reading an unattributed coinbase rather than on the miner's own report, the note says so.

Beside blocks the JSON carries schema (sololuck-solo-blocks/1), version (the date the record last changed), count, license, cite_as, method, inclusion and csv_sha256, the SHA-256 of the exact CSV bytes served. Neither file carries a build timestamp, so the same record always gives the same bytes. Found an error? Tell us.

Try it: curl https://sololuck.io/api/legends/v1/blocks.csv

Cross-origin requests (CORS)

The read-only data endpoints answer with Access-Control-Allow-Origin: *, so a web page on any site can read them with fetch() straight from the browser. That covers GET and HEAD on:

  • /api/public, /pool/pool.status, /api/stats and the other summary paths, and /api itself when asked for JSON
  • the Bitcoin Cash and DigiByte feeds: /api/bch, /bch/pool/pool.status, /api/dgb, /dgb/pool/pool.status
  • per-address JSON: /users/<address>.json, /users/<address> when asked for JSON, and /dgb/users/<address>
  • open data: the Solo Block Record under /api/legends/v1/ and the Solo Mining Census under /api/census/v1/, JSON and CSV
  • /oembed, for the embeddable odds calculator

For example: fetch("https://sololuck.io/api/public").then(r => r.json()). Keep it a simple request, a plain GET with at most an Accept header: a custom header makes the browser send an OPTIONS check first, which this server does not answer. Nothing here uses cookies or keys, so leave credentials off; the wildcard does not allow them. Errors from these endpoints, such as a 404 for an address that has never mined here, carry the header too. Nothing that writes does, and neither do the site's pages.

Block attribution

Blocks SoloLuck solves carry the coinbase tag /sololuck.io/. Explorers name a block's pool from public registries such as bitcoin-data/mining-pools. SoloLuck's entry is waiting there as pull request #132: the maintainer adds a pool once it has mined a block, and SoloLuck has not found a Bitcoin block yet. See /verify and /proof to check our claims.

Corrected : this card used to say SoloLuck was listed in the bitcoin-data/mining-pools and mempool/mining-pools registries. It is in neither yet.