# Blockchain Scanner Scraper (`publicmoney/blockchain-scanner-scraper`) Actor

Read on-chain data across Ethereum, Base, Polygon, Arbitrum, Optimism, zkSync, Celo, Bitcoin and Solana in one schema: address balance, transaction history, token balances and transfers. Export data, run via API, schedule and monitor runs, or integrate with other tools.

- **URL**: https://apify.com/publicmoney/blockchain-scanner-scraper.md
- **Developed by:** [Public Money](https://apify.com/publicmoney) (Apify)
- **Categories:** Business
- **Stats:** 4 total users, 3 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.00 / 1,000 records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

Every block explorer has its own API, its own key and its own field names, so covering nine chains means nine integrations. This Actor reads them all through one input and returns one schema: address balance and activity, transaction history, token balances and transfers, or token metadata, with `nativeBalance` meaning the same thing whether the chain is Ethereum, Bitcoin or Solana.

### What it does

- Covers **nine chains through one schema**: Ethereum, Base, Polygon, Arbitrum, Optimism, zkSync, Celo, Bitcoin and Solana. Switch the chain input and your parsing code does not change.
- Five **routes** on the same input: `address` for a balance summary, `transactions` for history, `tokenBalances` and `tokenTransfers` for token activity, and `token` for contract metadata.
- Resolves **ENS names** into `ensDomainName` where the chain supports them, so a record is readable without a lookup.
- Flags whether an address is a **contract or a wallet** in `isContract`, which changes how you should read every other field.
- Values token holdings in **USD** in `valueUsd` where a price is available, not just in token units.
- Caps work per address with **Max items per address**, so one busy wallet cannot consume the whole run.

### Use cases

| You need to | How this Actor does it |
| --- | --- |
| Watch a treasury across chains | Pass the same address with each chain and compare `nativeBalance` |
| Audit a wallet's token holdings | Use the `tokenBalances` route and read `valueUsd` |
| Follow the money out of an address | Use the `transactions` route and read `to`, `value` and `method` |
| Tell a contract from a wallet | Read `isContract` before you interpret a balance |
| Track token transfers for a project | Use the `tokenTransfers` route on the project treasury |
| Feed an on-chain research agent | Call the Actor over MCP and let the model pass the address it found |

### Quick start

1. Click **Try for free**.
2. Pick a **Chain**: `ethereum`, `base`, `polygon`, `arbitrum`, `optimism`, `zksync`, `celo`, `bitcoin` or `solana`.
3. Pick a **Route**: `address` for a balance summary, `transactions`, `tokenBalances`, `tokenTransfers`, or `token` for contract metadata.
4. Add your addresses, one per line, in that chain's own format. An Ethereum address on Bitcoin will fail.
5. Click **Start**. Rows appear within seconds.
6. Export as JSON, CSV, Excel or XML, or read the dataset over the API.

### Input

| Field | Type | Default | What it controls |
| --- | --- | --- | --- |
| `chain` | string | `ethereum` | Which of the nine chains to read |
| `route` | string | `address` | What to return: balance summary, transactions, token balances, token transfers or token metadata |
| `addresses` | array | empty | Addresses to read, in the chosen chain's own format |
| `maxItemsPerAddress` | integer | `100` | Caps rows per address, so one busy wallet cannot consume the run |
| `maxItems` | integer | `0` | Caps how many records are written. `0` writes them all |

```json
{
    "chain": "ethereum",
    "route": "address",
    "addresses": [
        "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
    ],
    "maxItemsPerAddress": 100
}
```

### Output

One dataset item per address on the `address` route, and one per transaction, balance or transfer on the others. The dataset has four views, one per route, so the console shows the right columns for what you asked for.

| Field group | Fields |
| --- | --- |
| Always | `status`, `route`, `chainTitle`, `address`, `url` |
| Address route | `nativeSymbol`, `nativeBalance`, `transactionCount`, `tokenTransferCount`, `isContract`, `ensDomainName` |
| Transactions route | `hash`, `timestamp`, `from`, `to`, `value`, `fee`, `method` |
| Token routes | `tokenSymbol`, `tokenName`, `tokenAddress`, `amount`, `valueUsd` |
| Timing | `validFrom`, `scrapedAt` |

```json
{
    "status": "ok",
    "route": "address",
    "chainTitle": "Ethereum",
    "address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
    "ensDomainName": "vitalik.eth",
    "nativeSymbol": "ETH",
    "nativeBalance": 4821.4409,
    "transactionCount": 1842,
    "tokenTransferCount": 9214,
    "isContract": false,
    "validFrom": "2026-09-06T05:30:00.000Z",
    "url": "https://etherscan.io/address/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
}
```

### Integrations

Run it over the API and get the rows back in one call:

```bash
curl -X POST "https://api.apify.com/v2/acts/publicmoney~blockchain-scanner-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"chain": "ethereum", "route": "address", "addresses": ["0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"], "maxItemsPerAddress": 100}'
```

From Python:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("publicmoney/blockchain-scanner-scraper").call(run_input={"chain": "ethereum", "route": "address", "addresses": ["0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"], "maxItemsPerAddress": 100})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["validFrom"])
```

Give an AI agent the Actor over MCP:

```json
{
    "mcpServers": {
        "apify": {
            "url": "https://mcp.apify.com/?actors=publicmoney/blockchain-scanner-scraper"
        }
    }
}
```

Schedules run it on any cron, webhooks fire when a run finishes, and platform integrations push the
dataset to Google Sheets, Slack, Airtable, Zapier or your own endpoint.

### Cost

Pay per event, so you pay for records rather than compute time.

| Event | Free tier | Top volume tier |
| --- | --- | --- |
| Record with data | $0.002 | $0.0007 |
| Actor start | $0.00005 per GB | Same |

A record that returned no data is published as a failure row and is **never charged**. Six volume tiers apply, so the per-record price falls with monthly volume.

### Troubleshooting

| Issue | Solution |
| --- | --- |
| An address returns `failed` | The address format does not match the chain. Bitcoin, Solana and the EVM chains all use different formats, so check the chain input. |
| `ensDomainName` is missing | The address has no ENS name, or the chain does not support ENS. Only the EVM chains resolve names. |
| `valueUsd` is missing on a token | No price is available for that token. The token amount is still exact. |
| One address dominates the run | Lower **Max items per address**. A treasury with a hundred thousand transfers will otherwise fill the dataset. |
| The transactions route returns fewer rows than the explorer shows | **Max items per address** caps it, and the default is 100. Raise it for a full history. |

### FAQ

#### Do I need an Etherscan API key?

No. This Actor reads the explorers for you, so there is no key per chain to register, rotate or keep under a free-tier limit. You need an Apify token to call the Actor over the API.

#### Which chains are supported?

Nine: Ethereum, Base, Polygon, Arbitrum, Optimism, zkSync, Celo, Bitcoin and Solana. The field names are the same on all of them, which is the point of the Actor.

#### Why is one schema across chains useful?

Because `nativeBalance`, `transactionCount` and `isContract` mean the same thing on every chain here. Writing against nine explorer APIs means nine sets of field names and nine sets of pagination rules.

#### Can it read a contract's internal calls or logs?

No. The routes cover address summaries, transactions, token balances and transfers, and token metadata. Decoded logs and internal calls are not read.

#### Does it return historical balances?

No, balances are current. Transaction history is historical and each row carries its own `timestamp`, so you can reconstruct a balance over time from the transfers.

#### Do I need a block explorers API key?

No. You need an Apify token to call the Actor over the API. No block explorers credential is involved anywhere.

#### Can I get this data in Python?

Yes, with the `apify-client` package as shown above. It returns parsed JSON, so there is no HTML or response handling on your side.

#### Can I get the data into Excel or Google Sheets?

Yes. Export the dataset as XLSX or CSV, or connect the Google Sheets integration so each run appends to a sheet.

#### Can an AI agent call this Actor?

Yes. Add it to an MCP client with the config above and the model can request what it needs on its own. Every record is flat JSON with named fields, so no post-processing is needed.

#### Is it legal to scrape block explorers?

Blockchain data is public by design and this Actor reads public explorers, so there is nothing gated here. Addresses are pseudonymous rather than anonymous, so if you link one to a named person you are handling personal data and your own privacy obligations apply. Take your own legal advice for your use case.

### Changelog

- **0.0.2** Added the token metadata route, ENS resolution and USD valuation of token balances.
- **0.0.1** First release. Address, transaction and token routes across nine chains.

### Feedback

Found a field block explorers publishes that this Actor misses, or an input it rejects? Open an issue on the Issues tab with the input and what you expected. A daily test runs every Actor in the fleet against live sources, so parser fixes ship fast.

# Actor input Schema

## `chain` (type: `string`):

Which chain to read. The field names in the output are the same on every chain, so switching this does not change your parsing code. Addresses must be in the chosen chain's own format, so an Ethereum address on Bitcoin will fail. Examples: 'ethereum', 'base', 'bitcoin', 'solana'. Default is 'ethereum'.

## `route` (type: `string`):

What each record represents. Address returns one balance summary per address; transactions returns the transfer history; tokenBalances and tokenTransfers cover token activity; token returns contract metadata. Examples: 'address', 'transactions', 'tokenBalances'. Default is 'address'.

## `addresses` (type: `array`):

Addresses to read, one per line, in the chosen chain's own format. EVM chains use 0x addresses, Bitcoin and Solana use their own. ENS names are resolved into the output where the chain supports them. Examples: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'.

## `maxItemsPerAddress` (type: `integer`):

Caps how many rows a single address can contribute on the transaction and token routes, newest first. It exists so one busy treasury with a hundred thousand transfers cannot consume the whole run. Examples: 20, 100, 1000. Default is 100.

## `maxItems` (type: `integer`):

Maximum number of addresses to read, counted from the top of the list. Use it to cap spend on a long list without editing the list itself. Examples: 10, 50, 200. Default is 0, which reads every address given.

## Actor input object example

```json
{
  "chain": "ethereum",
  "route": "address",
  "addresses": [
    "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
  ],
  "maxItemsPerAddress": 100,
  "maxItems": 0
}
```

# Actor output Schema

## `results` (type: `string`):

One item per address, transaction, holding or transfer read by the run, in the default dataset.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "chain": "ethereum",
    "route": "address",
    "addresses": [
        "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
    ],
    "maxItemsPerAddress": 100,
    "maxItems": 0
};

// Run the Actor and wait for it to finish
const run = await client.actor("publicmoney/blockchain-scanner-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "chain": "ethereum",
    "route": "address",
    "addresses": ["0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"],
    "maxItemsPerAddress": 100,
    "maxItems": 0,
}

# Run the Actor and wait for it to finish
run = client.actor("publicmoney/blockchain-scanner-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "chain": "ethereum",
  "route": "address",
  "addresses": [
    "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
  ],
  "maxItemsPerAddress": 100,
  "maxItems": 0
}' |
apify call publicmoney/blockchain-scanner-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,publicmoney/blockchain-scanner-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/eDjWNG4vWZHA8sINw/builds/iREh4bO27FUNyKWG0/openapi.json
