Metric Versions

Overview

Some metrics in the Santiment API have multiple versions. Each version represents a different implementation, calculation methodology, or underlying data source used to compute the metric.

You can select the desired version using the version parameter in the getMetric query.

Different versions of the same metric typically exist when improvements are made to the calculation process or when the metric starts using a different dataset. This allows us to introduce enhancements without altering the historical behavior of existing versions.

For example, social metrics have a modern:v1 version that is computed on a dataset of currently active Crypto Twitter users, alongside the long-running original:v1 dataset. See Social Data Versions for the list of social versions and when to use each one.

Adding new social accounts or servers to an existing metric version could change its historical values. Alternatively, if historical recomputation is not performed, the introduction of new sources may create artificial spikes in the data. These spikes do not reflect real changes in social activity but are simply the result of expanding the underlying data coverage.

This page covers version semantics in detail. For a general introduction to getMetric and its fields, see Fetching Metrics.

Finding Versions

To get versions for a single metric, execute:

{
getMetric(metric: "social_volume_total") {
metadata {
availableVersions {
version
versionName
}
}
}
}

To get versions for all metrics, execute:

{
getAccessRestrictions(filter: METRIC) {
name
availableVersions {
version
versionName
}
}
}

To get versions for a specific product and plan, execute:

{
getAccessRestrictions(product: SANAPI, plan: BUSINESS_PRO, filter: METRIC) {
name
isAccessible
availableVersions {
version
versionName
}
}
}

Why Metrics Have Versions

Analytical methodologies evolve over time. When Santiment improves how a metric is calculated, the updated logic is published as a new version rather than overwriting the original. This approach provides several benefits:

  • Historical stability — data you have already queried or stored does not change retroactively, because the original version continues to return the same results.
  • Backward compatibility — existing integrations, dashboards, and alerts keep working without modification.
  • Side-by-side comparison — you can compare the old and new calculation to understand how the methodology has changed before migrating.

How Versions Work

Each version is identified by a version string. Most metrics use simple numeric strings like "1.0" and "2.0". Social metrics also have named social data versions: "original:v1", "modern:v1", and "modern_pit:v1". Experimental versions use descriptive names such as "Experimental (Weighted Age)".

Each entry in availableVersions has these fields:

FieldDescriptionExample
versionThe numeric version string"2.0"
versionNameThe version name, used for social metrics"modern:v1"
versionNumThe numeric version, same as version"2.0"
descriptionA short description of the computation"Modern computation, v1."

For social metrics, the names map to numbers like this:

versionNameversion
original:v11.0
modern:v12.0
modern_pit:v12.1

Key points:

  • Every non-social metric has at least version "1.0". Every social metric has at least version "original:v1".
  • The version parameter scopes the entire getMetric context — all subfields (timeseries data, available slugs, available since, etc.) return data for that version.
  • Numeric versions are sorted in semantic order: "1.0" < "2.0" < "3.0", with experimental versions listed after stable ones.

Querying a Specific Version

Pass the version argument to getMetric. When omitted, it defaults to "1.0", or to "original:v1" for social metrics.

{
getMetric(metric: "social_volume_total", version: "original:v1") {
timeseriesDataJson(
slug: "bitcoin"
from: "utc_now-30d"
to: "utc_now"
interval: "1d"
)
}
}

Omitting the version parameter is equivalent to specifying the default version. For the social metric below, that is version: "original:v1":

{
noVersion: getMetric(metric: "social_volume_total") {
timeseriesDataJson(
slug: "bitcoin"
from: "utc_now-7d"
to: "utc_now"
interval: "1d"
)
}
# Will return the same data as noVersion, as original:v1 is the default
original: getMetric(metric: "social_volume_total", version: "original:v1") {
timeseriesDataJson(
slug: "bitcoin"
from: "utc_now-7d"
to: "utc_now"
interval: "1d"
)
}
modern: getMetric(metric: "social_volume_total", version: "modern:v1") {
timeseriesDataJson(
slug: "bitcoin"
from: "utc_now-7d"
to: "utc_now"
interval: "1d"
)
}
}

The noVersion and original aliases above return identical results.

Using Versions in Sanpy

The sanpy Python library (0.12.6+) supports versioned metrics. You can check which versions a metric has and pass the desired version to san.get or san.get_many.

Check available versions for a metric:

import san
san.available_metric_versions("social_dominance_total")
# ['1.0', '2.0', '2.1']

available_metric_versions returns the numeric version values. To get the version names, query versionName through the API.

Fetch data for a specific version:

import san
san.get(
"social_dominance_total",
slug="bitcoin",
from_date="2026-01-01",
to_date="2026-01-10",
interval="1d",
version="modern:v1"
)
san.get_many(
"social_dominance_total",
slugs=["bitcoin", "ethereum"],
from_date="2026-01-01",
to_date="2026-01-10",
interval="1d",
version="modern:v1"
)

When version is omitted, the default version ("1.0", or "original:v1" for social metrics) is used — the same behavior as the GraphQL API.

The santiment-research-quickstart repository contains additional examples and Agent skills that can work with versioned metrics.

Discovering Available Versions

For a Single Metric

Use the availableVersions field inside the metadata query:

{
getMetric(metric: "social_volume_total") {
metadata {
availableVersions {
version
versionName
}
}
}
}
{
"data": {
"getMetric": {
"metadata": {
"availableVersions": [
{
"version": "1.0",
"versionName": "original:v1"
},
{
"version": "2.0",
"versionName": "modern:v1"
},
{
"version": "2.1",
"versionName": "modern_pit:v1"
}
]
}
}
}
}

Most non-social metrics only have version "1.0". Metrics with multiple versions will list all of them.

For All Metrics

Use the availableVersions field on the getAccessRestrictions query to fetch versions for every metric at once:

{
getAccessRestrictions(filter: METRIC) {
name
availableVersions {
version
versionName
}
}
}

For a specific product and plan, execute:

{
getAccessRestrictions(product: SANAPI, plan: BUSINESS_PRO, filter: METRIC) {
name
isAccessible
availableVersions {
version
versionName
}
}
}
{
"data": {
"getAccessRestrictions": [
{
"name": "social_volume_total",
"isAccessible": true,
"availableVersions": [
{
"version": "1.0",
"versionName": "original:v1"
},
{
"version": "2.0",
"versionName": "modern:v1"
},
{
"version": "2.1",
"versionName": "modern_pit:v1"
}
]
}
]
}
}

Version Access by Plan

Newer social data versions need a higher subscription plan than the default "original:v1":

VersionMinimum SanAPI plan
"original:v1"Follows the metric’s normal access rules
"modern:v1"Business Pro or Business Max
"modern_pit:v1"Business Max, paid yearly

If you request a version your plan does not include, that getMetric alias returns null and the response has an error like this one:

Metric version modern_pit:v1 requires a paid yearly SanAPI Business Max subscription. Anonymous requests have access to original:v1.

Other aliases in the same request still return data.

Version-Aware Fields

The version parameter on getMetric affects the following fields:

FieldEffect
timeseriesDataJsonReturns timeseries data for the specified version
timeseriesDataPerSlugJsonReturns per-slug timeseries data for the specified version
aggregatedTimeseriesDataReturns the aggregated value computed from the specified version
histogramDataReturns histogram buckets for the specified version
availableSlugs / availableProjectsReturns only the assets that have data for the specified version
availableSinceReturns the first available date for the specified version
⚠️

availableSince without a version argument returns the start date of the default version ("1.0", or "original:v1" for social metrics), not of the newest version. Before you backtest on a newer version, pass that version explicitly (see the availableSince comparison in Comparing Versions). A value of 1970-01-01T00:00:00Z means the version has no data for that asset.

Update Lag per Version

Versions of the same metric do not all finalize a bar at the same time. This affects how soon after a bar closes you can treat its value as final:

VersionWhen a bar is finalNotes
"original:v1" (default)Up to ~12 hours after the bar closesDocuments that arrive late are added for up to 12 hours, so recent values can still go up. Changes to labels or sources can also trigger a recalculation of the previous month.
"modern:v1"Up to ~12 hours after the bar closesDocuments that arrive late are added for up to 12 hours, so recent values can still go up. History is not recalculated when labels or sources change.
"modern_pit:v1" (point-in-time)~15–30 minutes after the 15-minute window closesComputed once, 15 minutes after the window ends, for example [00:00, 00:15) at 00:30. Documents that arrive more than 30 minutes after publication are never included, so the value does not change later.

If you compare "original:v1" and "modern_pit:v1" for the most recent hours, expect the "original:v1" values to keep changing while the "modern_pit:v1" values stay fixed.

Comparing Versions

You can compare versioned query outputs side-by-side in a single request by using GraphQL aliases.

{
original: getMetric(metric: "social_volume_total", version: "original:v1") {
timeseriesDataJson(
slug: "bitcoin"
from: "utc_now-7d"
to: "utc_now"
interval: "1d"
)
}
modern: getMetric(metric: "social_volume_total", version: "modern:v1") {
timeseriesDataJson(
slug: "bitcoin"
from: "utc_now-7d"
to: "utc_now"
interval: "1d"
)
}
}

The response contains both original and modern objects so you can compare the two datasets. After discovering additional versions from availableVersions, replace version: "modern:v1" with the desired version string and rerun the query. You can apply the same pattern to compare availability:

{
original: getMetric(metric: "social_volume_total", version: "original:v1") {
availableSince(slug: "bitcoin")
}
modern: getMetric(metric: "social_volume_total", version: "modern:v1") {
availableSince(slug: "bitcoin")
}
}

Experimental Versions

Some metrics have experimental versions with descriptive names like "Experimental (Weighted Age)". These differ from stable versions in several ways:

  • Access requirements — experimental versions are only accessible to users with alpha-level metric access. Querying an experimental version without the required access level returns an error.
  • Naming convention — experimental version strings start with "Experimental" followed by a short description in parentheses, making them easy to identify in the availableVersions list.
  • Stability — experimental versions may change without notice. They are intended for testing and evaluation, not for production use.

Default Behavior and Backward Compatibility

  • No version = default version — if you do not provide a version parameter, the API defaults to "1.0", or to "original:v1" for social metrics. This means all existing queries that were written before versions were introduced continue to work exactly as before.
  • Existing integrations are unaffected — introducing a new version of a metric does not change the behavior of the default version. Your dashboards, alerts, and scripts will keep returning the same data.
  • Pin versions in production — if you rely on a specific version, pass it explicitly (e.g. version: "1.0" or version: "modern:v1") rather than relying on the default. This protects your integration even if the default changes in the future.