A way to access the etherscan.io api using promises. Fetch a diverse set of information about the blockchain.
Written in TypeScript, shipped as an ES module with bundled type declarations. Requires Node.js >= 22.
Mainnet
import { init } from 'etherscan-api';
const api = init('YourApiKey');
const balance = await api.account.balance('0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae');
console.log(balance);This library has no runtime dependencies — requests use Node's built-in
https module. If you need custom networking (a proxy, retries, a different
agent), pass your own transport as the 4th argument to init. It receives the
fully-qualified URL and must resolve with the parsed JSON body:
import { init } from 'etherscan-api';
// (url, { timeout, method, body }) => Promise<object>
// `method`/`body` are only set for the POST contract-verification endpoints;
// for read-only use you can ignore them.
async function request(url, { timeout, method = 'GET', body }) {
const res = await fetch(url, {
method,
body,
headers: body ? { 'Content-Type': 'application/x-www-form-urlencoded' } : undefined,
signal: AbortSignal.timeout(timeout),
});
// fetch resolves on any HTTP status; surface non-2xx as an error.
if (!res.ok) throw new Error(`Request failed with status code ${res.status}`);
return res.json();
}
const api = init('apikey', null, 10000, request);- The API key travels in the request URL on GET requests. Etherscan requires
apikeyas a query parameter, so it is part of every GET request URL. Treat full request URLs as secrets: do not log them, and be careful with proxies, APM tools, and access logs that capture URLs. A custom transport receives the URL containing the key — never write it to logs verbatim. (The library itself never puts the URL or key into thrown errors.) The POST contract-verification endpoints are the exception: there the key is sent in the form body and the URL is a bare/v2/api. - The default transport refuses cleartext
http://. Requests go tohttps://api.etherscan.ioover TLS with certificate validation on. If a request somehow targets anhttp://URL, the default transport rejects rather than sending the key unencrypted; pass{ allowInsecure: true }in the transport options only if you deliberately need cleartext (e.g. a local test server). - The default transport caps the response body at 50 MB to guard against a
memory-exhaustion response. Override with
maxResponseBytesin the transport options if you expect larger payloads.
The library passes the transport only timeout (plus method and body for
the POST verification endpoints), so allowInsecure and maxResponseBytes are
set by wrapping the default transport, which is exported as httpTransport:
import { init, httpTransport } from 'etherscan-api';
const api = init('apikey', 'mainnet', 10000, (url, options) =>
httpTransport(url, { ...options, maxResponseBytes: 200 * 1024 * 1024 }));Etherscan deprecated the V1 API on 2025-08-15. This library now talks to a
single base URL — https://api.etherscan.io/v2/api — and selects the network
with a chainid query parameter. One API key works across all chains.
Pass a chain name (or a numeric chainid) as the second argument to init:
import { init } from 'etherscan-api';
// apikey, chain, timeout
const api = init('YourApiKey', 'sepolia', 3000);Supported chain names:
| Name | chainid |
|---|---|
mainnet / homestead / ethereum |
1 |
sepolia |
11155111 |
hoodi |
560048 |
arbitrum |
42161 |
optimism |
10 |
base |
8453 |
polygon |
137 |
bsc |
56 |
avalanche |
43114 |
avalanche_fuji |
43113 |
Any other chain is reachable by passing its numeric chainid directly, e.g.
init('YourApiKey', 59144) for Linea.
Retired testnets (ropsten, rinkeby, kovan, goerli, holesky, morden,
arbitrum_rinkeby) have been removed and now throw an
error with a helpful message — use sepolia or hoodi instead.
npm install etherscan-api --saveFull Api Docs, including a short tutorial (also covering use from CommonJS) and examples.
Source lives in ./src (TypeScript) and compiles to ./lib (ES modules + .d.ts).
npm run build- compilessrc→libwithtscnpm run typecheck- type-checks without emitting (replaces the old linter)npm test- builds, then runs the fully mocked test suite (no API key required)npm run docs- generates the API docs with TypeDocnpm run preversion- runs the full test suite (build + type-check + tests) beforenpm versiontags a release
Release notes are generated when a v* tag is pushed: the release workflow
lists the commits since the previous tag as the body of the GitHub release.
This library is maintained in my spare time. If your company relies on it, consider sponsoring — it directly funds maintenance and new features. Sponsors at $50/month or more get their logo placed here.
No sponsors yet — be the first