Use the Santiment GraphQL API to fetch cryptocurrency market data — on-chain metrics (active addresses, NVT, MVRV, exchange flows), social sentiment, development activity, financial data (price, volume, marketcap), NFT metrics, and custom SQL queries. Use when working with crypto data, Santiment, sanpy Python library, or any task requiring blockchain analytics. Covers authentication, all query patterns, rate limits, and 1000+ metrics across 12+ blockchains.
Read API key from SANTIMENT_API_KEY env var (or SANPY_APIKEY — sanpy auto-reads this natively).
Obtain key: https://app.santiment.net/account. Pass as header: Authorization: Apikey <key>.
Some metrics are free (no key needed), but rate limits still apply.
curl -X POST -H "Content-Type: application/json" \
-H "Authorization: Apikey $SANTIMENT_API_KEY" \
--data '{"query": "{ currentUser { id email } }"}' \
https://api.santiment.net/graphql
import os, san
san.ApiConfig.api_key = os.environ["SANTIMENT_API_KEY"]
— POST, , body: . Explorer: | (supports auth headers)
https://api.santiment.net/graphqlContent-Type: application/json{"query": "..."}"bitcoin", "ethereum", etc. Look up: { projectBySlug(slug: "bitcoin") { slug name ticker } }getMetric(metric: "<name>"). Names are snake_case. Some use hyphens for time windows (e.g., dev_activity-1d)"1d", "1h", "30m", "1w". Check min via metadata { minInterval }"utc_now", "utc_now-7d". In intervals m=minutes; in dates m=monthsAVG, SUM, MIN, MAX, LAST, FIRST, MEDIAN, ANY{
getMetric(metric: "daily_active_addresses") {
timeseriesData(slug: "ethereum", from: "utc_now-7d", to: "utc_now", interval: "1d") {
datetime
value
}
}
}
Python: san.get("daily_active_addresses", slug="ethereum", from_date="2024-01-01", to_date="2024-01-31", interval="1d")
Use timeseriesDataJson for compact JSON output. Add includeIncompleteData: true to include current incomplete interval.
{
getMetric(metric: "price_usd") {
timeseriesDataPerSlugJson(
selector: { slugs: ["bitcoin", "ethereum"] }
from: "utc_now-7d", to: "utc_now", interval: "1d")
}
}
Python: san.get_many("price_usd", slugs=["bitcoin", "ethereum"], from_date="2024-01-01", to_date="2024-01-31", interval="1d")
{
getMetric(metric: "daily_active_addresses") {
aggregatedTimeseriesData(slug: "ethereum", from: "utc_now-30d", to: "utc_now", aggregation: AVG)
}
}
{
getMetric(metric: "dev_activity") {
timeseriesDataJson(slug: "ethereum", from: "utc_now-365d", to: "utc_now", interval: "7d",
transform: { type: "moving_average", movingAverageBase: 4 })
}
}
Types: "moving_average" (needs movingAverageBase), "consecutive_differences".
{
getMetric(metric: "age_distribution") {
histogramData(slug: "santiment", from: "2024-01-01T00:00:00Z", to: "2024-03-01T00:00:00Z", interval: "1d") {
values {
... on DatetimeRangeFloatValueList { data { range value } }
... on FloatRangeFloatValueList { data { range value } }
}
}
}
}
Include both inline fragments — union type varies by metric.
{ getAvailableMetrics }
{ getAvailableMetrics(product: SANAPI, plan: BUSINESS_PRO) }
{ projectBySlug(slug: "ethereum") { availableMetrics } }
{
getMetric(metric: "daily_active_addresses") {
metadata { metric defaultAggregation minInterval dataType }
availableSince(slug: "ethereum")
}
}
{
getAccessRestrictions(product: SANAPI, plan: FREE, filter: METRIC) {
name isAccessible isRestricted isDeprecated restrictedFrom restrictedTo
}
}
Python: san.available_metrics(), san.available_metrics_for_slug("ethereum"), san.metadata("daily_active_addresses")
Raw GraphQL: san.graphql.execute_gql('{ getMetric(metric: "price_usd") { aggregatedTimeseriesData(slug: "bitcoin", from: "utc_now-1d", to: "utc_now", aggregation: LAST) } }')
batch = san.AsyncBatch()
batch.get("daily_active_addresses", slug="bitcoin", from_date="2024-01-01", to_date="2024-01-31", interval="1d")
batch.get("price_usd", slug="bitcoin", from_date="2024-01-01", to_date="2024-01-31", interval="1d")
results = batch.execute() # list of DataFrames, default 10 workers
"errors" key in response JSONavailableSince or handle null"5m" interval = 5 minutes; "utc_now-3m" = 3 monthsincludeIncompleteData: trueallProjects — unpaginated returns everything{"data": null, "errors": [{"message": "..."}]} — HTTP 429 = rate limited, 5xx = server errorfunction arg is a stringified JSON string. Enums are lowercase. Returns { projects { ... } }pip install sanpy
import os, san
san.ApiConfig.api_key = os.environ["SANTIMENT_API_KEY"]
df = san.get("price_usd", slug="bitcoin", from_date="2024-01-01", to_date="2024-01-31", interval="1d")
df = san.get_many("price_usd", slugs=["bitcoin", "ethereum"], from_date="2024-01-01", to_date="2024-01-31", interval="1d")
df = san.execute_sql(query="SELECT * FROM daily_metrics_v2 LIMIT 5")
result = san.graphql.execute_gql('{ getMetric(metric: "price_usd") { aggregatedTimeseriesData(slug: "bitcoin", from: "utc_now-1d", to: "utc_now", aggregation: LAST) } }')
Read these files as needed for detailed information:
allProjectsByFunction with full JSON structurecomputeRawClickhouseQuery)