glassnode-api
v0.7.7
Published
Typescript client for the Glassnode API (Node.js and Browser)
Maintainers
Readme
Glassnode API — TypeScript Client
A fully-typed TypeScript client for the Glassnode API — on-chain and market data for Bitcoin, Ethereum, and hundreds of crypto assets. Responses are runtime-validated with Zod, and it runs in both Node.js and the browser.
import { GlassnodeAPI } from 'glassnode-api';
const api = new GlassnodeAPI({ apiKey: 'YOUR_API_KEY' });
const btcPrice = await api.callMetric('/market/price_usd_close', { a: 'BTC' });Features
- 🧩 Fully typed — complete TypeScript definitions for every request and response
- ✅ Runtime-validated — responses parsed and validated with Zod, so bad data fails fast
- 🌐 Universal — works in Node.js and the browser (UMD + ESM bundles, tree-shakeable)
- 🔁 Built-in retries — automatic retry with exponential backoff for
429and5xx - 📦 Bulk endpoints — fetch every asset in a single call with
callBulkMetric() - 🎯 Typed errors —
GlassnodeApiErrorwithstatus,statusText, andisRetryable - 🪶 Lightweight — a single runtime dependency (
zod) - 🔌 Pluggable — inject a custom
fetchimplementation and alogger
Table of Contents
- Installation
- Quick Start
- Configuration
- Methods
- Error Handling
- Retries
- Bulk Metrics
- Browser
- Examples
- Development
- License
Installation
# pnpm
pnpm add glassnode-api
# npm
npm install glassnode-api
# yarn
yarn add glassnode-apiYou'll need a Glassnode API key — create one from your Glassnode account.
Quick Start
import { GlassnodeAPI } from 'glassnode-api';
const api = new GlassnodeAPI({
apiKey: 'YOUR_API_KEY',
// apiUrl: 'https://api.glassnode.com', // optional override
});
// Fetch metadata for all supported assets
const assets = await api.getAssetMetadata();
// Fetch metadata for a specific metric
const metric = await api.getMetricMetadata('/distribution/balance_exchanges', { a: 'BTC' });
// List every available metric path
const metrics = await api.getMetricList();
// Call any metric endpoint directly
const data = await api.callMetric('/market/price_usd_close', {
a: 'BTC',
s: '1609459200', // since (unix timestamp)
});Configuration
new GlassnodeAPI(config)
| Option | Type | Default | Description |
| ------------ | ----------------------------------------------- | --------------------------- | ------------------------------------------------------- |
| apiKey | string | — (required) | Your Glassnode API key |
| apiUrl | string | https://api.glassnode.com | Base URL for the API |
| logger | (message: string, ...args: unknown[]) => void | — | Callback for debug logging (e.g. console.log) |
| fetch | typeof fetch | globalThis.fetch | Custom fetch implementation (custom headers, testing…) |
| maxRetries | number | 0 | Retries for retryable errors (429, 5xx) |
| retryDelay | number | 1000 | Base delay in ms between retries (doubles each attempt) |
The config is validated at construction time with Zod — an invalid config (e.g. an empty apiKey) throws immediately.
Methods
| Method | Returns | Description |
| ---------------------------------- | --------------------------------- | ------------------------------------------------- |
| getAssetMetadata() | Promise<AssetMetadataResponse> | Metadata for all supported assets |
| getMetricMetadata(path, params?) | Promise<MetricMetadataResponse> | Metadata for a specific metric |
| getMetricList() | Promise<MetricListResponse> | List of all available metric paths |
| callMetric<T>(path, params?) | Promise<T> | Call any metric endpoint directly |
| callBulkMetric(path, params?) | Promise<BulkResponse> | Call a bulk endpoint (all assets in one response) |
All response types are exported and fully typed.
Error Handling
Failed requests throw a GlassnodeApiError with the HTTP status, the status text, and a human-readable
message. Network failures are re-thrown as an Error with the original error preserved on .cause.
import { GlassnodeAPI, GlassnodeApiError } from 'glassnode-api';
try {
await api.callMetric('/market/price_usd_close', { a: 'BTC' });
} catch (err) {
if (err instanceof GlassnodeApiError) {
console.error(err.status); // e.g. 401
console.error(err.statusText); // e.g. "Unauthorized"
console.error(err.isRetryable); // true for 429 / 5xx
console.error(err.message); // "API request failed (401): Invalid or missing API key"
}
}Retries
Enable automatic retries with exponential backoff for rate limits (429) and server errors (5xx):
const api = new GlassnodeAPI({
apiKey: 'YOUR_API_KEY',
maxRetries: 3, // retry up to 3 times
retryDelay: 1000, // 1s, then 2s, then 4s
});Non-retryable errors (e.g. 401, 404) fail immediately without retrying.
Bulk Metrics
callBulkMetric() returns a value for every asset at each timestamp in a single request — ideal for
snapshots across the whole market:
const marketcaps = await api.callBulkMetric('/market/marketcap_usd');
// [{ t: 1609459200, bulk: [{ a: 'BTC', v: 600000000000 }, { a: 'ETH', v: 100000000000 }] }]Browser
The library ships prebuilt UMD and ESM bundles, so it also runs directly in the browser without a build step.
<!-- UMD -->
<script src="https://unpkg.com/glassnode-api/dist/glassnode-api.umd.min.js"></script>
<script>
const api = new GlassnodeAPI.GlassnodeAPI({ apiKey: 'YOUR_API_KEY' });
</script><!-- ESM -->
<script type="module">
import { GlassnodeAPI } from 'https://unpkg.com/glassnode-api/dist/glassnode-api.esm.min.js';
const api = new GlassnodeAPI({ apiKey: 'YOUR_API_KEY' });
</script>Your API key is exposed to end users in browser code. Only ship it in trusted, first-party contexts — otherwise proxy Glassnode requests through your own backend.
Examples
See the examples directory for detailed usage patterns.
cd examples
cp .env.example .env # add your API key
pnpm dlx ts-node metadata.validation.tsDevelopment
pnpm install # install dependencies
pnpm run build && pnpm run build:browser # build Node.js + browser bundles
pnpm test # run tests (Vitest)
pnpm run lint # lint
pnpm run format # format