Production-ready CLI agent for downloading full past and upcoming ICO lists from CryptoRank API.
.
├── .env.example
├── README.md
├── requirements.txt
├── src
│ ├── __init__.py
│ ├── api_client.py
│ ├── config.py
│ ├── main.py
│ └── models.py
└── tests
└── test_api_client.py
- Create a virtual environment:
python3 -m venv .venv
. .venv/bin/activate- Install dependencies:
pip install -r requirements.txt- Get a CryptoRank API key:
- Open https://cryptorank.io/public-api/dashboard
- Create or select an API plan.
- Generate an API key.
- Copy
.env.exampleto.envand setCRYPTORANK_API_KEY.
The public dashboard currently documents x-api-key: YOUR_KEY. The CLI also supports bearer auth through CRYPTORANK_AUTH_MODE=bearer if your plan/docs require it. Official API docs are linked from https://api.cryptorank.io/v2/docs; the page is JavaScript-rendered, so endpoint and response parsing are intentionally configurable and tolerant. CryptoRank's current public pricing page lists token sales under /currencies/public-sales; the client first tries legacy /ico/{status} endpoints and then falls back to /currencies/public-sales.
Fetch both lists:
python -m src.main --status allFetch only past ICOs and save both JSON and CSV:
python -m src.main --status past --format both --output-dir dataForce public page-data scraping when REST /currencies/public-sales is not
available on your CryptoRank tariff:
python -m src.main --status all --format both --source scrapeFetch upcoming ICOs with debug logs:
python -m src.main --status upcoming --debugRun tests:
pytestThe project includes a small dark table dashboard that reads generated files
from output/.
Generate data first:
python -m src.main --status all --format both --source scrapeStart the static server from the project root:
python -m http.server 8787Open:
http://localhost:8787/frontend/
Build and run the always-on dashboard with daily morning updates:
docker compose up -d --buildThe service:
- serves the UI at
http://localhost:8787/frontend/; - writes generated files to the host
./outputdirectory; - refreshes data on container start by default;
- refreshes data every day at
UPDATE_TIMEin the configuredTZ; - restarts automatically through
restart: unless-stopped.
Runtime settings are read from .env. Useful Docker runner variables:
TZ=Europe/Berlin
HTTP_PORT=8787
UPDATE_TIME=06:00
UPDATE_STATUS=all
UPDATE_SOURCE=scrape
RUN_ON_START=trueCheck logs:
docker compose logs -fStop:
docker compose down[
{
"id": "123",
"name": "Example Protocol",
"symbol": "EXM",
"start_date": "2026-01-15",
"end_date": "2026-01-20",
"status": "upcoming",
"raised_amount": 2500000.0,
"raised_currency": "USD",
"category": "DeFi",
"website": "https://example.org",
"twitter": "https://x.com/example",
"telegram": "https://t.me/example",
"token_price": 0.05,
"tokenomics": {
"tokensForSale": "50000000",
"allocationOfSupply": "5%"
}
}
]