PHPackages                             tigusigalpa/glassnode-php - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. tigusigalpa/glassnode-php

ActiveLibrary[API Development](/categories/api)

tigusigalpa/glassnode-php
=========================

Framework-agnostic PHP SDK for the Glassnode Basic API with a first-class Laravel bridge.

v1.0.0(today)00MITPHPPHP &gt;=8.1CI failing

Since Jul 30Pushed today1 watchersCompare

[ Source](https://github.com/tigusigalpa/glassnode-php)[ Packagist](https://packagist.org/packages/tigusigalpa/glassnode-php)[ RSS](/packages/tigusigalpa-glassnode-php/feed)WikiDiscussions main Synced today

READMEChangelog (1)Dependencies (6)Versions (2)Used By (0)

glassnode-php
=============

[](#glassnode-php)

[![GlassNode PHP/Laravel SDK](https://camo.githubusercontent.com/f88fb3cd8c1dba518c6972b8a7f5869d76cd099de9e7f4147053d1317a6aa1cd/68747470733a2f2f692e706f7374696d672e63632f634a6a46564450422f676c6173736e6f64652d7068702d6769746875622e6a7067)](https://camo.githubusercontent.com/f88fb3cd8c1dba518c6972b8a7f5869d76cd099de9e7f4147053d1317a6aa1cd/68747470733a2f2f692e706f7374696d672e63632f634a6a46564450422f676c6173736e6f64652d7068702d6769746875622e6a7067)

[![PHP Version](https://camo.githubusercontent.com/1f28f2b4faa0e0f1224d8870dbbc65deeea67e3391cd0be5ca39bb23feddf1cc/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e312b2d3737374242343f6c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://www.php.net/)[![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667)](LICENSE)![Tests](https://camo.githubusercontent.com/d940ad7f0752e2cbe0d63c50dcebf329078807390051c41fe63258f1b5c4e182/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f74657374732d70617373696e672d627269676874677265656e)[![Laravel](https://camo.githubusercontent.com/5ed5d963280b1293ea5c652a3c7d787f7d60559610113a3acb4e09ad848ccfef/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31302532302537432532303131253230253743253230313225323025374325323031332d4646324432303f6c6f676f3d6c61726176656c266c6f676f436f6c6f723d7768697465)](https://laravel.com/)

> **Unofficial** PHP SDK for the [Glassnode Basic API](https://docs.glassnode.com/basic-api/). Not affiliated with or endorsed by Glassnode.

A framework-agnostic, production-oriented PHP library for the Glassnode Basic API with a first-class Laravel bridge.

If you've ever tried to pull on-chain metrics from Glassnode in a PHP project, you know the drill: hand-rolling cURL requests, manually constructing query strings, decoding JSON, and wrapping everything in try-catch blocks just to get a clean error message. This SDK takes care of all that — and goes further by making the **entire documented metric surface** discoverable and safely consumable through three layers of API:

1. **Transport/config** — `GlassnodeClient` with cURL or PSR-18 transport, immutable config, automatic retries, and rate-limit awareness
2. **Metadata/generic** — `MetadataResource` for runtime discovery, `GlassnodeClient::get()` for any metric path (present or future)
3. **Ergonomic category resources** — 25 typed resource classes with convenience methods that map 1:1 to Glassnode's endpoint categories

The result? You write less boilerplate, catch errors earlier, and spend more time analyzing data instead of wrestling with HTTP plumbing.

Why This SDK?
-------------

[](#why-this-sdk)

- **Stop hand-writing HTTP calls** — every endpoint is a method call away with proper parameter handling
- **Discover metrics at runtime** — not sure which parameters a metric accepts? Ask the metadata API
- **Survive rate limits gracefully** — automatic retry on 429 with server-aware backoff
- **Stay framework-agnostic** — works in plain PHP, Laravel, Symfony, or anything else
- **Keep your API key safe** — header-based auth by default, never leaked in URLs or logs
- **Only pay for what you use** — bulk endpoints with explicit asset lists so you control credit consumption

Features
--------

[](#features)

- **Framework-agnostic** — works in any PHP 8.1+ project, no framework required
- **First-class Laravel bridge** — service provider, facade, config publishing, auto-discovery
- **25 category resources** with typed convenience methods covering every documented endpoint category
- **Generic metric API** for every valid metric path — present or future, even ones not yet wrapped
- **Metadata-first** — discover assets, metric paths, and parameter capabilities at runtime before making data calls
- **Bulk endpoint support** with repeated query parameters for multi-asset requests
- **Point-in-Time metrics** with `computed_at` timestamp preservation for historically accurate analysis
- **Header authentication** (`X-Api-Key`) by default; query-string opt-in for environments that need it
- **Automatic retry** on HTTP 429 with `x-rate-limit-reset` support and exponential backoff
- **Rich exception hierarchy** — `BadRequestException`, `UnauthorizedException`, `NotFoundException`, `RateLimitException`, and more, each carrying context about what went wrong
- **PSR-18 compatible** — use any PSR-18 HTTP client (Guzzle, Symfony HTTP Client, etc.), or the built-in zero-dependency cURL transport
- **Immutable configuration** — once created, config objects can't be accidentally mutated mid-request
- **No network requests at boot time** — Laravel-safe, won't slow down your app startup

Installation
------------

[](#installation)

```
composer require tigusigalpa/glassnode-php
```

That's it. The package has no hard dependencies beyond `ext-curl` and `ext-json` (both enabled by default in virtually every PHP installation). If you're using Laravel, the service provider and facade are auto-discovered — no manual registration needed.

### Laravel Setup

[](#laravel-setup)

The package auto-discovers the service provider and facade via Laravel's package discovery. Publish the config file to customize defaults:

```
php artisan vendor:publish --tag=glassnode-config
```

This creates `config/glassnode.php` in your project. Then set your API key in `.env`:

```
GLASSNODE_API_KEY=your-api-key-here
```

The published config file lets you override the base URL, timeout, retry settings, auth mode, and more — all in one place.

### Plain PHP Setup

[](#plain-php-setup)

No framework? No problem. Just instantiate the client directly:

```
use Tigusigalpa\Glassnode\GlassnodeClient;
use Tigusigalpa\Glassnode\GlassnodeConfig;

$config = new GlassnodeConfig(apiKey: 'your-api-key');
$client = new GlassnodeClient($config);
```

Or load from environment variables (`GLASSNODE_API_KEY`, `GLASSNODE_TIMEOUT`, etc.):

```
$config = GlassnodeConfig::fromEnv();
$client = new GlassnodeClient($config);
```

Quick Start
-----------

[](#quick-start)

### Standalone PHP

[](#standalone-php)

Here's a complete example — fetch BTC price data and print it:

```
use Tigusigalpa\Glassnode\GlassnodeClient;
use Tigusigalpa\Glassnode\GlassnodeConfig;

$client = new GlassnodeClient(new GlassnodeConfig(
    apiKey: 'YOUR_API_KEY',
    timeout: 15.0,
    retryAttempts: 3,
));

// Fetch BTC price with 24h resolution
$price = $client->market->price(['a' => 'BTC', 'i' => '24h']);
foreach ($price as $point) {
    printf("BTC price at %d: $%.2f\n", $point['t'], $point['v']);
}
```

Want to explore what's available before pulling data? Use the metadata API:

```
// List all supported assets
$assets = $client->metadata->assets();
foreach ($assets as $asset) {
    printf("%s (%s)\n", $asset['name'], $asset['symbol']);
}

// Inspect a specific metric's parameters
$metricInfo = $client->metadata->metric('/market/price_usd');
print_r($metricInfo);
```

### Laravel

[](#laravel)

In Laravel, you can use the facade for quick access:

```
use Tigusigalpa\Glassnode\Laravel\Facades\Glassnode;

// Fetch metrics with a clean, expressive syntax
$price = Glassnode::market()->price(['a' => 'BTC', 'i' => '24h']);
$sopr = Glassnode::indicators()->sopr(['a' => 'BTC']);
$assets = Glassnode::metadata()->assets();
```

Or via dependency injection (recommended for controllers and services):

```
use Tigusigalpa\Glassnode\GlassnodeClient;

class DashboardController extends Controller
{
    public function index(GlassnodeClient $client)
    {
        $price = $client->market->price(['a' => 'BTC']);
        $activeAddresses = $client->addresses->activeCount(['a' => 'BTC']);

        return view('dashboard', [
            'price' => $price,
            'activeAddresses' => $activeAddresses,
        ]);
    }
}
```

### Common Use Cases

[](#common-use-cases)

**Building a market dashboard:**

```
// Get OHLC candles for charting
$ohlc = $client->market->priceOhlc(['a' => 'BTC', 'i' => '1h']);

// Market cap and realized cap for valuation analysis
$mcap = $client->market->marketCap(['a' => 'BTC']);
$rcap = $client->market->realizedCap(['a' => 'BTC']);

// MVRV ratio — a classic cycle indicator
$mvrv = $client->indicators->mvrv(['a' => 'BTC']);
```

**Monitoring network health:**

```
// Active addresses — measures network usage
$active = $client->addresses->activeCount(['a' => 'BTC', 'i' => '24h']);

// Hash rate — mining security
$hashrate = $client->mining->hashRateMean(['a' => 'BTC']);

// Total supply — track inflation
$supply = $client->supply->current(['a' => 'BTC']);
```

API Key Security
----------------

[](#api-key-security)

Your Glassnode API key is the gateway to your account and its data credits. Treat it like a password.

- **Never hardcode** your API key in source code, commit it to version control, or expose it in client-side code
- Use `GlassnodeConfig::fromEnv()` in plain PHP or Laravel's `env('GLASSNODE_API_KEY')` to load from environment variables
- The SDK uses **header mode** (`X-Api-Key`) by default — your key is sent in an HTTP header and never appears in URLs, query strings, or server access logs
- **Query-string mode** (`api_key` parameter) is available as an opt-in for environments where headers aren't supported, but it's less secure — the key may be visible in proxy logs, browser history, or referrer headers
- If you accidentally expose a key, rotate it immediately in [Glassnode Studio settings](https://studio.glassnode.com/settings/api)

Authentication Modes
--------------------

[](#authentication-modes)

The SDK supports two authentication modes. Header mode is the default and recommended for all production usage:

```
// Header mode (default, recommended)
// Sends the key as an X-Api-Key header — invisible in URLs and logs
new GlassnodeConfig(apiKey: 'key')

// Query-string mode (opt-in, less secure)
// Appends ?api_key=... to every request URL
new GlassnodeConfig(apiKey: 'key', authMode: GlassnodeConfig::AUTH_MODE_QUERY)
```

Configuration
-------------

[](#configuration)

The `GlassnodeConfig` object is immutable — once created, its values can't change. This prevents accidental mutation mid-request in long-running processes.

All configuration options with their defaults:

```
$config = new GlassnodeConfig(
    apiKey: 'YOUR_API_KEY',        // Required — your Glassnode API key
    baseUrl: 'https://api.glassnode.com',  // API base URL (rarely needs changing)
    timeout: 15.0,                 // HTTP timeout in seconds
    retryAttempts: 3,             // Max retries on HTTP 429
    retryDelay: 1.0,              // Base delay in seconds for exponential backoff
    authMode: 'header',           // 'header' (default) or 'query'
    userAgent: 'glassnode-php/1.0', // User-Agent header sent with each request
    appId: null,                  // Optional app identifier for Glassnode analytics
);
```

### Creating Config from Different Sources

[](#creating-config-from-different-sources)

From an array (great for loading from a config file):

```
$config = GlassnodeConfig::fromArray([
    'api_key' => 'YOUR_API_KEY',
    'timeout' => 15.0,
    'retry_attempts' => 3,
]);
```

From environment variables (reads `GLASSNODE_API_KEY`, `GLASSNODE_TIMEOUT`, etc.):

```
$config = GlassnodeConfig::fromEnv();
```

In Laravel, the published `config/glassnode.php` file handles all of this for you — just set the values in `.env` and the service provider wires everything up automatically.

Category Resources
------------------

[](#category-resources)

ResourceClient PropertyLaravel FacadeDocumentationAddresses`$client->addresses``Glassnode::addresses()`[Addresses](https://docs.glassnode.com/basic-api/endpoints/addresses)Bridges`$client->bridges``Glassnode::bridges()`[Bridges](https://docs.glassnode.com/basic-api/endpoints/bridges)Blockchain`$client->blockchain``Glassnode::blockchain()`[Blockchain](https://docs.glassnode.com/basic-api/endpoints/blockchain)Breakdowns`$client->breakdowns``Glassnode::breakdowns()`[Breakdowns](https://docs.glassnode.com/basic-api/endpoints/breakdowns)DeFi`$client->defi``Glassnode::defi()`[DeFi](https://docs.glassnode.com/basic-api/endpoints/defi)Derivatives`$client->derivatives``Glassnode::derivatives()`[Derivatives](https://docs.glassnode.com/basic-api/endpoints/derivatives)Distribution`$client->distribution``Glassnode::distribution()`[Distribution](https://docs.glassnode.com/basic-api/endpoints/distribution)Entities`$client->entities``Glassnode::entities()`[Entities](https://docs.glassnode.com/basic-api/endpoints/entities)ETH 2.0`$client->eth2``Glassnode::eth2()`[ETH 2.0](https://docs.glassnode.com/basic-api/endpoints/eth2)Fees`$client->fees``Glassnode::fees()`[Fees](https://docs.glassnode.com/basic-api/endpoints/fees)Global`$client->global``Glassnode::global()`[Global](https://docs.glassnode.com/basic-api/endpoints/global)Indicators`$client->indicators``Glassnode::indicators()`[Indicators](https://docs.glassnode.com/basic-api/endpoints/indicators)Institutions`$client->institutions``Glassnode::institutions()`[Institutions](https://docs.glassnode.com/basic-api/endpoints/institutions)Lightning`$client->lightning``Glassnode::lightning()`[Lightning](https://docs.glassnode.com/basic-api/endpoints/lightning)Macro`$client->macro``Glassnode::macro()`[Macro](https://docs.glassnode.com/basic-api/endpoints/macro)Market`$client->market``Glassnode::market()`[Market](https://docs.glassnode.com/basic-api/endpoints/market)Mempool`$client->mempool``Glassnode::mempool()`[Mempool](https://docs.glassnode.com/basic-api/endpoints/mempool)Mining`$client->mining``Glassnode::mining()`[Mining](https://docs.glassnode.com/basic-api/endpoints/mining)Options`$client->options``Glassnode::options()`[Options](https://docs.glassnode.com/basic-api/endpoints/options)Point-In-Time`$client->pointInTime``Glassnode::pointInTime()`[PIT](https://docs.glassnode.com/basic-api/endpoints/pit)Protocols`$client->protocols``Glassnode::protocols()`[Protocols](https://docs.glassnode.com/basic-api/endpoints/protocols)Signals`$client->signals``Glassnode::signals()`[Signals](https://docs.glassnode.com/basic-api/endpoints/signals)Supply`$client->supply``Glassnode::supply()`[Supply](https://docs.glassnode.com/basic-api/endpoints/supply)Transactions`$client->transactions``Glassnode::transactions()`[Transactions](https://docs.glassnode.com/basic-api/endpoints/transactions)Treasuries`$client->treasuries``Glassnode::treasuries()`[Treasuries](https://docs.glassnode.com/basic-api/endpoints/treasuries)**Full endpoint coverage:** [docs/endpoint-coverage.md](docs/endpoint-coverage.md)

Generic Metric API
------------------

[](#generic-metric-api)

The 25 category resources cover every documented endpoint category, but Glassnode occasionally adds new metrics before a typed wrapper exists. The generic API ensures you're never blocked — it works with **any** valid metric path, present or future:

```
// Raw decoded JSON — works with any metric path
$data = $client->get('/v1/metrics/addresses/sending_count', ['a' => 'BTC']);

// Full parameter set: asset, resolution, time range
$data = $client->get('/v1/metrics/market/price_ohlc', [
    'a' => 'BTC',      // Asset
    'i' => '24h',      // Resolution: 10m, 1h, 24h, 1w, 1month
    's' => 1609459200, // Since (Unix timestamp)
    'u' => 1609545600, // Until (Unix timestamp)
    'c' => 'USD',      // Currency (for market metrics)
    'f' => 'Json',     // Format: Json, CSV
]);
```

### Common Query Parameters

[](#common-query-parameters)

ParameterDescriptionExample`a`Asset symbol`'BTC'`, `'ETH'``i`Resolution interval`'10m'`, `'1h'`, `'24h'`, `'1w'`, `'1month'``s`Since (Unix timestamp)`1609459200``u`Until (Unix timestamp)`1609545600``c`Currency (market metrics)`'USD'`, `'EUR'``f`Response format`'Json'`, `'CSV'``timestamp_format`Timestamp format`'unix'`, `'humanized'`, `'humanized-30d'`Use `metadata/metric` to discover which parameters a specific metric accepts.

Bulk Metrics
------------

[](#bulk-metrics)

Bulk endpoints let you fetch data for multiple assets in a single request, saving on rate limits. However, **credits are still consumed per asset** — so a bulk call for 5 assets costs the same as 5 individual calls.

```
// Fetch MVRV for BTC and ETH in one call
$resp = $client->get('/v1/metrics/market/mvrv/bulk', [
    'a' => ['BTC', 'ETH'],   // Multiple assets as an array
    's' => strtotime('-7 days'),
    'i' => '24h',
]);
```

### Bulk Best Practices

[](#bulk-best-practices)

- **Always specify assets explicitly** — never use wildcards, as this can consume unexpected credits
- **Check `bulk_supported`** via `metadata/metric` before calling bulk endpoints — not all metrics support it
- **Batch in reasonable sizes** — 5–10 assets per call is a good balance between throughput and credit visibility
- **Monitor your credit usage** with `$client->user->apiUsage()` to catch unexpected consumption early

Error Handling
--------------

[](#error-handling)

The SDK throws a rich hierarchy of exceptions, so you can catch exactly the errors you care about without parsing error messages or HTTP status codes yourself:

```
use Tigusigalpa\Glassnode\Exceptions\BadRequestException;
use Tigusigalpa\Glassnode\Exceptions\UnauthorizedException;
use Tigusigalpa\Glassnode\Exceptions\NotFoundException;
use Tigusigalpa\Glassnode\Exceptions\RateLimitException;
use Tigusigalpa\Glassnode\Exceptions\GlassnodeException;

try {
    $data = $client->indicators->sopr(['a' => 'BTC']);
} catch (UnauthorizedException $e) {
    // 401 — API key is missing, invalid, or expired
    echo "Invalid API key — check your configuration\n";
} catch (RateLimitException $e) {
    // 429 — you've hit the rate limit (after all retries are exhausted)
    printf("Rate limited. Reset in %s seconds.\n", $e->rateLimitReset ?? 'unknown');
} catch (BadRequestException $e) {
    // 400 — invalid parameters, unsupported asset, etc.
    printf("Bad request: %s\n", $e->getMessage());
} catch (NotFoundException $e) {
    // 404 — the metric path doesn't exist
    echo "Metric not found — check the path with metadata/metric\n";
} catch (GlassnodeException $e) {
    // Catch-all for any other SDK error (network issues, transport errors, etc.)
    printf("Unexpected error: %s\n", $e->getMessage());
}
```

### Exception Hierarchy

[](#exception-hierarchy)

All exceptions extend `GlassnodeException`, so you can catch everything with a single `catch` block if you prefer:

```
GlassnodeException (base)
├── BadRequestException        (HTTP 400)
├── UnauthorizedException      (HTTP 401)
├── NotFoundException          (HTTP 404)
├── RateLimitException         (HTTP 429, after retries)
├── ConfigurationException     (invalid config)
└── TransportException         (network/HTTP errors)

```

Each exception carries the HTTP status code, response body, and (for `RateLimitException`) the `rateLimitReset` value from the `x-rate-limit-reset` header.

PSR-18 HTTP Client Support
--------------------------

[](#psr-18-http-client-support)

The SDK ships with a zero-dependency cURL transport that works out of the box. But if you're already using Guzzle, Symfony HTTP Client, or any other PSR-18 compatible client in your project, you can plug it in directly — no need for a second HTTP dependency:

```
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\HttpFactory;

$client = new GlassnodeClient(
    config: $config,
    psrClient: new Client(),       // Any PSR-18 ClientInterface
    requestFactory: new HttpFactory(),  // PSR-17 RequestFactoryInterface
    streamFactory: new HttpFactory(),   // PSR-17 StreamFactoryInterface
);
```

This is particularly useful in Symfony projects (which ship with their own HTTP client) or in projects where you need custom middleware like request logging, circuit breakers, or proxy configuration.

Retry Behavior
--------------

[](#retry-behavior)

Nobody likes getting rate-limited. The SDK handles 429 responses automatically so you don't have to wrap every call in retry logic:

- **Retries only `GET` requests** on HTTP 429 — non-idempotent methods are never retried
- **Honors `x-rate-limit-reset`** header when present — waits exactly as long as the server tells us
- **Falls back to exponential backoff** when the header is absent: `retryDelay * 2^attempt`
- **Never retries** 400, 401, or 404 — these are client errors that won't resolve by retrying
- **Configurable** via `retryAttempts` (default: 3) and `retryDelay` (default: 1.0s)

If all retry attempts are exhausted, a `RateLimitException` is thrown with the `rateLimitReset` value (if available) so your application can decide how to handle it — queue the request, alert the user, or back off further.

Rate Limits
-----------

[](#rate-limits)

Rate limits are governed by Glassnode's servers and depend on your subscription tier. The API returns these headers on every response, so you can monitor your usage proactively:

HeaderDescription`x-rate-limit-limit`Total request limit per minute (e.g. 600 for standard tier)`x-rate-limit-remaining`Requests remaining in the current window`x-rate-limit-reset`Seconds until the limit resetsMetadata endpoints are separately limited to 1200 req/min, so you can discover metrics freely without worrying about impacting your data request budget.

### Tips for Staying Within Limits

[](#tips-for-staying-within-limits)

- Cache metadata responses — assets and metric definitions rarely change
- Use appropriate resolutions — don't fetch 10-minute data when you only need daily aggregates
- Batch with bulk endpoints where supported — one HTTP call instead of many
- Monitor `x-rate-limit-remaining` and back off before hitting zero

Data Credits
------------

[](#data-credits)

Glassnode charges data credits per request, not per data point. Understanding the credit model helps you avoid surprises:

- **BTC**: 1 credit per request
- **All other assets**: 2 credits per request
- **Bulk endpoints**: credits = sum of individual calls (e.g., 5 assets = 5× credits)
- **Monitor usage** via `$client->user->apiUsage()` or [Studio settings](https://studio.glassnode.com/settings/api)

If you're building a dashboard that pulls many metrics, consider caching results and refreshing on a schedule rather than polling continuously.

Testing
-------

[](#testing)

The test suite uses mocked HTTP transports — no API key or live requests are required, so you can run the full suite anywhere:

```
composer install
vendor/bin/phpunit
```

For verbose output with test names:

```
vendor/bin/phpunit --testdox
```

The suite includes 41 tests (37 unit + 4 feature) covering all resources, error handling, retry logic, configuration, and the Laravel bridge.

Examples
--------

[](#examples)

The `examples/` directory contains ready-to-run scripts you can adapt for your own projects:

- [Basic usage](examples/basic.php) — price, indicators, assets, API usage
- [Laravel](examples/laravel.php) — facade and dependency injection in a controller
- [Error handling](examples/error_handling.php) — exception types and recovery strategies

Compatibility
-------------

[](#compatibility)

- **PHP 8.1+** (uses named arguments, readonly properties, enums)
- **Laravel 10, 11, 12, 13** (auto-discovery, facade, config publishing)
- **ext-curl** and **ext-json** required (both enabled by default in standard PHP)
- **PSR-18 client** optional (for custom HTTP transports like Guzzle or Symfony HTTP Client)

FAQ
---

[](#faq)

**Do I need a Glassnode account to use this SDK?**Yes. You need a Glassnode account with an API key. Sign up at [studio.glassnode.com](https://studio.glassnode.com/) — there's a free tier with limited credits to get started.

**Is this an official Glassnode product?**No. This is an unofficial, community-built SDK. It's not affiliated with or endorsed by Glassnode. The official API documentation is at [docs.glassnode.com](https://docs.glassnode.com/).

**Does the SDK work without Laravel?**Absolutely. The core library is framework-agnostic. The Laravel bridge is an optional layer on top — if you're using plain PHP, Symfony, or any other framework, just instantiate `GlassnodeClient` directly.

**What happens when Glassnode adds new metrics?**The generic API (`$client->get()`) works with any valid metric path, so you can use new metrics immediately even before a typed wrapper is added. Check `metadata/metrics` to discover new paths at runtime.

**Can I use this in a long-running process (queue worker, daemon)?**Yes. The `GlassnodeConfig` is immutable, and the `GlassnodeClient` is safe to reuse across requests. The cURL transport creates fresh handles per request, so there's no state leakage between calls.

**How do I get CSV format instead of JSON?**Pass `'f' => 'CSV'` in the query parameters. The SDK returns the raw CSV string as-is. JSON (the default) is automatically decoded into PHP arrays.

Contributing
------------

[](#contributing)

Contributions are welcome! Whether it's a bug fix, a new example, improved documentation, or a feature — here's how to get started:

1. **Fork** the repository and create your branch from `main`
2. **Run tests** to make sure everything passes before you start: `vendor/bin/phpunit`
3. **Make your changes** — keep code style consistent with the existing codebase
4. **Add tests** for any new functionality — all tests must pass with mocked transports (no live API calls)
5. **Submit a pull request** with a clear description of what and why

### Reporting Issues

[](#reporting-issues)

Found a bug or have a feature request? Please open an issue on GitHub with:

- A clear description of the problem or request
- Steps to reproduce (for bugs)
- Expected vs. actual behavior
- PHP version and framework (if applicable)

Changelog
---------

[](#changelog)

See [CHANGELOG.md](CHANGELOG.md) for version history and breaking changes.

Author
------

[](#author)

**Igor Sazonov** —  — [github.com/tigusigalpa](https://github.com/tigusigalpa)

License
-------

[](#license)

[MIT](LICENSE) — do whatever you want, just don't blame me if something breaks.

Official Links
--------------

[](#official-links)

- [Glassnode Documentation](https://docs.glassnode.com/)
- [Glassnode Basic API](https://docs.glassnode.com/basic-api/)
- [Glassnode Studio](https://studio.glassnode.com/)
- [Glassnode Academy](https://academy.glassnode.com/)

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance100

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity42

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

0d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/2721390?v=4)[Igor Sazonov](/maintainers/tigusigalpa)[@tigusigalpa](https://github.com/tigusigalpa)

---

Top Contributors

[![tigusigalpa](https://avatars.githubusercontent.com/u/2721390?v=4)](https://github.com/tigusigalpa "tigusigalpa (3 commits)")

---

Tags

apibitcoinchainlinkcryptocryptocurrencyglassnodelaravellaravel-packagenear-protocolphpapilaravelsdkcryptobitcoinblockchainglassnodeon-chain

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/tigusigalpa-glassnode-php/health.svg)

```
[![Health](https://phpackages.com/badges/tigusigalpa-glassnode-php/health.svg)](https://phpackages.com/packages/tigusigalpa-glassnode-php)
```

###  Alternatives

[tempest/framework

The PHP framework that gets out of your way.

2.2k34.4k17](/packages/tempest-framework)[telnyx/telnyx-php

Official Telnyx PHP SDK — APIs for Voice, SMS, MMS, WhatsApp, Fax, SIP Trunking, Wireless IoT, Call Control, and more. Build global communications on Telnyx's private carrier-grade network.

36789.4k2](/packages/telnyx-telnyx-php)[openai-php/client

OpenAI PHP is a supercharged PHP API client that allows you to interact with the Open AI API

5.8k28.0M327](/packages/openai-php-client)[mollie/mollie-api-php

Mollie API client library for PHP. Mollie is a European Payment Service provider and offers international payment methods such as Mastercard, VISA, American Express and PayPal, and local payment methods such as iDEAL, Bancontact, SOFORT Banking, SEPA direct debit, Belfius Direct Net, KBC Payment Button and various gift cards such as Podiumcadeaukaart and fashioncheque.

60316.0M89](/packages/mollie-mollie-api-php)[getbrevo/brevo-php

Official Brevo provided RESTFul API V3 php library

1003.9M50](/packages/getbrevo-brevo-php)[flow-php/flow

PHP ETL - Extract Transform Load - Data processing framework

85036.3k](/packages/flow-php-flow)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
