glassnode

package module
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 2, 2026 License: MIT Imports: 11 Imported by: 0

README

GlassNode Golang SDK

GlassNode Golang SDK

CI Tests Go Version License CodeQL Codecov GitHub Release GoDoc

Unofficial Go SDK for the Glassnode Basic API. Not affiliated with or endorsed by Glassnode — just a community-built tool I wish had existed when I started working with on-chain data.

A dependency-light, production-oriented Go module for the Glassnode Basic API, built with the kind of care you'd want from a library you depend on every day.

If you've ever found yourself hand-crafting net/http calls to Glassnode, parsing JSON into map[string]interface{}, and string-building metric paths at 2 AM to ship a dashboard — you already know it gets tedious fast. This SDK wraps all of that into a clean, idiomatic Go package with strongly-typed structs, context.Context propagation, and sensible defaults, so you can spend your time on application logic instead of HTTP plumbing.

The SDK exposes the complete documented metric surface through three layers of API, each one building on the last:

  1. Typed transport/config — a Client with functional options, secure defaults, context.Context support, and zero external dependencies
  2. Metadata & generic metrics — a MetadataService for runtime discovery and a MetricsService that works with any present or future metric path
  3. Ergonomic category services — 25 typed service structs with convenience methods that map 1:1 to Glassnode's endpoint categories

Who Is This For?

This SDK was written for the kind of developer who:

  • Builds trading dashboards, research tools, or backtesting pipelines that need on-chain data
  • Cares about dependency hygiene — no surprise transitive packages, no go.sum bloat
  • Wants errors they can actually branch on with errors.Is / errors.As instead of grepping strings
  • Runs services in production and needs concurrency-safe clients that won't fall over under load
  • Likes their libraries to do the boring stuff (retries, redaction, context propagation) so they can focus on the interesting stuff

If that sounds like you, welcome — you're in the right place.

Why This SDK?

  • Zero external dependencies — uses only the Go standard library, so it won't bloat your go.sum or create transitive dependency conflicts that surface at the worst possible moment
  • Idiomatic Go — functional options, context.Context propagation, strongly-typed structs, and errors.Is / errors.As support throughout
  • Concurrency-safe — the Client is safe for concurrent use across goroutines, perfect for high-throughput services and fan-out workloads
  • Discover metrics at runtime — not sure which parameters a metric accepts? Ask the metadata API before you make data calls and avoid wasting credits on bad requests
  • Survive rate limits gracefully — automatic retry on 429 with server-aware backoff, so you don't have to wrap every call in your own retry loop
  • Keep your API key safe — header-based auth by default, and the SDK redacts the key in request URLs and response metadata so it never leaks into your logs
  • Only pay for what you use — bulk endpoints with explicit asset lists put you in control of credit consumption, no accidental wildcard blow-ups

Features

  • Zero external dependencies — uses only the Go standard library, nothing else. Your go.sum stays as short as the day you started the project
  • 25 category services 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 by a typed method
  • 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 and backtesting
  • Header authentication (X-Api-Key) by default; query-string opt-in for the rare environments that genuinely need it
  • Automatic retry on HTTP 429 with x-rate-limit-reset support and exponential backoff as a fallback
  • Exported, inspectable error types with errors.Is / errors.As support — no string matching required
  • API key redaction in request URLs and response metadata, including query-string authentication
  • Concurrency-safe Client suitable for goroutine use without additional locking
  • Configurable HTTP transport for testing and custom http.RoundTripper implementations (proxies, middleware, recording)
  • Functional options — configure only what you need, sensible defaults for everything else

Installation

go get github.com/tigusigalpa/glassnode-go

That's it. The module has zero external dependencies, so your go.sum stays clean. Just import it and start using it — no go mod tidy surprises, no version conflicts to untangle.

Quick Start

Here's a complete, runnable example — create a client, fetch BTC price data, and print it. Drop it into a main.go and you're off:

package main

import (
    "context"
    "fmt"
    "log"

    glassnode "github.com/tigusigalpa/glassnode-go"
)

func main() {
    // From environment variable GLASSNODE_API_KEY
    client, err := glassnode.NewClientFromEnv()
    if err != nil {
        log.Fatal(err)
    }

    // Or pass an explicit key if you prefer
    // client := glassnode.NewClient("YOUR_API_KEY")

    ctx := context.Background()

    // Fetch BTC price with 24h resolution
    price, err := client.Market.Price(ctx, &glassnode.MetricQuery{
        Asset:      "BTC",
        Resolution: glassnode.Resolution24h,
    })
    if err != nil {
        log.Fatal(err)
    }
    for _, p := range price {
        fmt.Printf("BTC price at %d: $%.2f\n", p.T, p.V)
    }
}

Want to explore what's available before pulling data? The metadata API is your friend — it lets you window-shop metrics without spending credits on guesses:

// List all supported assets
assets, err := client.Metadata.Assets(ctx, "")
if err != nil {
    log.Fatal(err)
}
for _, a := range assets {
    fmt.Printf("%s (%s)\n", a.Name, a.Symbol)
}

// Inspect a specific metric's parameters
metricInfo, err := client.Metadata.Metric(ctx, "/market/price_usd")
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Metric: %s\n", metricInfo.Path)
fmt.Printf("Parameters: %v\n", metricInfo.Parameters)
Common Use Cases

A few real-world patterns to get you oriented. These are intentionally small — copy, paste, and adapt.

Building a market dashboard:

ctx := context.Background()

// Get OHLC candles for charting
ohlc, err := client.Market.PriceOHLC(ctx, &glassnode.MetricQuery{
    Asset:      "BTC",
    Resolution: glassnode.Resolution1h,
})

// Market cap and realized cap for valuation analysis
mcap, err := client.Market.MarketCap(ctx, &glassnode.MetricQuery{Asset: "BTC"})
rcap, err := client.Market.RealizedCap(ctx, &glassnode.MetricQuery{Asset: "BTC"})

// MVRV ratio — a classic cycle indicator
mvrv, err := client.Indicators.MVRV(ctx, &glassnode.MetricQuery{Asset: "BTC"})

Monitoring network health:

// Active addresses — measures network usage
active, err := client.Addresses.ActiveCount(ctx, &glassnode.MetricQuery{
    Asset:      "BTC",
    Resolution: glassnode.Resolution24h,
})

// Hash rate — mining security
hashrate, err := client.Mining.HashRate(ctx, &glassnode.MetricQuery{Asset: "BTC"})

// Total supply — track inflation
supply, err := client.Supply.CirculatingSupply(ctx, &glassnode.MetricQuery{Asset: "BTC"})

Concurrent fetches with goroutines:

The Client is concurrency-safe, so fan-out patterns just work. Here's the textbook pattern for pulling several metrics in parallel:

var (
    price   []glassnode.TimePoint
    sopr    []glassnode.TimePoint
    active  []glassnode.TimePoint
)

var wg sync.WaitGroup
wg.Add(3)

query := &glassnode.MetricQuery{Asset: "BTC", Resolution: glassnode.Resolution24h}

go func() {
    defer wg.Done()
    price, _ = client.Market.Price(ctx, query)
}()
go func() {
    defer wg.Done()
    sopr, _ = client.Indicators.SOPR(ctx, query)
}()
go func() {
    defer wg.Done()
    active, _ = client.Addresses.ActiveCount(ctx, query)
}()

wg.Wait()
// The Client is concurrency-safe — no additional locking needed

Tip: In production code, propagate errors back from each goroutine through a channel or shared error slice instead of discarding them with _. The example above keeps things short; real services should never swallow errors silently.

Tracking credit usage over time:

usage, err := client.User.APIUsage(ctx)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Credits used this month: %d\n", usage.CreditsUsed)

API Key Security

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

  • Never hardcode your API key in source code or commit it to version control. Secrets in git history are forever
  • Use NewClientFromEnv() to read from the GLASSNODE_API_KEY environment variable — this is the recommended path for almost every deployment
  • Or pass the key at runtime: glassnode.NewClient(os.Getenv("GLASSNODE_API_KEY"))
  • The SDK redacts the API key in request URLs and response metadata, including when query-string authentication is enabled
  • Header mode (X-Api-Key) is the default and recommended; the key is sent in an HTTP header and never appears in URLs, access logs, or proxy traces
  • Query-string mode (api_key) is opt-in via WithAuthMode(AuthModeQuery) for environments where headers aren't supported, but it's less secure — the key ends up in URLs that get logged everywhere they pass through
  • If you accidentally expose a key, rotate it immediately in Glassnode Studio settings. Don't wait, don't hope nobody noticed

Authentication Modes

The SDK supports two authentication modes. Header mode is the default and recommended for all production usage — there's rarely a good reason to switch:

// Header mode (default, recommended)
// Sends the key as an X-Api-Key header — invisible in URLs and logs
client := glassnode.NewClient("key")

// Query-string mode (opt-in, less secure)
// Appends ?api_key=... to every request URL
client := glassnode.NewClient("key", glassnode.WithAuthMode(glassnode.AuthModeQuery))

Configuration

The SDK uses the functional options pattern — configure only what you need, and everything else gets sensible defaults. This keeps the common case a one-liner while still letting you tune behavior when you need to:

client := glassnode.NewClient("key",
    glassnode.WithBaseURL("https://api.glassnode.com"),  // API base URL (rarely needs changing)
    glassnode.WithTimeout(15*time.Second),               // HTTP timeout
    glassnode.WithRetry(3, time.Second),                 // Max retries + base delay for 429 backoff
    glassnode.WithHTTPClient(customHTTPClient),          // Custom *http.Client for testing or proxies
    glassnode.WithUserAgent("my-app/1.0"),               // User-Agent header
    glassnode.WithAppID("trading-bot"),                  // Optional app identifier for Glassnode analytics
)
Available Options
Option Default Description
WithBaseURL(url) https://api.glassnode.com API base URL
WithTimeout(d) 30s HTTP request timeout
WithRetry(n, delay) 1, 500ms Max retry attempts on 429 + base backoff delay
WithHTTPClient(c) &http.Client{Timeout: 30s} Custom HTTP client (for testing, proxies, custom transports)
WithUserAgent(ua) glassnode-go/1.0 User-Agent header
WithAppID(id) "" Optional app identifier
WithAuthMode(mode) AuthModeHeader AuthModeHeader or AuthModeQuery
A Note on Timeouts

The default 30s timeout is generous on purpose — some historical metric pulls return large payloads and take a moment. If you're building a latency-sensitive service (say, a live trading dashboard), dial it down with WithTimeout. If you're pulling years of daily data in a batch job, you may want to dial it up. The right value is the one that matches your workload, not a magic number.

Category Services

The 25 category services map 1:1 to Glassnode's documented endpoint categories. Each one exposes typed convenience methods so you get autocomplete, compile-time checks, and self-documenting code:

Service Client Field Documentation
Addresses client.Addresses Addresses
Bridges client.Bridges Bridges
Blockchain client.Blockchain Blockchain
Breakdowns client.Breakdowns Breakdowns
DeFi client.DeFi DeFi
Derivatives client.Derivatives Derivatives
Distribution client.Distribution Distribution
Entities client.Entities Entities
ETH 2.0 client.ETH2 ETH 2.0
Fees client.Fees Fees
Global client.Global Global
Indicators client.Indicators Indicators
Institutions client.Institutions Institutions
Lightning client.Lightning Lightning
Macro client.Macro Macro
Market client.Market Market
Mempool client.Mempool Mempool
Mining client.Mining Mining
Options client.Options Options
Point-In-Time client.PointInTime PIT
Protocols client.Protocols Protocols
Signals client.Signals Signals
Supply client.Supply Supply
Transactions client.Transactions Transactions
Treasuries client.Treasuries Treasuries

Full endpoint coverage: docs/endpoint-coverage.md

Generic Metric API

The 25 category services cover every documented endpoint category, but Glassnode occasionally adds new metrics before a typed wrapper exists. The generic MetricsService ensures you're never blocked waiting for an SDK release — it works with any valid metric path, present or future:

// Raw JSON — works with any metric path, returns []byte
// Use this when you want full control over decoding, or when the response shape is unusual
raw, err := client.Metrics.Get(ctx, "/addresses/sending_count", &glassnode.MetricQuery{
    Asset: "BTC",
})

// Typed scalar time-series — parses into []TimePoint
// Use this when the metric returns {t, v} pairs
data, err := client.Metrics.GetTimePoints(ctx, "/indicators/sopr", &glassnode.MetricQuery{
    Asset:      "BTC",
    Resolution: glassnode.Resolution24h,
})

// Typed object time-series — parses into []ObjectPoint
// Use this when the metric returns {t, o: {...}} pairs (e.g. OHLC)
ohlc, err := client.Metrics.GetObjectPoints(ctx, "/market/price_ohlc", &glassnode.MetricQuery{
    Asset:      "BTC",
    Resolution: glassnode.Resolution1h,
})
MetricQuery Parameters

The MetricQuery struct covers all common query parameters. Only Asset is required — the rest are optional and only sent when set:

type MetricQuery struct {
    Asset           string          // Required — e.g. "BTC", "ETH"
    Resolution      Resolution      // Optional — Resolution10m, Resolution1h, etc.
    Since           *int64   // Optional — Unix timestamp
    Until           *int64   // Optional — Unix timestamp
    Currency        Currency        // Optional — CurrencyNative or CurrencyUSD
    Format          Format          // Optional — FormatJSON or FormatCSV
    TimestampFormat TimestampFormat // Optional — TimestampUnix or TimestampHumanized
}

Use metadata/metric to discover which parameters a specific metric accepts — not every metric honors every field, and sending unsupported parameters can cause 400s.

Convenience Resolution Constants

Instead of remembering string literals, use the exported constants for the common resolutions:

glassnode.Resolution10m     // "10m"
glassnode.Resolution1h      // "1h"
glassnode.Resolution24h     // "24h"
glassnode.Resolution1w      // "1w"
glassnode.Resolution1month  // "1month"

Bulk Metrics

Bulk endpoints let you fetch data for multiple assets in a single request, saving on rate-limit budget and round-trips. However, credits are still consumed per asset — so a bulk call for 5 assets costs the same as 5 individual calls. Bulk is about throughput, not credit savings:

since := time.Now().AddDate(0, 0, -7).Unix()
resp, err := client.Metrics.GetBulk(ctx, "/market/mvrv", &glassnode.BulkQuery{
    Assets:     []string{"BTC", "ETH"},
    Since:      &since,
    Resolution: glassnode.Resolution24h,
})
Bulk Best Practices
  • Always specify assets explicitly — never use wildcards, as this can consume unexpected credits and burn through your quota before you notice
  • Check bulk_supported via metadata/metric before calling bulk endpoints — not all metrics support it, and a 400 is the polite way to find out
  • Batch in reasonable sizes — 5–10 assets per call is a good balance between throughput and credit visibility; larger batches make it harder to attribute credit spikes
  • Monitor your credit usage with client.User.APIUsage() to catch unexpected consumption early, before it becomes a bill

Error Handling

The SDK exports sentinel error variables and a structured APIError type, so you can handle errors idiomatically with errors.Is and errors.As — no string matching, no fragile strings.Contains checks that break when the API changes its wording:

_, err := client.Indicators.SOPR(ctx, &glassnode.MetricQuery{Asset: "BTC"})
if err != nil {
    switch {
    case errors.Is(err, glassnode.ErrUnauthorized):
        // 401 — API key is missing, invalid, or expired
        log.Println("Invalid API key — check your configuration")

    case errors.Is(err, glassnode.ErrRateLimited):
        // 429 — rate limit hit after all retries exhausted
        var apiErr *glassnode.APIError
        if errors.As(err, &apiErr) {
            log.Printf("Rate limited after %d retries, reset in %ds\n",
                apiErr.Retried, apiErr.RateLimitReset)
        }

    case errors.Is(err, glassnode.ErrBadRequest):
        // 400 — invalid parameters, unsupported asset, etc.
        log.Printf("Bad request: %v", err)

    case errors.Is(err, glassnode.ErrNotFound):
        // 404 — the metric path doesn't exist
        log.Println("Metric not found — check the path with metadata/metric")

    default:
        // Network errors, context cancellation, unexpected responses
        log.Printf("Unexpected error: %v", err)
    }
}
Error Types

The SDK defines sentinel errors for each HTTP status code and an APIError struct that carries additional context — retry count, rate-limit reset, response body — so you can make informed decisions about what to do next:

Sentinel HTTP Status Description
ErrBadRequest 400 Invalid parameters or unsupported asset
ErrUnauthorized 401 API key missing, invalid, or expired
ErrNotFound 404 Metric path not found
ErrRateLimited 429 Rate limit hit (after retries exhausted)

The APIError struct includes the HTTP status code, response body, retry count, and RateLimitReset value (when available). Use errors.As to unwrap it and inspect the details.

A Practical Recovery Strategy

For long-running services, a simple but effective pattern is: on ErrRateLimited, pause the worker for RateLimitReset seconds (or a sensible fallback) before retrying the queue; on ErrUnauthorized, fail fast and alert — there's no point retrying a bad key. On a 5xx APIError, retry with backoff. Everything else is probably a bug in your request — log it and move on.

Retry Behavior

Nobody likes getting rate-limited, and nobody likes writing retry loops around every API call. The SDK handles 429 responses automatically so you can keep your call sites clean:

  • Retries only idempotent GET requests on HTTP 429 — non-idempotent methods are never retried, because retrying them could double-charge credits
  • Honors x-rate-limit-reset header when present — waits exactly as long as the server tells us to, no guessing
  • Falls back to exponential backoff when the header is absent: baseDelay * 2^attempt
  • Never retries 400, 401, or 404 — these are client errors that won't resolve by retrying, and retrying them just wastes time
  • Configurable via WithRetry(maxAttempts, baseDelay) (defaults: 1 attempt, 500ms base delay)

If all retry attempts are exhausted, an APIError wrapping ErrRateLimited is returned with the retry count and RateLimitReset value (if available) so your application can decide how to handle it — queue the request for later, alert the user, or back off further. The SDK does the retrying; you decide the policy on top.

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 rather than discovering the limit by hitting it:

Header Description
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 resets

Metadata endpoints are separately limited to 1200 req/min, so you can discover metrics freely without worrying about impacting your data request budget. That separation is by design — exploration shouldn't cost you throughput on the calls that matter.

Tips for Staying Within Limits
  • Cache metadata responses — assets and metric definitions rarely change; there's no reason to re-fetch them on every request
  • Use appropriate resolutions — don't fetch 10-minute data when you only need daily aggregates; smaller resolutions mean more data points and more frequent refresh needs
  • Batch with bulk endpoints where supported — one HTTP call instead of many reduces your request count without changing your credit cost
  • Monitor x-rate-limit-remaining and back off before hitting zero, not after — proactive throttling is cheaper than reactive retrying

Data Credits

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

  • 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

If you're building a service that pulls many metrics, consider caching results and refreshing on a schedule rather than polling continuously. A daily refresh job will almost always cost less than a live polling loop, and for most on-chain analysis the difference in freshness is irrelevant.

Point-in-Time Data

For backtesting and historically accurate analysis, the Point-in-Time service preserves the computed_at timestamp — the moment a metric was actually calculated, not just the data point's timestamp. This matters because Glassnode sometimes revises historical data, and a backtest that uses today's values for past dates will lie to you about how your strategy would have performed:

pit, err := client.PointInTime.GetPITTimePoints(ctx, "/indicators/sopr_pit", &glassnode.MetricQuery{
    Asset: "BTC",
})
// Each point carries both the data timestamp (t) and the computed_at timestamp,
// so you can reconstruct exactly what was known at any moment in the past.

See the Point-in-Time endpoint docs for the full list of supported metrics.

Testing

The test suite uses mocked HTTP transports — no API key or live requests are required, so you can run the full suite anywhere: CI, air-gapped laptops, your phone if you really wanted to:

# Run all tests with verbose output
go test ./... -v

# Check formatting (no output = clean)
gofmt -d .

# Run the linter
go vet ./...

The suite includes 39 tests covering all services, error handling, retry logic, configuration, and the generic metrics API. If you're contributing, please add tests for any new functionality — all tests must pass with mocked transports (no live API calls), so the suite stays hermetic and deterministic.

Writing Tests Against the SDK

For your own application tests, inject a custom *http.Client via WithHTTPClient and back it with an http.RoundTripper that returns canned responses. This keeps your tests fast, deterministic, and free of credit consumption:

rt := &mockRoundTripper{response: cannedResponse}
client := glassnode.NewClient("test-key", glassnode.WithHTTPClient(&http.Client{Transport: rt}))

Examples

The examples/ directory contains ready-to-run programs you can adapt for your own projects. Each one is self-contained and prints useful output so you can verify it works before wiring it into anything serious:

  • Basic usage — price, indicators, assets, API usage
  • Metadata — list metrics, inspect parameters at runtime
  • Bulk metrics — multi-asset bulk requests with credit awareness
  • Error handling — error types, errors.Is/errors.As, and recovery strategies

Compatibility

  • Go 1.21+ (uses log/slog, enhanced errors support, and modern stdlib features)
  • No external dependencies — uses only the Go standard library, so it builds cleanly in any environment that has Go
  • Works with custom http.RoundTripper implementations for testing, proxies, or middleware — nothing in the SDK assumes a particular transport

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 — there's a free tier with limited credits to get you started, which is plenty for experimentation.

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 and should always be your source of truth for endpoint behavior.

Why zero dependencies? Isn't that overkill?

Not really. The Go standard library already provides everything needed — net/http for transport, encoding/json for parsing, errors for error handling. Avoiding external dependencies means no transitive dependency conflicts, no security advisories from third-party packages to track, and a smaller binary. It's a feature, not a limitation, and it means the SDK will keep building cleanly for years without dependency maintenance.

What happens when Glassnode adds new metrics?

The generic MetricsService 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. If you'd like a typed wrapper for a new metric, open an issue or submit a PR — they're straightforward to add.

Is the Client safe for concurrent use?

Yes. The Client is safe for concurrent use across goroutines without additional locking. The underlying http.Client is also goroutine-safe. Just pass a context.Context with a timeout or cancellation signal per request, and you're good to fan out as wide as your rate limit allows.

How do I get CSV format instead of JSON?

Set Format: glassnode.FormatCSV in the MetricQuery passed to client.Metrics.Get. That method returns the raw CSV bytes as-is; it does not parse CSV because shapes vary across metrics. JSON (the default) is automatically decoded into typed structs.

Does the SDK work with the Glassnode Advanced API?

No. This SDK targets the Basic API only. The Advanced API has a different surface and auth model; supporting it would be a separate effort. If there's enough interest, that could happen — open an issue to signal demand.

Can I use this in a commercial product?

Yes. The SDK is MIT-licensed — do what you want with it, including using it in closed-source commercial products. Just don't blame me if something breaks, and keep the license notice around as the license requires.

Contributing

Contributions are welcome, and they're a big part of what keeps community projects like this alive. 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: go test ./...
  3. Make your changes — keep code style consistent with the existing codebase (run gofmt and go vet)
  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. The "why" matters more than the "what"
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) — ideally a minimal code snippet
  • Expected vs. actual behavior
  • Go version and any relevant environment details

The more reproducible your report, the faster it gets fixed.

Changelog

See CHANGELOG.md for version history and breaking changes. Breaking changes will be signaled clearly in the changelog and bumped in the major version number — no silent surprises.

Author

Igor Sazonovsovletig@gmail.comgithub.com/tigusigalpa

Bug reports, feature requests, and pull requests are all welcome.

License

MIT — do whatever you want, just don't blame me if something breaks.

Documentation

Overview

Package glassnode provides a Go SDK for the Glassnode Basic API (https://api.glassnode.com). It exposes service structs grouped by resource category accessible as fields on Client.

The SDK supports both header (X-Api-Key) and query-string (api_key) authentication, with header mode as the secure default. All network-facing methods accept context.Context as their first parameter.

Index

Constants

View Source
const DefaultBaseDelay = 500 * time.Millisecond

DefaultBaseDelay is the default initial backoff delay used for retry attempts, unless overridden with WithRetry.

View Source
const DefaultBaseURL = "https://api.glassnode.com"

DefaultBaseURL is the default Glassnode API base URL used by NewClient unless overridden with WithBaseURL.

View Source
const DefaultMaxAttempts = 1

DefaultMaxAttempts is the default number of attempts (including the initial request) made for a request before giving up when receiving HTTP 429 responses, unless overridden with WithRetry.

View Source
const DefaultTimeout = 30 * time.Second

DefaultTimeout is the default HTTP client timeout used unless overridden with WithTimeout.

View Source
const DefaultUserAgent = "glassnode-go/1.0.0"

DefaultUserAgent is the default User-Agent header value sent with every request.

Variables

View Source
var (
	// ErrMissingAPIKey is returned when no API key is provided.
	ErrMissingAPIKey = errors.New("glassnode: missing API key — set GLASSNODE_API_KEY or pass a key to NewClient")
	// ErrBadRequest is returned when the API responds with HTTP 400.
	ErrBadRequest = errors.New("glassnode: bad request — invalid parameters or unsupported asset")
	// ErrUnauthorized is returned when the API responds with HTTP 401.
	ErrUnauthorized = errors.New("glassnode: unauthorized — check your API key")
	// ErrNotFound is returned when the API responds with HTTP 404.
	ErrNotFound = errors.New("glassnode: resource not found")
	// ErrRateLimited is returned when the API responds with HTTP 429 and
	// all retry attempts have been exhausted.
	ErrRateLimited = errors.New("glassnode: rate limit exceeded")
	// ErrInvalidMetricPath is returned when an empty or malformed metric
	// path is provided.
	ErrInvalidMetricPath = errors.New("glassnode: invalid metric path")
)

Sentinel errors that can be checked with errors.Is against errors returned from service methods. The underlying *APIError is always available via errors.As for accessing StatusCode, RawBody, etc.

Functions

func BoolPtr

func BoolPtr(b bool) *bool

BoolPtr returns a pointer to the provided bool value.

func Float64Ptr

func Float64Ptr(f float64) *float64

Float64Ptr returns a pointer to the provided float64 value.

func Int64Ptr

func Int64Ptr(i int64) *int64

Int64Ptr returns a pointer to the provided int64 value.

func IntPtr

func IntPtr(i int) *int

IntPtr returns a pointer to the provided int value. It is useful for populating optional pointer fields in parameter structs.

func StringPtr

func StringPtr(s string) *string

StringPtr returns a pointer to the provided string value.

Types

type APIError

type APIError struct {
	// StatusCode is the HTTP status code returned by the API.
	StatusCode int
	// Message is a human-readable error message extracted from the
	// response body or a generated fallback.
	Message string
	// RawBody contains a truncated, redacted copy of the raw response
	// body for debugging purposes (max 512 bytes).
	RawBody []byte
	// RequestID is the value of the X-Request-ID response header, if
	// the server provides one.
	RequestID string
	// RateLimitLimit is the value of the x-rate-limit-limit header, if
	// present.
	RateLimitLimit string
	// RateLimitRemaining is the value of the x-rate-limit-remaining
	// header, if present.
	RateLimitRemaining string
	// RateLimitReset is the value of the x-rate-limit-reset header, if
	// present.
	RateLimitReset string
	// Retried is the number of retry attempts made before this error
	// was returned.
	Retried int
}

APIError represents an error response returned by the Glassnode API. It is returned by every service method when the API responds with a non-2xx HTTP status code. The error carries the status code, a safe response excerpt, rate-limit metadata, and the request ID when available, but never includes the API key.

func (*APIError) Error

func (e *APIError) Error() string

Error implements the error interface for APIError.

type APIUsage

type APIUsage struct {
	CreditsUsed int `json:"creditsUsed"`
}

APIUsage represents the response from the user/api_usage endpoint.

type AddressesService

type AddressesService struct {
	// contains filtered or unexported fields
}

AddressesService provides access to the Addresses category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/addresses

func (*AddressesService) AccumulationBalance

func (s *AddressesService) AccumulationBalance(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

AccumulationBalance retrieves the total funds held in accumulation addresses. Path: /addresses/accumulation_balance

func (*AddressesService) AccumulationCount

func (s *AddressesService) AccumulationCount(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

AccumulationCount retrieves the number of unique accumulation addresses. Path: /addresses/accumulation_count

func (*AddressesService) AccumulationCountPIT

func (s *AddressesService) AccumulationCountPIT(ctx context.Context, q *MetricQuery) ([]PITTimePoint, error)

AccumulationCountPIT retrieves the PIT version of accumulation count. Path: /addresses/accumulation_count_pit

func (*AddressesService) ActiveCount

func (s *AddressesService) ActiveCount(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

ActiveCount retrieves the number of unique active addresses. Path: /addresses/active_count

func (*AddressesService) ActiveCountPIT

func (s *AddressesService) ActiveCountPIT(ctx context.Context, q *MetricQuery) ([]PITTimePoint, error)

ActiveCountPIT retrieves the PIT version of active addresses count. Path: /addresses/active_count_pit

func (*AddressesService) ActiveCountWithContracts

func (s *AddressesService) ActiveCountWithContracts(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

ActiveCountWithContracts retrieves active addresses including smart contract calls. Path: /addresses/active_count_with_contracts

func (*AddressesService) Count

func (s *AddressesService) Count(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

Count retrieves the total number of addresses with a non-zero balance. Path: /addresses/count

func (*AddressesService) GetRaw

func (s *AddressesService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any addresses metric as raw JSON.

func (*AddressesService) NewAddresses

func (s *AddressesService) NewAddresses(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

NewAddresses retrieves the number of new addresses. Path: /addresses/new_entities

func (*AddressesService) ReceivingAddresses

func (s *AddressesService) ReceivingAddresses(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

ReceivingAddresses retrieves the number of receiving addresses. Path: /addresses/receiving_count

func (*AddressesService) SendingAddresses

func (s *AddressesService) SendingAddresses(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

SendingAddresses retrieves the number of sending addresses. Path: /addresses/sending_count

type Asset

type Asset struct {
	ID           string            `json:"id"`
	ExternalIDs  AssetExternalIDs  `json:"external_ids"`
	Symbol       string            `json:"symbol"`
	Name         string            `json:"name"`
	AssetType    string            `json:"asset_type"`
	Blockchains  []AssetBlockchain `json:"blockchains"`
	LogoURL      string            `json:"logo_url"`
	SemanticTags []string          `json:"semantic_tags"`
}

Asset represents a single asset in the metadata/assets response.

type AssetBlockchain

type AssetBlockchain struct {
	Blockchain     string `json:"blockchain"`
	Address        string `json:"address"`
	Decimals       int    `json:"decimals"`
	OnChainSupport bool   `json:"on_chain_support"`
}

AssetBlockchain represents a blockchain entry in asset metadata.

type AssetExternalIDs

type AssetExternalIDs struct {
	CCData        string `json:"ccdata"`
	CoinMarketCap string `json:"coinmarketcap"`
	CoinGecko     string `json:"coingecko"`
}

AssetExternalIDs holds references to external third-party IDs.

type AssetsResponse

type AssetsResponse struct {
	Data []Asset `json:"data"`
}

AssetsResponse wraps the metadata/assets response: {"data": [...]}.

type AuthMode

type AuthMode int

AuthMode controls how the API key is transmitted.

const (
	// AuthModeHeader sends the API key via the X-Api-Key header.
	// This is the default and recommended mode.
	AuthModeHeader AuthMode = iota
	// AuthModeQuery sends the API key via the api_key query parameter.
	// This is less secure because the key may appear in logs and URLs.
	AuthModeQuery
)

type BlockchainService

type BlockchainService struct {
	// contains filtered or unexported fields
}

BlockchainService provides access to the Blockchain category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/blockchain

func (*BlockchainService) BlockHeight

func (s *BlockchainService) BlockHeight(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

BlockHeight retrieves the current block height. Path: /blockchain/block_height

func (*BlockchainService) BlockIntervalMean

func (s *BlockchainService) BlockIntervalMean(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

BlockIntervalMean retrieves the mean block interval. Path: /blockchain/block_interval_mean

func (*BlockchainService) BlockIntervalMedian

func (s *BlockchainService) BlockIntervalMedian(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

BlockIntervalMedian retrieves the median block interval. Path: /blockchain/block_interval_median

func (*BlockchainService) BlockSizeMean

func (s *BlockchainService) BlockSizeMean(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

BlockSizeMean retrieves the mean block size. Path: /blockchain/block_size_mean

func (*BlockchainService) BlockSizeTotal

func (s *BlockchainService) BlockSizeTotal(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

BlockSizeTotal retrieves the total block size. Path: /blockchain/block_size_total

func (*BlockchainService) BlocksMined

func (s *BlockchainService) BlocksMined(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

BlocksMined retrieves the number of blocks mined. Path: /blockchain/blocks_mined

func (*BlockchainService) GetRaw

func (s *BlockchainService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any blockchain metric as raw JSON.

func (*BlockchainService) UTXOsCreated

func (s *BlockchainService) UTXOsCreated(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

UTXOsCreated retrieves the number of UTXOs created. Path: /blockchain/utxo_created_count

func (*BlockchainService) UTXOsSpent

func (s *BlockchainService) UTXOsSpent(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

UTXOsSpent retrieves the number of UTXOs spent. Path: /blockchain/utxo_spent_count

func (*BlockchainService) UTXOsTotal

func (s *BlockchainService) UTXOsTotal(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

UTXOsTotal retrieves the total number of UTXOs. Path: /blockchain/utxo_count

type BreakdownsService

type BreakdownsService struct {
	// contains filtered or unexported fields
}

BreakdownsService provides access to the Breakdowns category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/breakdowns

func (*BreakdownsService) GetRaw

func (s *BreakdownsService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any breakdowns metric as raw JSON.

func (*BreakdownsService) MVRVByAge

func (s *BreakdownsService) MVRVByAge(ctx context.Context, q *MetricQuery) ([]ObjectPoint, error)

MVRVByAge retrieves MVRV breakdown by age. Path: /breakdowns/mvrv_by_age

func (*BreakdownsService) RealizedCapByAge

func (s *BreakdownsService) RealizedCapByAge(ctx context.Context, q *MetricQuery) ([]ObjectPoint, error)

RealizedCapByAge retrieves realized cap breakdown by age. Path: /breakdowns/realized_cap_by_age

func (*BreakdownsService) SOPRByAge

func (s *BreakdownsService) SOPRByAge(ctx context.Context, q *MetricQuery) ([]ObjectPoint, error)

SOPRByAge retrieves SOPR breakdown by age. Path: /breakdowns/sopr_by_age

func (*BreakdownsService) SOPRByWalletSize

func (s *BreakdownsService) SOPRByWalletSize(ctx context.Context, q *MetricQuery) ([]ObjectPoint, error)

SOPRByWalletSize retrieves SOPR breakdown by wallet size. Path: /breakdowns/sopr_by_wallet_size

func (*BreakdownsService) SupplyByAge

func (s *BreakdownsService) SupplyByAge(ctx context.Context, q *MetricQuery) ([]ObjectPoint, error)

SupplyByAge retrieves supply breakdown by age. Path: /breakdowns/supply_by_age

func (*BreakdownsService) SupplyByPnL

func (s *BreakdownsService) SupplyByPnL(ctx context.Context, q *MetricQuery) ([]ObjectPoint, error)

SupplyByPnL retrieves supply breakdown by profit/loss. Path: /breakdowns/supply_by_pnl

func (*BreakdownsService) SupplyByWalletSize

func (s *BreakdownsService) SupplyByWalletSize(ctx context.Context, q *MetricQuery) ([]ObjectPoint, error)

SupplyByWalletSize retrieves supply breakdown by wallet size. Path: /breakdowns/supply_by_wallet_size

type BridgesService

type BridgesService struct {
	// contains filtered or unexported fields
}

BridgesService provides access to the Bridges category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/bridges

func (*BridgesService) DepositsByChain

func (s *BridgesService) DepositsByChain(ctx context.Context, q *MetricQuery) ([]ObjectPoint, error)

DepositsByChain retrieves bridge deposits by chain. Path: /bridges/deposits_by_chain

func (*BridgesService) GetRaw

func (s *BridgesService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any bridges metric as raw JSON.

func (*BridgesService) NetFlowByChain

func (s *BridgesService) NetFlowByChain(ctx context.Context, q *MetricQuery) ([]ObjectPoint, error)

NetFlowByChain retrieves bridge net flow by chain. Path: /bridges/net_flow_by_chain

func (*BridgesService) TVL

TVL retrieves the total value locked in bridges. Path: /bridges/tvl

func (*BridgesService) TVLRelative

func (s *BridgesService) TVLRelative(ctx context.Context, q *MetricQuery) ([]ObjectPoint, error)

TVLRelative retrieves the relative TVL across bridges. Path: /bridges/tvl_relative

func (*BridgesService) WithdrawalsByChain

func (s *BridgesService) WithdrawalsByChain(ctx context.Context, q *MetricQuery) ([]ObjectPoint, error)

WithdrawalsByChain retrieves bridge withdrawals by chain. Path: /bridges/withdrawals_by_chain

type BulkPoint

type BulkPoint struct {
	T        int64           `json:"t"`
	Bulk     json.RawMessage `json:"bulk"`
	Computed json.RawMessage `json:"computed,omitempty"`
}

BulkPoint represents a single entry in a bulk metric response. The parameter fields and value/category depend on the metric type.

type BulkQuery

type BulkQuery struct {
	// Assets (a) — list of asset ids. Use "*" for all available assets.
	// Always specify assets explicitly to control credit consumption.
	Assets []string
	// Exchanges (e) — list of exchange names.
	Exchanges []string
	// Networks (network) — list of network/blockchain identifiers.
	Networks []string
	// Since (s) — unix timestamp for the start of the data range.
	// Required for bulk requests.
	Since *int64
	// Until (u) — unix timestamp for the end of the data range.
	Until *int64
	// Resolution (i) — time interval. Defaults to 24h.
	Resolution Resolution
	// Currency (c) — currency for values. Defaults to native.
	Currency Currency
	// Format (f) — response format. Only json is supported for bulk.
	Format Format
	// ExtraParams holds endpoint-specific parameters not covered above.
	ExtraParams map[string][]string
}

BulkQuery holds query parameters for bulk metric requests. Bulk endpoints support repeated parameter values for assets, exchanges, and networks. The since (s), until (u), resolution (i), currency (c), and format (f) parameters behave the same as in MetricQuery.

func (*BulkQuery) ToValues

func (q *BulkQuery) ToValues() url.Values

ToValues converts the BulkQuery into url.Values with repeated keys for multi-value parameters.

type BulkResponse

type BulkResponse struct {
	Data []BulkPoint `json:"data"`
}

BulkResponse wraps the bulk metric response envelope: {"data": [...]}.

type Client

type Client struct {

	// Metadata provides access to the metadata endpoints.
	Metadata *MetadataService
	// User provides access to the user endpoints.
	User *UserService
	// Metrics provides access to the generic metric endpoints.
	Metrics *MetricsService
	// Addresses provides access to the addresses category endpoints.
	Addresses *AddressesService
	// Bridges provides access to the bridges category endpoints.
	Bridges *BridgesService
	// Blockchain provides access to the blockchain category endpoints.
	Blockchain *BlockchainService
	// Breakdowns provides access to the breakdowns category endpoints.
	Breakdowns *BreakdownsService
	// DeFi provides access to the DeFi category endpoints.
	DeFi *DeFiService
	// Derivatives provides access to the derivatives category endpoints.
	Derivatives *DerivativesService
	// Distribution provides access to the distribution category endpoints.
	Distribution *DistributionService
	// Entities provides access to the entities category endpoints.
	Entities *EntitiesService
	// ETH2 provides access to the ETH 2.0 category endpoints.
	ETH2 *ETH2Service
	// Fees provides access to the fees category endpoints.
	Fees *FeesService
	// Global provides access to the global category endpoints.
	Global *GlobalService
	// Indicators provides access to the indicators category endpoints.
	Indicators *IndicatorsService
	// Institutions provides access to the institutions category endpoints.
	Institutions *InstitutionsService
	// Lightning provides access to the lightning category endpoints.
	Lightning *LightningService
	// Macro provides access to the macro category endpoints.
	Macro *MacroService
	// Market provides access to the market category endpoints.
	Market *MarketService
	// Mempool provides access to the mempool category endpoints.
	Mempool *MempoolService
	// Mining provides access to the mining category endpoints.
	Mining *MiningService
	// Options provides access to the options category endpoints.
	Options *OptionsService
	// PointInTime provides access to the point-in-time category endpoints.
	PointInTime *PointInTimeService
	// Protocols provides access to the protocols category endpoints.
	Protocols *ProtocolsService
	// Signals provides access to the signals category endpoints.
	Signals *SignalsService
	// Supply provides access to the supply category endpoints.
	Supply *SupplyService
	// Transactions provides access to the transactions category endpoints.
	Transactions *TransactionsService
	// Treasuries provides access to the treasuries category endpoints.
	Treasuries *TreasuriesService
	// contains filtered or unexported fields
}

Client is the entry point of the Glassnode Go SDK. It holds the HTTP configuration and exposes one service struct per API resource group. A Client is safe for concurrent use by multiple goroutines.

func NewClient

func NewClient(apiKey string, opts ...Option) *Client

NewClient creates a new Glassnode API client authenticated with the given apiKey. The apiKey is sent in the X-Api-Key header on every request by default. Behaviour can be customized via Option values such as WithBaseURL, WithHTTPClient, WithTimeout, WithRetry, and WithAuthMode.

Example:

client := glassnode.NewClient("YOUR_API_KEY",
    glassnode.WithTimeout(15*time.Second),
    glassnode.WithRetry(3, time.Second),
)

func NewClientFromEnv

func NewClientFromEnv(opts ...Option) (*Client, error)

NewClientFromEnv reads the API key from the GLASSNODE_API_KEY environment variable and returns a new Glassnode client. Additional Option values can be passed to override timeouts, retries, etc.

type Currency

type Currency string

Currency represents a supported currency for metric values.

const (
	CurrencyNative Currency = "native"
	CurrencyUSD    Currency = "usd"
)

Supported currency values.

type DeFiService

type DeFiService struct {
	// contains filtered or unexported fields
}

DeFiService provides access to the DeFi category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/defi

func (*DeFiService) GetRaw

func (s *DeFiService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any DeFi metric as raw JSON.

func (*DeFiService) TVL

func (s *DeFiService) TVL(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

TVL retrieves the total value locked in DeFi. Path: /defi/total_value_locked

type DerivativesService

type DerivativesService struct {
	// contains filtered or unexported fields
}

DerivativesService provides access to the Derivatives category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/derivatives

func (*DerivativesService) FuturesEstimatedLeverageRatio

func (s *DerivativesService) FuturesEstimatedLeverageRatio(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

FuturesEstimatedLeverageRatio retrieves the estimated leverage ratio. Path: /derivatives/futures_estimated_leverage_ratio

func (*DerivativesService) FuturesLiquidationsLongTotal

func (s *DerivativesService) FuturesLiquidationsLongTotal(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

FuturesLiquidationsLongTotal retrieves total long liquidations. Path: /derivatives/futures_long_liquidations_total

func (*DerivativesService) FuturesLiquidationsShortTotal

func (s *DerivativesService) FuturesLiquidationsShortTotal(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

FuturesLiquidationsShortTotal retrieves total short liquidations. Path: /derivatives/futures_short_liquidations_total

func (*DerivativesService) FuturesOpenInterest

func (s *DerivativesService) FuturesOpenInterest(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

FuturesOpenInterest retrieves futures open interest. Path: /derivatives/futures_open_interest

func (*DerivativesService) FuturesPerpetualFundingRate

func (s *DerivativesService) FuturesPerpetualFundingRate(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

FuturesPerpetualFundingRate retrieves the perpetual funding rate. Path: /derivatives/futures_perpetual_funding_rate

func (*DerivativesService) FuturesVolume

func (s *DerivativesService) FuturesVolume(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

FuturesVolume retrieves futures trading volume. Path: /derivatives/futures_volume

func (*DerivativesService) GetRaw

func (s *DerivativesService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any derivatives metric as raw JSON.

func (*DerivativesService) OptionsOpenInterest

func (s *DerivativesService) OptionsOpenInterest(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

OptionsOpenInterest retrieves options open interest. Path: /derivatives/options_open_interest

func (*DerivativesService) OptionsVolume24h

func (s *DerivativesService) OptionsVolume24h(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

OptionsVolume24h retrieves 24h options volume. Path: /derivatives/options_volume_24h

type DistributionService

type DistributionService struct {
	// contains filtered or unexported fields
}

DistributionService provides access to the Distribution category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/distribution

func (*DistributionService) ExchangeBalancePercent

func (s *DistributionService) ExchangeBalancePercent(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

ExchangeBalancePercent retrieves exchange balance as a percentage. Path: /distribution/balance_exchanges_percent

func (*DistributionService) ExchangeBalanceTotal

func (s *DistributionService) ExchangeBalanceTotal(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

ExchangeBalanceTotal retrieves total exchange balance. Path: /distribution/balance_exchanges

func (*DistributionService) ExchangeNetPositionChange

func (s *DistributionService) ExchangeNetPositionChange(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

ExchangeNetPositionChange retrieves the exchange net position change. Path: /distribution/exchange_net_position_change

func (*DistributionService) GetRaw

func (s *DistributionService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any distribution metric as raw JSON.

func (*DistributionService) GiniCoefficient

func (s *DistributionService) GiniCoefficient(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

GiniCoefficient retrieves the Gini coefficient. Path: /distribution/gini

func (*DistributionService) HerfindahlIndex

func (s *DistributionService) HerfindahlIndex(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

HerfindahlIndex retrieves the Herfindahl index. Path: /distribution/herfindahl

func (*DistributionService) MinerBalance

func (s *DistributionService) MinerBalance(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

MinerBalance retrieves the miner balance. Path: /distribution/miner_balance

func (*DistributionService) MinerNetPositionChange

func (s *DistributionService) MinerNetPositionChange(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

MinerNetPositionChange retrieves the miner net position change. Path: /distribution/miner_net_position_change

func (*DistributionService) SupplyInSmartContracts

func (s *DistributionService) SupplyInSmartContracts(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

SupplyInSmartContracts retrieves supply held in smart contracts. Path: /distribution/supply_contracts

type ETH2Service

type ETH2Service struct {
	// contains filtered or unexported fields
}

ETH2Service provides access to the ETH 2.0 category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/eth2

func (*ETH2Service) ActiveValidators

func (s *ETH2Service) ActiveValidators(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

ActiveValidators retrieves the number of active validators. Path: /eth2/validators_active

func (*ETH2Service) AverageValidatorBalance

func (s *ETH2Service) AverageValidatorBalance(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

AverageValidatorBalance retrieves the average validator balance. Path: /eth2/validator_balance_mean

func (*ETH2Service) EstimatedAnnualIssuance

func (s *ETH2Service) EstimatedAnnualIssuance(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

EstimatedAnnualIssuance retrieves the estimated annual issuance. Path: /eth2/issuance_annualized

func (*ETH2Service) GetRaw

func (s *ETH2Service) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any ETH2 metric as raw JSON.

func (*ETH2Service) ParticipationRate

func (s *ETH2Service) ParticipationRate(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

ParticipationRate retrieves the participation rate. Path: /eth2/participation_rate

func (*ETH2Service) TotalValidators

func (s *ETH2Service) TotalValidators(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

TotalValidators retrieves the total number of validators. Path: /eth2/validators_count

func (*ETH2Service) TotalValueStaked

func (s *ETH2Service) TotalValueStaked(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

TotalValueStaked retrieves the total value staked in ETH 2.0. Path: /eth2/staked_total

type EntitiesService

type EntitiesService struct {
	// contains filtered or unexported fields
}

EntitiesService provides access to the Entities category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/entities

func (*EntitiesService) ActiveEntities

func (s *EntitiesService) ActiveEntities(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

ActiveEntities retrieves the number of active entities. Path: /entities/active_count

func (*EntitiesService) EntitiesNetGrowth

func (s *EntitiesService) EntitiesNetGrowth(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

EntitiesNetGrowth retrieves the net growth in entities. Path: /entities/net_growth_count

func (*EntitiesService) GetRaw

func (s *EntitiesService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any entities metric as raw JSON.

func (*EntitiesService) NewEntities

func (s *EntitiesService) NewEntities(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

NewEntities retrieves the number of new entities. Path: /entities/new_count

func (*EntitiesService) NumberWhales

func (s *EntitiesService) NumberWhales(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

NumberWhales retrieves the number of whale entities. Path: /entities/count

func (*EntitiesService) ReceivingEntities

func (s *EntitiesService) ReceivingEntities(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

ReceivingEntities retrieves the number of receiving entities. Path: /entities/receiving_count

func (*EntitiesService) SendingEntities

func (s *EntitiesService) SendingEntities(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

SendingEntities retrieves the number of sending entities. Path: /entities/sending_count

type FeesService

type FeesService struct {
	// contains filtered or unexported fields
}

FeesService provides access to the Fees category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/fees

func (*FeesService) FeeRatioMultiple

func (s *FeesService) FeeRatioMultiple(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

FeeRatioMultiple retrieves the Fee Ratio Multiple (FRM). Path: /fees/fee_ratio_multiple

func (*FeesService) FeesMean

func (s *FeesService) FeesMean(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

FeesMean retrieves mean fees per transaction. Path: /fees/volume_mean

func (*FeesService) FeesMedian

func (s *FeesService) FeesMedian(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

FeesMedian retrieves median fees per transaction. Path: /fees/volume_median

func (*FeesService) FeesTotal

func (s *FeesService) FeesTotal(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

FeesTotal retrieves total fees. Path: /fees/volume_sum

func (*FeesService) GasPriceMean

func (s *FeesService) GasPriceMean(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

GasPriceMean retrieves the mean gas price. Path: /fees/gas_price_mean

func (*FeesService) GasPriceMedian

func (s *FeesService) GasPriceMedian(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

GasPriceMedian retrieves the median gas price. Path: /fees/gas_price_median

func (*FeesService) GasUsedTotal

func (s *FeesService) GasUsedTotal(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

GasUsedTotal retrieves total gas used. Path: /fees/gas_used_sum

func (*FeesService) GetRaw

func (s *FeesService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any fees metric as raw JSON.

type Format

type Format string

Format represents a supported response format.

const (
	FormatJSON Format = "json"
	FormatCSV  Format = "csv"
)

Supported response format values.

type GlobalService

type GlobalService struct {
	// contains filtered or unexported fields
}

GlobalService provides access to the Global category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/global

func (*GlobalService) GetRaw

func (s *GlobalService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any global metric as raw JSON.

func (*GlobalService) MedianSOPR

func (s *GlobalService) MedianSOPR(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

MedianSOPR retrieves the median SOPR. Path: /global/sopr_median

func (*GlobalService) TotalMarketCap

func (s *GlobalService) TotalMarketCap(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

TotalMarketCap retrieves the total market capitalization. Path: /global/marketcap

func (*GlobalService) TotalOpenInterest

func (s *GlobalService) TotalOpenInterest(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

TotalOpenInterest retrieves the total open interest. Path: /global/open_interest

func (*GlobalService) TotalRealizedCap

func (s *GlobalService) TotalRealizedCap(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

TotalRealizedCap retrieves the total realized capitalization. Path: /global/marketcap_realized

type IndicatorsService

type IndicatorsService struct {
	// contains filtered or unexported fields
}

IndicatorsService provides access to the Indicators category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/indicators

func (*IndicatorsService) AccumulationTrendScore

func (s *IndicatorsService) AccumulationTrendScore(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

AccumulationTrendScore retrieves the Accumulation Trend Score. Path: /indicators/accumulation_trend_score

func (*IndicatorsService) CDD

CDD retrieves Coin Days Destroyed. Path: /indicators/cdd

func (*IndicatorsService) Dormancy

func (s *IndicatorsService) Dormancy(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

Dormancy retrieves the Dormancy indicator. Path: /indicators/dormancy

func (*IndicatorsService) FearGreed

func (s *IndicatorsService) FearGreed(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

FearGreed retrieves the Fear & Greed Index. Path: /indicators/fear_greed_index

func (*IndicatorsService) GetRaw

func (s *IndicatorsService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any indicators metric as raw JSON.

func (*IndicatorsService) Liveliness

func (s *IndicatorsService) Liveliness(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

Liveliness retrieves the Liveliness indicator. Path: /indicators/liveliness

func (*IndicatorsService) MVRV

MVRV retrieves the MVRV Ratio (Z-Score). Path: /indicators/mvrv

func (*IndicatorsService) NUPL

NUPL retrieves Net Unrealized Profit/Loss. Path: /indicators/nupl

func (*IndicatorsService) NVT

NVT retrieves the NVT Ratio. Path: /indicators/nvt

func (*IndicatorsService) PuellMultiple

func (s *IndicatorsService) PuellMultiple(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

PuellMultiple retrieves the Puell Multiple. Path: /indicators/puell_multiple

func (*IndicatorsService) RHODL

RHODL retrieves the RHODL Ratio. Path: /indicators/rhodl_ratio

func (*IndicatorsService) RealizedLoss

func (s *IndicatorsService) RealizedLoss(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

RealizedLoss retrieves realized loss. Path: /indicators/realized_loss

func (*IndicatorsService) RealizedProfit

func (s *IndicatorsService) RealizedProfit(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

RealizedProfit retrieves realized profit. Path: /indicators/realized_profit

func (*IndicatorsService) ReserveRisk

func (s *IndicatorsService) ReserveRisk(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

ReserveRisk retrieves the Reserve Risk indicator. Path: /indicators/reserve_risk

func (*IndicatorsService) SOPR

SOPR retrieves the Spent Output Profit Ratio. Path: /indicators/sopr

func (*IndicatorsService) StockToFlow

func (s *IndicatorsService) StockToFlow(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

StockToFlow retrieves the Stock-to-Flow Ratio. Path: /indicators/s2f

type InstitutionsService

type InstitutionsService struct {
	// contains filtered or unexported fields
}

InstitutionsService provides access to the Institutions category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/institutions

func (*InstitutionsService) GetRaw

func (s *InstitutionsService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any institutions metric as raw JSON.

func (*InstitutionsService) PurposeBitcoinETFHoldings

func (s *InstitutionsService) PurposeBitcoinETFHoldings(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

PurposeBitcoinETFHoldings retrieves Purpose Bitcoin ETF holdings. Path: /institutions/holdings_purpose_etf

func (*InstitutionsService) USSpotETFBalances

func (s *InstitutionsService) USSpotETFBalances(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

USSpotETFBalances retrieves US Spot ETF balances. Path: /institutions/holdings_us_spot_etf

func (*InstitutionsService) USSpotETFNetFlows

func (s *InstitutionsService) USSpotETFNetFlows(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

USSpotETFNetFlows retrieves US Spot ETF net flows. Path: /institutions/flows_us_spot_etf

func (*InstitutionsService) USSpotETFPrice

func (s *InstitutionsService) USSpotETFPrice(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

USSpotETFPrice retrieves US Spot ETF price. Path: /institutions/price_us_spot_etf

func (*InstitutionsService) USSpotETFTradingVolume

func (s *InstitutionsService) USSpotETFTradingVolume(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

USSpotETFTradingVolume retrieves US Spot ETF trading volume. Path: /institutions/volume_us_spot_etf

type LightningService

type LightningService struct {
	// contains filtered or unexported fields
}

LightningService provides access to the Lightning Network category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/lightning

func (*LightningService) BaseFeeMedian

func (s *LightningService) BaseFeeMedian(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

BaseFeeMedian retrieves the median base fee. Path: /lightning/base_fee_median

func (*LightningService) Capacity

func (s *LightningService) Capacity(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

Capacity retrieves the Lightning Network capacity. Path: /lightning/capacity

func (*LightningService) ChannelSizeMean

func (s *LightningService) ChannelSizeMean(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

ChannelSizeMean retrieves the mean channel size. Path: /lightning/channel_size_mean

func (*LightningService) ChannelSizeMedian

func (s *LightningService) ChannelSizeMedian(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

ChannelSizeMedian retrieves the median channel size. Path: /lightning/channel_size_median

func (*LightningService) FeeRateMedian

func (s *LightningService) FeeRateMedian(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

FeeRateMedian retrieves the median fee rate. Path: /lightning/fee_rate_median

func (*LightningService) GetRaw

func (s *LightningService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any lightning metric as raw JSON.

func (*LightningService) NumberOfChannels

func (s *LightningService) NumberOfChannels(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

NumberOfChannels retrieves the number of Lightning Network channels. Path: /lightning/channel_count

func (*LightningService) NumberOfNodes

func (s *LightningService) NumberOfNodes(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

NumberOfNodes retrieves the number of Lightning Network nodes. Path: /lightning/node_count

type MacroService

type MacroService struct {
	// contains filtered or unexported fields
}

MacroService provides access to the Macro category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/macro

func (*MacroService) EuroAreaInterestRate

func (s *MacroService) EuroAreaInterestRate(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

EuroAreaInterestRate retrieves the Euro area interest rate. Path: /macro/euro_interest_rate

func (*MacroService) GetRaw

func (s *MacroService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any macro metric as raw JSON.

func (*MacroService) USCentralBankBalanceSheet

func (s *MacroService) USCentralBankBalanceSheet(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

USCentralBankBalanceSheet retrieves the US central bank balance sheet. Path: /macro/us_central_bank_balance_sheet

func (*MacroService) USCoreInflationRate

func (s *MacroService) USCoreInflationRate(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

USCoreInflationRate retrieves the US core inflation rate. Path: /macro/us_core_inflation_rate

func (*MacroService) USGDP

func (s *MacroService) USGDP(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

USGDP retrieves the US GDP. Path: /macro/us_gdp

func (*MacroService) USInterestRate

func (s *MacroService) USInterestRate(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

USInterestRate retrieves the US interest rate. Path: /macro/us_interest_rate

func (*MacroService) USMoneySupplyM2

func (s *MacroService) USMoneySupplyM2(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

USMoneySupplyM2 retrieves the US M2 money supply. Path: /macro/us_money_supply_m2

type MarketService

type MarketService struct {
	// contains filtered or unexported fields
}

MarketService provides access to the Market category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/market

func (*MarketService) BTCDominance

func (s *MarketService) BTCDominance(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

BTCDominance retrieves BTC Dominance. Path: /market/btc_dominance

func (*MarketService) BetaBtc7D

func (s *MarketService) BetaBtc7D(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

BetaBtc7D retrieves the 7-day beta to BTC. Path: /market/beta_btc_7d

func (*MarketService) GetRaw

func (s *MarketService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any market metric as raw JSON.

func (*MarketService) MVRV

func (s *MarketService) MVRV(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

MVRV retrieves the MVRV Ratio. Path: /market/mvrv

func (*MarketService) MarketCap

func (s *MarketService) MarketCap(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

MarketCap retrieves the market capitalization. Path: /market/marketcap_usd

func (*MarketService) Price

func (s *MarketService) Price(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

Price retrieves the market price. Path: /market/price_usd_close

func (*MarketService) PriceDrawdownFromATH

func (s *MarketService) PriceDrawdownFromATH(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

PriceDrawdownFromATH retrieves the price drawdown from all-time high. Path: /market/price_drawdown_relative

func (*MarketService) PriceOHLC

func (s *MarketService) PriceOHLC(ctx context.Context, q *MetricQuery) ([]ObjectPoint, error)

PriceOHLC retrieves the OHLC price. Path: /market/price_usd_ohlc

func (*MarketService) RealizedCap

func (s *MarketService) RealizedCap(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

RealizedCap retrieves the realized capitalization. Path: /market/marketcap_realized_usd

func (*MarketService) RealizedPrice

func (s *MarketService) RealizedPrice(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

RealizedPrice retrieves the realized price. Path: /market/price_realized_usd

func (*MarketService) RealizedVolatility1M

func (s *MarketService) RealizedVolatility1M(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

RealizedVolatility1M retrieves 1-month realized volatility. Path: /market/realized_volatility_1m

func (*MarketService) SpotVolume

func (s *MarketService) SpotVolume(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

SpotVolume retrieves spot trading volume. Path: /market/volume

func (*MarketService) SpotVolume24h

func (s *MarketService) SpotVolume24h(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

SpotVolume24h retrieves 24h spot trading volume. Path: /market/volume_usd_24h

type MempoolService

type MempoolService struct {
	// contains filtered or unexported fields
}

MempoolService provides access to the Mempool category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/mempool

func (*MempoolService) AverageRelativeFee

func (s *MempoolService) AverageRelativeFee(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

AverageRelativeFee retrieves the mempool average relative fee. Path: /mempool/fees_relative_mean

func (*MempoolService) GetRaw

func (s *MempoolService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any mempool metric as raw JSON.

func (*MempoolService) TotalAmountOfCoins

func (s *MempoolService) TotalAmountOfCoins(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

TotalAmountOfCoins retrieves the total amount of coins in the mempool. Path: /mempool/value_sum

func (*MempoolService) TotalAmountOfFees

func (s *MempoolService) TotalAmountOfFees(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

TotalAmountOfFees retrieves the total amount of fees in the mempool. Path: /mempool/fees_sum

func (*MempoolService) TransactionCount

func (s *MempoolService) TransactionCount(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

TransactionCount retrieves the mempool transaction count. Path: /mempool/count

func (*MempoolService) TransactionsSize

func (s *MempoolService) TransactionsSize(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

TransactionsSize retrieves the total size of mempool transactions. Path: /mempool/size_sum

type MetadataService

type MetadataService struct {
	// contains filtered or unexported fields
}

MetadataService provides access to the Glassnode metadata endpoints. Metadata is a first-class feature: use it to list supported assets, enumerate metric paths, inspect parameter capabilities, and determine whether bulk endpoints are available for a given metric.

Documentation: https://docs.glassnode.com/basic-api/metadata

func (*MetadataService) Assets

func (s *MetadataService) Assets(ctx context.Context, filter string) (*AssetsResponse, error)

Assets lists all assets and relevant metadata. The optional filter parameter accepts a CEL (Common Expression Language) expression to narrow results.

Documentation: https://docs.glassnode.com/basic-api/metadata#assets

func (*MetadataService) Metric

func (s *MetadataService) Metric(ctx context.Context, metricPath string, query *MetricQuery) (*MetricMetadata, error)

Metric retrieves metadata describing the available parameters and potential drill-down options for a specific metric. The path parameter is required (e.g. "/distribution/balance_exchanges"). Additional query parameters can be passed to refine the metadata query.

Documentation: https://docs.glassnode.com/basic-api/metadata#metric

func (*MetadataService) Metrics

func (s *MetadataService) Metrics(ctx context.Context, query *MetricQuery) ([]string, error)

Metrics lists all available metric paths. The returned paths include only the metric portion (e.g. "/addresses/count"), not the full "/v1/metrics" prefix. The optional query parameters (a, e, i, etc.) can be used to filter the list.

Documentation: https://docs.glassnode.com/basic-api/metadata#metrics

type MetricDescriptors

type MetricDescriptors struct {
	Name        string            `json:"name"`
	ShortName   string            `json:"short_name"`
	Group       string            `json:"group"`
	Tags        []string          `json:"tags"`
	Description map[string]string `json:"description"`
}

MetricDescriptors holds detailed information about a metric.

type MetricMetadata

type MetricMetadata struct {
	Path        string              `json:"path"`
	Tier        int                 `json:"tier"`
	IsPIT       bool                `json:"is_pit"`
	Parameters  map[string][]string `json:"parameters"`
	Queried     map[string]string   `json:"queried"`
	Timerange   *Timerange          `json:"timerange"`
	Modified    int64               `json:"modified"`
	Refs        *MetricRefs         `json:"refs"`
	Descriptors *MetricDescriptors  `json:"descriptors"`
}

MetricMetadata represents the response from metadata/metric.

type MetricQuery

type MetricQuery struct {
	// Asset (a) — asset id, e.g. BTC, ETH.
	Asset string
	// Since (s) — unix timestamp for the start of the data range.
	Since *int64
	// Until (u) — unix timestamp for the end of the data range.
	Until *int64
	// Resolution (i) — time interval, e.g. 24h, 1h.
	Resolution Resolution
	// Currency (c) — currency for values, e.g. native, usd.
	Currency Currency
	// Format (f) — response format, e.g. json, csv.
	Format Format
	// TimestampFormat — unix or humanized (RFC 3339).
	TimestampFormat TimestampFormat
	// Exchange (e) — exchange name, e.g. binance, coinbase.
	Exchange string
	// FromExchange — source exchange for inter-exchange metrics.
	FromExchange string
	// ToExchange — destination exchange for inter-exchange metrics.
	ToExchange string
	// Miner — miner identifier for mining-related metrics.
	Miner string
	// Maturity — maturity period for derivatives metrics.
	Maturity string
	// Network — network/blockchain identifier for cross-chain metrics.
	Network string
	// Period — time period for aggregation.
	Period string
	// QuoteSymbol — quote currency symbol for trading pairs.
	QuoteSymbol string
	// ExtraParams holds endpoint-specific parameters not covered by the
	// typed fields above. Values are URL-encoded and repeated keys are
	// supported by providing multiple values in the slice.
	ExtraParams map[string][]string
}

MetricQuery holds the common query parameters supported by Glassnode metric endpoints. Not all parameters apply to every metric — use the metadata endpoint to discover which parameters are valid for a given metric path.

func (*MetricQuery) ToValues

func (q *MetricQuery) ToValues() url.Values

ToValues converts the MetricQuery into url.Values suitable for use with the HTTP transport. Zero/empty values are omitted.

type MetricRefs

type MetricRefs struct {
	Docs          string        `json:"docs"`
	Studio        string        `json:"studio"`
	MetricVariant MetricVariant `json:"metric_variant"`
}

MetricRefs holds links to the metric in Studio, docs, and variants.

type MetricVariant

type MetricVariant struct {
	Base string `json:"base"`
	Bulk string `json:"bulk"`
	PIT  string `json:"pit"`
}

MetricVariant holds references to related metric variants.

type MetricsService

type MetricsService struct {
	// contains filtered or unexported fields
}

MetricsService provides generic access to any Glassnode metric endpoint. It guarantees coverage of every documented or future metric path without waiting for a typed wrapper.

Use Metadata.Metric to discover whether a metric supports bulk endpoints (bulk_supported field) before calling GetBulk.

Documentation: https://docs.glassnode.com/basic-api/endpoints

func (*MetricsService) Get

func (s *MetricsService) Get(ctx context.Context, metricPath string, query *MetricQuery) (json.RawMessage, error)

Get retrieves a single metric as a raw JSON response. This method safely calls every valid metric path, even if no convenience wrapper exists. The metricPath should be the metric portion only (e.g. "/indicators/sopr"), without the "/v1/metrics" prefix.

The returned json.RawMessage can be unmarshaled into []TimePoint, []ObjectPoint, []PITTimePoint, or []PITObjectPoint depending on the metric's response shape. When query.Format is FormatCSV, it instead contains the unmodified CSV response bytes. Use the metadata endpoint to determine the expected shape.

Documentation: https://docs.glassnode.com/basic-api/endpoints

func (*MetricsService) GetBulk

func (s *MetricsService) GetBulk(ctx context.Context, metricPath string, query *BulkQuery) (*BulkResponse, error)

GetBulk retrieves a bulk metric response. The metricPath should be the regular metric's path (e.g. "/market/mvrv"); the "/bulk" suffix is appended automatically. Always specify assets explicitly in the BulkQuery to control credit consumption.

Documentation: https://docs.glassnode.com/basic-api/bulk-metrics

func (*MetricsService) GetBulkRaw

func (s *MetricsService) GetBulkRaw(ctx context.Context, metricPath string, query *BulkQuery) (json.RawMessage, error)

GetBulkRaw retrieves a bulk metric response as raw JSON, for endpoints whose bulk shape cannot be safely represented with BulkResponse.

func (*MetricsService) GetObjectPoints

func (s *MetricsService) GetObjectPoints(ctx context.Context, metricPath string, query *MetricQuery) ([]ObjectPoint, error)

GetObjectPoints retrieves a metric and decodes it as a slice of ObjectPoint (object time-series: {"t":..., "o":...}).

func (*MetricsService) GetTimePoints

func (s *MetricsService) GetTimePoints(ctx context.Context, metricPath string, query *MetricQuery) ([]TimePoint, error)

GetTimePoints retrieves a metric and decodes it as a slice of TimePoint (scalar time-series: {"t":..., "v":...}).

type MiningService

type MiningService struct {
	// contains filtered or unexported fields
}

MiningService provides access to the Mining category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/mining

func (*MiningService) Difficulty

func (s *MiningService) Difficulty(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

Difficulty retrieves the mining difficulty. Path: /mining/difficulty_latest

func (*MiningService) GetRaw

func (s *MiningService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any mining metric as raw JSON.

func (*MiningService) HashRate

func (s *MiningService) HashRate(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

HashRate retrieves the network hash rate. Path: /mining/hash_rate_mean

func (*MiningService) MinerRevenueBlockRewards

func (s *MiningService) MinerRevenueBlockRewards(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

MinerRevenueBlockRewards retrieves miner revenue from block rewards. Path: /mining/revenue_from_rewards

func (*MiningService) MinerRevenueFees

func (s *MiningService) MinerRevenueFees(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

MinerRevenueFees retrieves miner revenue from fees. Path: /mining/revenue_from_fees

func (*MiningService) MinerRevenueTotal

func (s *MiningService) MinerRevenueTotal(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

MinerRevenueTotal retrieves total miner revenue. Path: /mining/revenue_sum

func (*MiningService) Thermocap

func (s *MiningService) Thermocap(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

Thermocap retrieves the Thermocap metric. Path: /mining/thermocap

type ObjectPoint

type ObjectPoint struct {
	T int64           `json:"t"`
	O json.RawMessage `json:"o"`
}

ObjectPoint represents an object-valued time-series data point: {"t": <unix-timestamp>, "o": {...}}.

type Option

type Option func(*Client)

Option configures a Client. Options are applied in the order they are passed to NewClient.

func WithAPIKey

func WithAPIKey(key string) Option

WithAPIKey sets the API key used for authentication. This is typically passed to NewClient directly, but this option allows overriding it.

func WithAppID

func WithAppID(id string) Option

WithAppID appends an application identifier to the User-Agent header, separated by a space. This allows services to identify themselves without leaking secrets.

func WithAuthMode

func WithAuthMode(mode AuthMode) Option

WithAuthMode sets the authentication mode. AuthModeHeader (default) sends the key via the X-Api-Key header. AuthModeQuery sends it via the api_key query parameter, which is less secure.

func WithBaseURL

func WithBaseURL(url string) Option

WithBaseURL overrides the default Glassnode API base URL (https://api.glassnode.com). This is primarily useful for testing against a mock server.

func WithHTTPClient

func WithHTTPClient(client *http.Client) Option

WithHTTPClient sets a custom *http.Client used to perform requests. This allows callers to configure transport-level behaviour such as proxies, TLS settings, or custom RoundTrippers.

func WithRetry

func WithRetry(maxAttempts int, baseDelay time.Duration) Option

WithRetry configures automatic retry behaviour for HTTP 429 (rate limited) responses. maxAttempts is the total number of attempts (including the first one) and baseDelay is the initial backoff delay used for exponential backoff. When the x-rate-limit-reset response header is present and valid, that value takes precedence.

func WithTimeout

func WithTimeout(d time.Duration) Option

WithTimeout sets the timeout applied to the underlying HTTP client for every request made by the Client.

func WithUserAgent

func WithUserAgent(ua string) Option

WithUserAgent sets the User-Agent header value. The SDK name and version are included by default; this option overrides the entire value.

type OptionsService

type OptionsService struct {
	// contains filtered or unexported fields
}

OptionsService provides access to the Options category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/options

func (*OptionsService) GetRaw

func (s *OptionsService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any options metric as raw JSON.

func (*OptionsService) ImpliedVolatility

func (s *OptionsService) ImpliedVolatility(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

ImpliedVolatility retrieves ATM implied volatility. Path: /options/iv_atm

func (*OptionsService) MaxPain

func (s *OptionsService) MaxPain(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

MaxPain retrieves the options max pain. Path: /options/max_pain

func (*OptionsService) OpenInterest

func (s *OptionsService) OpenInterest(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

OpenInterest retrieves options open interest. Path: /options/open_interest_sum

func (*OptionsService) PutCallRatio

func (s *OptionsService) PutCallRatio(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

PutCallRatio retrieves the options put/call ratio. Path: /options/volume_put_call_ratio

func (*OptionsService) Volume

func (s *OptionsService) Volume(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

Volume retrieves options volume. Path: /options/volume_sum

type PITObjectPoint

type PITObjectPoint struct {
	T          int64           `json:"t"`
	O          json.RawMessage `json:"o"`
	ComputedAt int64           `json:"computed_at,omitempty"`
}

PITObjectPoint represents a point-in-time object-valued data point: {"t": <unix-timestamp>, "o": {...}, "computed_at": <unix-timestamp>}.

type PITTimePoint

type PITTimePoint struct {
	T          int64   `json:"t"`
	V          float64 `json:"v"`
	ComputedAt int64   `json:"computed_at,omitempty"`
}

PITTimePoint represents a point-in-time scalar data point that includes a computed_at timestamp: {"t": <unix-timestamp>, "v": <value>, "computed_at": <unix-timestamp>}.

type PointInTimeService

type PointInTimeService struct {
	// contains filtered or unexported fields
}

PointInTimeService provides access to the Point-In-Time category endpoints. Point-in-Time metrics include a computed_at timestamp indicating when the data point was computed, which is important for backtesting and historical analysis.

Documentation: https://docs.glassnode.com/basic-api/endpoints/pit

func (*PointInTimeService) GetPITObjectPoints

func (s *PointInTimeService) GetPITObjectPoints(ctx context.Context, metricPath string, q *MetricQuery) ([]PITObjectPoint, error)

GetPITObjectPoints retrieves a PIT metric and decodes it as PITObjectPoint.

func (*PointInTimeService) GetPITTimePoints

func (s *PointInTimeService) GetPITTimePoints(ctx context.Context, metricPath string, q *MetricQuery) ([]PITTimePoint, error)

GetPITTimePoints retrieves a PIT metric and decodes it as PITTimePoint.

func (*PointInTimeService) GetRaw

func (s *PointInTimeService) GetRaw(ctx context.Context, metricPath string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any point-in-time metric as raw JSON. The metricName should be the full metric path (e.g. "/indicators/sopr_pit").

type ProtocolsService

type ProtocolsService struct {
	// contains filtered or unexported fields
}

ProtocolsService provides access to the Protocols category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/protocols

func (*ProtocolsService) AaveV3AvailableLiquidity

func (s *ProtocolsService) AaveV3AvailableLiquidity(ctx context.Context, q *MetricQuery) ([]ObjectPoint, error)

AaveV3AvailableLiquidity retrieves Aave V3 available liquidity by token. Path: /protocols/aave-v3/tvl_by_token

func (*ProtocolsService) GetRaw

func (s *ProtocolsService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any protocols metric as raw JSON.

func (*ProtocolsService) UniswapTVLPerFeeTier

func (s *ProtocolsService) UniswapTVLPerFeeTier(ctx context.Context, q *MetricQuery) ([]ObjectPoint, error)

UniswapTVLPerFeeTier retrieves Uniswap TVL per fee tier. Path: /protocols/uniswap/tvl_per_fee_tier

type RawResponse

type RawResponse struct {
	Raw json.RawMessage `json:"-"`
}

RawResponse wraps a raw JSON response for endpoints whose response shape cannot be safely represented with a stable struct. The Raw field contains the original decoded JSON.

type Resolution

type Resolution string

Resolution represents a supported time interval for Glassnode metrics. The official documented resolutions include 10m, 1h, 24h, 1w, and 1month, subject to metric and subscription-plan availability.

const (
	Resolution10m    Resolution = "10m"
	Resolution1h     Resolution = "1h"
	Resolution24h    Resolution = "24h"
	Resolution1w     Resolution = "1w"
	Resolution1month Resolution = "1month"
)

Supported resolution values.

type ResponseMetadata

type ResponseMetadata struct {
	// StatusCode is the HTTP status code.
	StatusCode int
	// RateLimitLimit is the value of the x-rate-limit-limit header.
	RateLimitLimit string
	// RateLimitRemaining is the value of the x-rate-limit-remaining
	// header.
	RateLimitRemaining string
	// RateLimitReset is the value of the x-rate-limit-reset header
	// (seconds until the limit resets).
	RateLimitReset string
	// RequestID is the value of the X-Request-ID header, if present.
	RequestID string
	// Duration is the time taken for the HTTP round-trip.
	Duration time.Duration
	// FinalURL is the redacted final URL of the request. If query-string
	// authentication is used, the api_key value is replaced with
	// "[REDACTED]".
	FinalURL string
}

ResponseMetadata holds non-body information from an HTTP response. It is returned alongside the decoded payload so applications can inspect rate-limit headers, request IDs, and timing.

type SignalsService

type SignalsService struct {
	// contains filtered or unexported fields
}

SignalsService provides access to the Signals category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/signals

func (*SignalsService) AltcoinCycleSignal

func (s *SignalsService) AltcoinCycleSignal(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

AltcoinCycleSignal retrieves the Altcoin Cycle Signal. Path: /signals/altcoin_cycle_signal

func (*SignalsService) BSSGoldilocksSignal

func (s *SignalsService) BSSGoldilocksSignal(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

BSSGoldilocksSignal retrieves the BSS Goldilocks Signal. Path: /signals/bss_goldilocks_signal

func (*SignalsService) BitcoinRiskSignal

func (s *SignalsService) BitcoinRiskSignal(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

BitcoinRiskSignal retrieves the Bitcoin Risk Signal. Path: /signals/bitcoin_risk_signal

func (*SignalsService) BitcoinSharpeSignal

func (s *SignalsService) BitcoinSharpeSignal(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

BitcoinSharpeSignal retrieves the Bitcoin Sharpe Signal. Path: /signals/bitcoin_sharpe_signal

func (*SignalsService) EcosystemMomentumSignal

func (s *SignalsService) EcosystemMomentumSignal(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

EcosystemMomentumSignal retrieves the Ecosystem Momentum Signal. Path: /signals/ecosystem_momentum_signal

func (*SignalsService) GetRaw

func (s *SignalsService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any signals metric as raw JSON.

type SupplyService

type SupplyService struct {
	// contains filtered or unexported fields
}

SupplyService provides access to the Supply category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/supply

func (*SupplyService) ActiveSupply

func (s *SupplyService) ActiveSupply(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

ActiveSupply retrieves the active supply. Path: /supply/active

func (*SupplyService) CirculatingSupply

func (s *SupplyService) CirculatingSupply(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

CirculatingSupply retrieves the circulating supply. Path: /supply/current

func (*SupplyService) GetRaw

func (s *SupplyService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any supply metric as raw JSON.

func (*SupplyService) HODLWaves

func (s *SupplyService) HODLWaves(ctx context.Context, q *MetricQuery) ([]ObjectPoint, error)

HODLWaves retrieves the HODL Waves distribution. Path: /supply/hodl_waves

func (*SupplyService) InflationRate

func (s *SupplyService) InflationRate(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

InflationRate retrieves the inflation rate. Path: /supply/inflation_rate

func (*SupplyService) LongTermHolderSupply

func (s *SupplyService) LongTermHolderSupply(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

LongTermHolderSupply retrieves the long-term holder supply. Path: /supply/lth

func (*SupplyService) ProfitableSupply

func (s *SupplyService) ProfitableSupply(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

ProfitableSupply retrieves the supply in profit. Path: /supply/profit_relative

func (*SupplyService) ShortTermHolderSupply

func (s *SupplyService) ShortTermHolderSupply(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

ShortTermHolderSupply retrieves the short-term holder supply. Path: /supply/sth

type TimePoint

type TimePoint struct {
	T int64   `json:"t"`
	V float64 `json:"v"`
}

TimePoint represents a standard scalar time-series data point: {"t": <unix-timestamp>, "v": <value>}.

type Timerange

type Timerange struct {
	Min int64 `json:"min"`
	Max int64 `json:"max"`
}

Timerange holds the minimum and maximum available timestamps.

type TimestampFormat

type TimestampFormat string

TimestampFormat represents the timestamp format in responses.

const (
	TimestampUnix      TimestampFormat = "unix"
	TimestampHumanized TimestampFormat = "humanized"
)

Supported timestamp format values.

type TransactionsService

type TransactionsService struct {
	// contains filtered or unexported fields
}

TransactionsService provides access to the Transactions category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/transactions

func (*TransactionsService) Count

Count retrieves the transaction count. Path: /transactions/count

func (*TransactionsService) ExchangeDeposits

func (s *TransactionsService) ExchangeDeposits(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

ExchangeDeposits retrieves the number of exchange deposits. Path: /transactions/deposits_count

func (*TransactionsService) ExchangeWithdrawals

func (s *TransactionsService) ExchangeWithdrawals(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

ExchangeWithdrawals retrieves the number of exchange withdrawals. Path: /transactions/withdrawals_count

func (*TransactionsService) GetRaw

func (s *TransactionsService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any transactions metric as raw JSON.

func (*TransactionsService) Rate

Rate retrieves the transaction rate. Path: /transactions/rate

func (*TransactionsService) SizeMean

func (s *TransactionsService) SizeMean(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

SizeMean retrieves the mean transaction size. Path: /transactions/size_mean

func (*TransactionsService) SizeTotal

func (s *TransactionsService) SizeTotal(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

SizeTotal retrieves the total transaction size. Path: /transactions/size_sum

func (*TransactionsService) TransferVolumeMean

func (s *TransactionsService) TransferVolumeMean(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

TransferVolumeMean retrieves the mean transfer volume. Path: /transactions/volume_mean

func (*TransactionsService) TransferVolumeTotal

func (s *TransactionsService) TransferVolumeTotal(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

TransferVolumeTotal retrieves the total transfer volume. Path: /transactions/volume_sum

type TreasuriesService

type TreasuriesService struct {
	// contains filtered or unexported fields
}

TreasuriesService provides access to the Treasuries category endpoints.

Documentation: https://docs.glassnode.com/basic-api/endpoints/treasuries

func (*TreasuriesService) GetRaw

func (s *TreasuriesService) GetRaw(ctx context.Context, metricName string, q *MetricQuery) (json.RawMessage, error)

GetRaw retrieves any treasuries metric as raw JSON.

func (*TreasuriesService) TreasuryBalancesCompanies

func (s *TreasuriesService) TreasuryBalancesCompanies(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

TreasuryBalancesCompanies retrieves treasury balances for companies. Path: /treasuries/balance_companies

func (*TreasuriesService) TreasuryBalancesGovernments

func (s *TreasuriesService) TreasuryBalancesGovernments(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

TreasuryBalancesGovernments retrieves treasury balances for governments. Path: /treasuries/balance_governments

func (*TreasuriesService) TreasuryCountCompanies

func (s *TreasuriesService) TreasuryCountCompanies(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

TreasuryCountCompanies retrieves the treasury count for companies. Path: /treasuries/count_companies

func (*TreasuriesService) TreasuryNetFlowsCompanies

func (s *TreasuriesService) TreasuryNetFlowsCompanies(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

TreasuryNetFlowsCompanies retrieves treasury net flows for companies. Path: /treasuries/flows_companies

func (*TreasuriesService) TreasuryNetFlowsGovernments

func (s *TreasuriesService) TreasuryNetFlowsGovernments(ctx context.Context, q *MetricQuery) ([]TimePoint, error)

TreasuryNetFlowsGovernments retrieves treasury net flows for governments. Path: /treasuries/flows_governments

type UserService

type UserService struct {
	// contains filtered or unexported fields
}

UserService provides access to the Glassnode user endpoints.

func (*UserService) APIUsage

func (s *UserService) APIUsage(ctx context.Context) (*APIUsage, error)

APIUsage retrieves the current month's API credit usage. The response includes a creditsUsed field indicating how many data credits have been consumed.

Documentation: https://docs.glassnode.com/basic-api/api-credits

Directories

Path Synopsis
examples
basic command
bulk command
error_handling command
metadata command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL