Recover ETH stuck in old smart contracts
All endpoints are read-only GET requests. Responses are JSON with snake_case keys. No authentication required. Data refreshes on the scheduled refresh cycle from onchain Multicall3 scans. Rate limits vary per endpoint (see each section). CORS * enabled.
Per-address lookups go through the public sharded JSON index on GitHub, not a live API. Same data the site uses internally, delivered via GitHub raw — free, unauthenticated, and never rate-limited.
data/index_shards/meta.json — protocol metadata (contract address, coverage, scan date)data/index_shards/{prefix}.json — 256 shards (00.json…ff.json), keyed by the first two hex chars of the lowercased address{ "0x<full address>": { "<protocol_key>": "<balance_eth>" } }ADDR=0xab5801a7d398351b8be11c439e05c5b3259aec9b
PREFIX=${ADDR:2:2}
curl -s "https://raw.githubusercontent.com/q84c6tsm95-create/forgotten-eth/main/data/index_shards/${PREFIX}.json" \
| jq ".[\"${ADDR}\"]"
const addr = '0xab5801...'.toLowerCase(); const prefix = addr.slice(2, 4); const shard = await (await fetch( `https://raw.githubusercontent.com/q84c6tsm95-create/forgotten-eth/main/data/index_shards/${prefix}.json` )).json(); console.log(shard[addr]); // { protocol_key: "0.123" } or undefined
import json, urllib.request addr = '0xab5801...'.lower() prefix = addr[2:4] url = f'https://raw.githubusercontent.com/q84c6tsm95-create/forgotten-eth/main/data/index_shards/{prefix}.json' shard = json.loads(urllib.request.urlopen(url).read()) print(shard.get(addr)) # { 'protocol_key': '0.123' } or None
Group your addresses by their two-char prefix, fetch each shard once, then do constant-time lookups. 256 shards total ≈ 50 MB worst case; most use cases need fewer than 10. Cache locally and re-fetch only after a new refresh (check /api/summary's scan_date).
/api/check?Direct programmatic access to the per-address endpoint was removed to prevent abuse and keep the public API free. The shards above are the same source of truth, delivered faster and at zero infrastructure cost. The aggregate endpoints (summary, table, total, claims) remain available for live counters.
Overview of all tracked contracts with ETH balances, address counts, and coverage percentages. Rate limit: 30 req/min per IP.
{
"total_eth": 157640.24,
"contract_count": 193,
"contracts": {
"etherdelta": {
"contract": "0x8d12A197cB00D4747a1fe03395095ce2A5CC6819",
"total_eth": 1234.56,
"contract_eth_balance": 1500.00,
"addresses_with_balance": 245119,
"coverage_pct": 99.8,
"scan_date": "2026-03-30 UTC"
},
...
}
}
| Field | Type | Description |
|---|---|---|
| total_eth | number | Sum of all mapped depositor balances across all protocols |
| contract_count | number | Number of tracked contracts |
| contracts.*.total_eth | number | Total ETH mapped to known depositors in this contract |
| contracts.*.contract_eth_balance | number | Actual ETH balance of the contract onchain |
| contracts.*.addresses_with_balance | number | Number of depositors with non-zero balances |
| contracts.*.coverage_pct | number | Percentage of contract ETH mapped to known depositors (total_eth / contract_eth_balance * 100) |
| contracts.*.scan_date | string | When this contract was last scanned (UTC date) |
Detailed metadata for a single protocol: balances, coverage, balance distribution, and monthly TVL history. Rate limit: 60 req/min per IP.
| Parameter | Type | Description |
|---|---|---|
| exchange | string | Protocol key (e.g. etherdelta, ens_old, thedao). See full key list. |
{
"exchange": "etherdelta",
"meta": {
"contract": "0x8d12A197cB00D4747a1fe03395095ce2A5CC6819",
"total_eth": 1234.56,
"contract_eth_balance": 1500.00,
"addresses_with_balance": 245119,
"coverage_pct": 99.8,
"scan_date": "2026-03-30 UTC",
"distribution": {
">=100 ETH": { "count": 10, "total_eth": 2460.18 },
"10-100 ETH": { "count": 150, "total_eth": 3560.60 },
"1-10 ETH": { "count": 1882, "total_eth": 4567.89 },
"0.1-1 ETH": { "count": 8500, "total_eth": 3200.00 },
"0.01-0.1 ETH": { "count": 45000, "total_eth": 1200.00 },
"<0.01 ETH": { "count": 189577, "total_eth": 257.89 }
},
"tvl": [
{ "date": "2018-01", "eth": 150000 },
{ "date": "2026-03", "eth": 1500 }
]
}
}
| Field | Type | Description |
|---|---|---|
| meta.distribution | object | Balance distribution across 6 tiers. Each tier has count (addresses) and total_eth |
| meta.tvl | array | Monthly historical ETH balance from deployment to present. Each entry has date (YYYY-MM) and eth |
| meta.activity | object? | Transaction activity metadata (when available): total transactions, last activity date |
Lightweight endpoint returning total tracked ETH and counts. Ideal for widgets and bots. Rate limit: 60 req/min per IP.
{
"total_eth": 157640.24,
"total_contract_eth": 159064.22,
"contract_count": 193,
"address_count": 552886,
"eth_claimed": 11496.9,
"unique_claimers": 586,
"peak_eth": 169137.14
}
| Field | Type | Description |
|---|---|---|
| total_eth | number | Total ETH mapped to known depositors |
| total_contract_eth | number | Total ETH actually held in contracts onchain (may differ from total_eth due to unmapped depositors) |
| contract_count | number | Number of tracked contracts |
| address_count | number | Total unique addresses with claimable balances across all contracts |
Static JSON listing all tracked protocols with keys, names, and categories. No rate limit.
[
{ "key": "etherdelta", "name": "EtherDelta", "contract": "0x8d12...", "category": "dex" },
{ "key": "ens_old", "name": "ENS Old Registrar", "contract": "0x6090...", "category": "other" },
{ "key": "thedao", "name": "The DAO", "contract": "0xbb9b...", "category": "ico" },
...
]
Descriptions, categories, deploy dates, theme colors, and slugs for all tracked protocols. Static file, no rate limit.
{
"etherdelta": {
"name": "EtherDelta",
"desc": "The first popular decentralized exchange on Ethereum...",
"category": "dex",
"color": "#6441a5",
"contract": "0x8d12A197cB00D4747a1fe03395095ce2A5CC6819",
"deployed": "February 2016",
"slug": "etherdelta"
},
"ens_old": {
"name": "ENS Old Registrar",
"desc": "The original ENS name registration system...",
"category": "other",
"color": "#5284ff",
"contract": "0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef",
"deployed": "May 2017",
"slug": "ens"
},
...
}
All verified ETH claims made through the site. Includes per-claim tx hashes, ENS deed names, and per-protocol aggregates. Rate limit: 30 req/min per IP.
{
"total_claims": 251,
"unique_addresses": 43,
"total_eth": 1042.66,
"by_protocol": {
"ens_old": { "claims": 208, "eth": 763.45 },
"idex": { "claims": 14, "eth": 273.88 },
...
},
"claims": [
{
"timestamp": "2026-04-01T22:09:17.553Z",
"address": "0x5807a8b404c71cf22eb0bac2e5f2a6c202ebe0a1",
"protocol": "ens_old",
"eth": 118.811,
"tx_hash": "0xc70e253ef2445e...",
"deed_name": "wellsfargo"
},
...
]
}
| Field | Type | Description |
|---|---|---|
| total_claims | number | Total number of claim transactions |
| unique_addresses | number | Unique wallets that have claimed |
| total_eth | number | Total ETH claimed across all transactions |
| by_protocol | object | Aggregate claims and ETH per protocol |
| claims[].timestamp | string | ISO 8601 timestamp of the claim |
| claims[].address | string | Wallet address that claimed |
| claims[].protocol | string | Protocol key |
| claims[].eth | number | ETH amount claimed |
| claims[].tx_hash | string | Ethereum transaction hash (verifiable on Etherscan) |
| claims[].deed_name | string? | ENS only. The domain name of the released deed |
All error responses follow a consistent JSON format with an error field.
| Status | Meaning | Response |
|---|---|---|
| 400 | Invalid or missing parameters | {"error": "Invalid address format"} |
| 404 | Protocol not found | {"error": "Unknown exchange"} |
| 405 | Method not allowed | {"error": "Method not allowed"} |
| 429 | Rate limit exceeded (see per-endpoint limits) | {"error": "Rate limit exceeded. Try again in 1 minute."} |
| 500 | Server error (data unavailable) | {"error": "Summary data not available"} |
All API responses include these headers:
| Header | Value | Description |
|---|---|---|
| Cache-Control | private, max-age=300 | Address checks cached for 5 min. /api/summary and /api/table use s-maxage=3600 (1h CDN cache) |
| X-Content-Type-Options | nosniff | Prevents MIME type sniffing |
| Access-Control-Allow-Origin | * | CORS enabled for all origins — call from any domain |
| Content-Type | application/json | All responses are JSON |
ETH values are in ether (not wei) unless the field name ends in _wei.coverage_pct shows what fraction of depositors we've mapped. 100% means all known depositors are indexed.scan_date field shows when each contract was last scanned./data/protocols.json or the /api/summary response./data/ are not rate-limited and can be cached freely.