Snapshot API
La Snapshot API renderiza gráficos de analítica on-chain como imágenes PNG o gráficos vectoriales SVG. Envíe los IDs de las métricas y parámetros de visualización opcionales, y reciba una imagen de gráfico completamente renderizada lista para incrustar en informes, dashboards o conversaciones con IA. Actualmente admite métricas de Bitcoin, con una cobertura multi-cadena (ETH, TON, TRON) en expansión.
Endpoints
| Método | Ruta | Descripción |
|---|---|---|
GET | /v1/chart/snapshot | Gráficos simples mediante parámetros de consulta |
POST | /v1/chart/snapshot | Personalización completa mediante cuerpo JSON |
Ambos endpoints devuelven image/png de forma predeterminada. Cambie a SVG (image/svg+xml) o metadatos JSON (application/json) configurando la cabecera de solicitud Accept, o —en POST— el campo format del cuerpo ("png", "svg", "json").
Las respuestas correctas en PNG y SVG incluyen una cabecera X-Render-Id para que el gráfico renderizado pueda volver a obtenerse por URL durante 1 hora:
| Salida | Cacheado en |
|---|---|
| PNG | https://api.blocklens.co/v1/chart/renders/{X-Render-Id}.png |
| SVG | https://api.blocklens.co/v1/chart/renders/{X-Render-Id}.svg |
Autenticación
Todas las solicitudes requieren una clave API mediante la cabecera Authorization:
Authorization: Bearer YOUR_API_KEY
Consulte Autenticación para más detalles sobre cómo obtener claves API.
Acceso y límites de tasa
La Snapshot API requiere el nivel Pro o Enterprise. Las claves de los niveles Demo y Free reciben 403 Forbidden.
La Snapshot API sigue los mismos límites de tasa que la Data API. Consulte Límites de tasa para más detalles.
Cuando se aplica el límite de tasa, la API devuelve 429 Too Many Requests con un campo retry_after.
El acceso a las métricas también está restringido por grado: las métricas de grado 0 (precio, oferta, MVRV) están disponibles para todas las claves Pro+, las métricas de grado 1 (SOPR, P&L) requieren Pro, y las métricas de grado 2 (mapas de calor CBD) requieren Enterprise.
GET /v1/chart/snapshot
Genera un gráfico a partir de parámetros de consulta. Ideal para gráficos simples, de métrica única o basados en plantillas.
Parámetros
| Parámetro | Tipo | Predeterminado | Descripción |
|---|---|---|---|
metric | string | - | ID de una sola métrica (p. ej., price, lth_supply). Mutuamente excluyente con metrics y template. |
metrics | string | - | IDs de métricas separados por comas, máximo 6 (p. ej., lth_supply,sth_supply). Mutuamente excluyente con metric y template. |
template | string | - | ID de plantilla predefinida. Mutuamente excluyente con metric y metrics. |
days | integer | 365 | Días de datos históricos (7-10000). |
start_date | string | - | Fecha de inicio (YYYY-MM-DD). Reemplaza a days. |
end_date | string | - | Fecha de fin (YYYY-MM-DD). Por defecto, hoy. |
style | string | auto | Estilo del gráfico: line, area, bar. Detectado automáticamente del registro de métricas si se omite. |
scale | string | linear | Escala del eje Y: linear o log. |
overlay | string | - | Añade una superposición de precio como una línea discontinua sutil en el eje derecho (use price). Actualmente, precio de BTC. |
width | integer | 1200 | Ancho de la imagen en píxeles (600-2400). |
height | integer | 600 | Alto de la imagen en píxeles (300-1200). |
title | string | auto | Título del gráfico. Generado automáticamente a partir de los nombres de las métricas si se omite. |
theme | string | light | Tema de color: light o dark. |
Debe proporcionarse exactamente uno de metric, metrics o template.
Plantillas disponibles
| Plantilla | Métricas |
|---|---|
price | Precio de BTC |
price_volume | Precio + Volumen |
market_cap | Market Cap |
holder_supply | Oferta LTH + Oferta STH |
mvrv_ratio | LTH MVRV + STH MVRV |
realized_price | Realized Price LTH + Realized Price STH |
realized_cap | Realized Cap LTH + Realized Cap STH |
unrealized_pl | P/L no realizado LTH + P/L no realizado STH |
realized_pl | P/L realizado LTH + P/L realizado STH |
sopr | LTH SOPR + STH SOPR |
block_height | Altura de bloque |
Ejemplos
# Bitcoin example: BTC price, 1 year, line chart
curl -H "Authorization: Bearer YOUR_KEY" \
"https://api.blocklens.co/v1/chart/snapshot?metric=price" \
--output price.png
# Bitcoin example: two metrics with area style
curl -H "Authorization: Bearer YOUR_KEY" \
"https://api.blocklens.co/v1/chart/snapshot?metrics=lth_supply,sth_supply&style=area&days=730" \
--output supply.png
# Template with dark theme
curl -H "Authorization: Bearer YOUR_KEY" \
"https://api.blocklens.co/v1/chart/snapshot?template=mvrv_ratio&theme=dark" \
--output mvrv_dark.png
# Log scale with price overlay
curl -H "Authorization: Bearer YOUR_KEY" \
"https://api.blocklens.co/v1/chart/snapshot?metric=lth_supply&scale=log&overlay=price&days=1095" \
--output supply_with_price.png
# Get JSON metadata instead of image
curl -H "Authorization: Bearer YOUR_KEY" \
-H "Accept: application/json" \
"https://api.blocklens.co/v1/chart/snapshot?metric=price" | jq
# Get SVG instead of PNG
curl -H "Authorization: Bearer YOUR_KEY" \
-H "Accept: image/svg+xml" \
"https://api.blocklens.co/v1/chart/snapshot?metric=price" \
--output price.svg
Respuesta correcta
PNG (predeterminado):
HTTP/1.1 200 OK
Content-Type: image/png
Cache-Control: public, max-age=3600
X-Snapshot-Cache: HIT
X-Snapshot-Render-Ms: 0
X-Render-Id: 0a1b2c3d4e5f6789
<binary PNG data>
SVG (con Accept: image/svg+xml):
HTTP/1.1 200 OK
Content-Type: image/svg+xml
Cache-Control: public, max-age=3600
X-Snapshot-Cache: MISS
X-Snapshot-Render-Ms: 412
X-Render-Id: 0a1b2c3d4e5f6789
Content-Disposition: attachment; filename="chart.svg"
<svg xmlns="http://www.w3.org/2000/svg" ...>...</svg>
El valor de X-Render-Id puede usarse para volver a obtener la misma imagen en /v1/chart/renders/{render_id}.png o /v1/chart/renders/{render_id}.svg hasta 1 hora.
POST /v1/chart/snapshot
Personalización completa del gráfico mediante cuerpo JSON. Admite estilos por métrica, ejes personalizados, fórmulas, líneas de referencia, áreas de referencia y mucho más. Diseñado para agentes de IA (mediante MCP) y usuarios avanzados.
Cuerpo de la solicitud
Proporcione exactamente una fuente de datos (metric, metrics o template):
{
"metric": "price",
"days": 365,
"start_date": "2025-01-01",
"end_date": "2026-02-23",
"title": "Custom Chart Title",
"width": 1200,
"height": 600,
"theme": "light",
"format": "png",
"style": "line",
"scale": "linear",
"overlay": "price",
"y_axes": [
{"id": "axis-left", "side": "left", "scale": "linear", "format": "number"},
{"id": "axis-right", "side": "right", "scale": "log", "format": "currency"}
],
"formulas": [
{"expression": "sma(m1, 200)", "label": "200-day SMA", "color": "#9333ea", "style": "line"}
],
"reference_lines": [
{"y": 1.0, "stroke": "#9ca3af", "stroke_dasharray": "3 3", "label": "Break-even"}
],
"reference_areas": [
{"y1": 0, "y2": 0.85, "fill": "#16a34a", "fill_opacity": 0.08, "label": "Undervalued"}
]
}
Nota: Debe proporcionarse exactamente uno de metric, metrics o template.
Campo Metrics
El campo metrics admite tipos mixtos:
// String shorthand
["price", "lth_supply"]
// Full config objects
[{"id": "price", "axis": "right", "style": "line", "color": "#374151"}]
// Mixed
["price", {"id": "lth_supply", "axis": "left", "style": "area"}]
// With params for parameterized metrics
[
{"id": "funding_binance", "params": {"exchange": "binance"}},
{"id": "price"}
]
Algunas métricas requieren parámetros adicionales (p. ej., exchange, ticker, id). Incluya el objeto params de la definición de la métrica al usar estas métricas.
Opciones por métrica
| Campo | Tipo | Descripción |
|---|---|---|
id | string | Obligatorio. ID de la métrica del registro. |
params | object | Parámetros para métricas parametrizadas (p. ej., {"exchange": "binance"}). Consulte la definición de la métrica para los parámetros requeridos. |
axis | left / right | Lado del eje Y. Asignado automáticamente si se omite. |
y_axis_id | string | Vincular a un eje Y específico por ID (p. ej. axis-diff). Reemplaza a axis. |
style | line / area / bar | Estilo del gráfico. Valor por defecto del registro si se omite. |
color | string | Color hexadecimal (p. ej., #2563eb). Asignado automáticamente si se omite. |
label | string | Etiqueta de visualización. Usa el nombre de la métrica si se omite. |
stroke_width | integer | Ancho de línea (0-5). Predeterminado: 2. Use 0 para barras sin bordes. |
fill_opacity | float | Opacidad de relleno (0.0-1.0). Para barras transparentes, use valores bajos como 0.2. |
stroke_dash | string | Patrón de guiones (p. ej., 5 5). |
stack_group | string | ID de grupo de apilamiento para gráficos apilados. |
show_in_legend | boolean | Si se muestra en la leyenda del gráfico. Predeterminado: true. |
visible | boolean | Mostrar/ocultar. Predeterminado: true. |
Ejes Y personalizados
El campo y_axes define los ejes Y disponibles para métricas y fórmulas. Cada eje tiene un id único que puede referenciarse mediante y_axis_id en métricas o fórmulas. Puede definir más de dos ejes —por ejemplo, un eje separado para diferencias calculadas:
"y_axes": [
{"id": "axis-left", "side": "left", "scale": "linear", "format": "number"},
{"id": "axis-right", "side": "right", "scale": "log", "format": "currency"},
{"id": "axis-diff", "side": "left", "scale": "linear", "format": "number"}
]
| Campo | Tipo | Descripción |
|---|---|---|
id | string | Identificador único del eje. Referenciado por y_axis_id en métricas/fórmulas. |
side | left / right | En qué lado del gráfico aparece el eje. |
scale | linear / log | Escala del eje. Predeterminado: linear. |
format | number / currency / percent | Formato numérico para las etiquetas del eje. |
range | [number, number] | Zona vertical como [from%, to%]. 0 = abajo, 100 = arriba. Predeterminado: altura completa. Úselo para apilar ejes verticalmente (p. ej. volumen en el 20% inferior, precio en el 80% superior). |
domain_min | number | Límite inferior fijo del dominio. El eje nunca bajará por debajo de este valor. |
domain_max | number | Límite superior fijo del dominio. El eje nunca subirá por encima de este valor. |
no_padding | "top" / "bottom" / "both" | Elimina el relleno automático del 10% en los bordes. Útil cuando un límite de dominio es una frontera fija (p. ej. drawdown limitado a 0). |
Si se omite y_axes, los ejes se generan automáticamente según los valores de axis de las métricas.
Ejemplo: Precio + Volumen con zonas verticales
Apile las barras de volumen en el 20% inferior y el precio en el espacio restante:
curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"metrics": [
{"id": "price", "style": "line", "color": "#374151", "y_axis_id": "axis-price"},
{"id": "volume", "style": "bar", "color": "#3b82f6", "fill_opacity": 0.3, "stroke_width": 0, "y_axis_id": "axis-vol"}
],
"y_axes": [
{"id": "axis-price", "side": "right", "scale": "log", "format": "currency", "range": [20, 100]},
{"id": "axis-vol", "side": "left", "format": "number", "range": [0, 20], "no_padding": "bottom"}
],
"days": 365,
"title": "BTC Price + Volume (Zoned)"
}' --output price_volume_zones.png
Lo que esto produce:
- Las barras de volumen llenan el 20% inferior del gráfico (
range: [0, 20]) sin relleno en el borde inferior - El precio ocupa el 80% superior (
range: [20, 100]) en una escala logarítmica - Las dos series nunca se superponen, creando un diseño apilado limpio
Ejemplo: Drawdown con límite de dominio
Limite el drawdown a 0 (borde superior) para que la línea toque la parte superior de su zona:
curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"metrics": ["price"],
"formulas": [
{"expression": "drawdown(price)", "label": "Drawdown from ATH", "style": "area", "color": "#dc2626", "fill_opacity": 0.15, "y_axis_id": "axis-dd"}
],
"y_axes": [
{"id": "axis-right", "side": "right", "scale": "log", "format": "currency"},
{"id": "axis-dd", "side": "left", "format": "percent", "domain_max": 0, "no_padding": "top"}
],
"days": 1825,
"title": "BTC Price + Drawdown from ATH"
}' --output drawdown.png
Lo que esto produce:
- El drawdown siempre es ≤ 0, por lo que
domain_max: 0fija el borde superior no_padding: "top"elimina el relleno automático del 10% por encima de 0, haciendo que la línea toque la parte superior cuando el drawdown es del 0%- El precio está en el eje derecho con escala logarítmica
Fórmulas
El campo formulas le permite definir series calculadas derivadas de sus métricas. Las fórmulas pueden referenciar métricas por su id (p. ej. lth_supply) o por índice posicional (m1, m2, etc., según el orden en el array metrics).
"formulas": [
{
"expression": "lth_supply - shift(lth_supply, 30)",
"label": "LTH 30d Change",
"color": "#16a34a",
"style": "bar",
"y_axis_id": "axis-diff",
"fill_opacity": 0.2,
"stroke_width": 0
}
]
Funciones admitidas (30 en total):
Medias móviles y estadísticas móviles
| Función | Sintaxis | Descripción |
|---|---|---|
sma | sma(series, period) | Media móvil simple |
ema | ema(series, period) | Media móvil exponencial |
median | median(series, period) | Mediana móvil |
sum | sum(series, period) | Suma móvil |
std | std(series, period) | Desviación estándar móvil |
Acumuladas
| Función | Sintaxis | Descripción |
|---|---|---|
cumsum | cumsum(series) | Suma acumulada expansiva |
cummean | cummean(series) | Media acumulada expansiva |
cummedian | cummedian(series) | Mediana acumulada expansiva |
cumstd | cumstd(series) | Desviación estándar acumulada expansiva |
cummax | cummax(series) | Máximo acumulado histórico |
cummin | cummin(series) | Mínimo acumulado histórico |
Cambios
| Función | Sintaxis | Descripción |
|---|---|---|
percent_change | percent_change(series, period) | Cambio porcentual (decimal: 0.20 = +20%) |
diff | diff(series, period) | Cambio en valor absoluto |
Matemáticas
| Función | Sintaxis | Descripción |
|---|---|---|
abs | abs(series) | Valor absoluto |
pow | pow(series, n) | Elevar a la potencia n |
log | log(series) | Logaritmo en base 10 |
round | round(series, digits) | Redondear a N decimales |
max | max(a, b, ...) | Máximo puntual |
min | min(a, b, ...) | Mínimo puntual |
Indicadores técnicos
| Función | Sintaxis | Descripción |
|---|---|---|
rsi | rsi(series, period) | Índice de fuerza relativa (0-100) |
corr | corr(s1, s2, period) | Correlación de Pearson (-1 a 1) |
drawdown | drawdown(series) | Drawdown desde el ATH (decimal negativo) |
Riesgo y rentabilidad
| Función | Sintaxis | Descripción |
|---|---|---|
mean_return | mean_return(series, period) | Rentabilidad media móvil anualizada |
realized_vol | realized_vol(series, period) | Volatilidad realizada anualizada |
sharpe_ratio_arithmetic | sharpe_ratio_arithmetic(series, period) | Ratio de Sharpe (aritmético) |
sharpe_ratio_geometric | sharpe_ratio_geometric(series, period) | Ratio de Sharpe (geométrico) |
Manipulación de series
| Función | Sintaxis | Descripción |
|---|---|---|
shift | shift(series, period) | Desplazar la serie N periodos |
if | if(a, "op", b, then, else) | Condicional (op: =, !=, >, >=, <, <=) |
Operadores
Aritméticos: +, -, *, /
Agrupación: (, )
Referenciado
- Métricas por nombre:
lth_supply + sth_supply— use los IDs de las métricas directamente - Métricas por posición:
m1 + m2— referencias posicionales (m1 = primera métrica, m2 = segunda, etc.) - Otras fórmulas:
f1 * 2— referencia fórmulas anteriores (f1 = primera fórmula, etc.) - Las fórmulas se evalúan en orden, por lo que f2 puede referenciar a f1, pero no a la inversa.
Opciones de fórmula:
| Campo | Tipo | Descripción |
|---|---|---|
expression | string | Obligatorio. Expresión de la fórmula usando IDs de métricas o referencias posicionales (m1, m2). |
label | string | Obligatorio. Etiqueta de visualización para la leyenda. |
color | string | Color hexadecimal. Asignado automáticamente si se omite. |
style | line / area / bar | Estilo del gráfico. Predeterminado: line. |
y_axis_id | string | Vincular a un eje Y específico por ID (p. ej. axis-diff). Reemplaza a axis. |
axis | left / right | Lado del eje Y. Predeterminado: left. Ignorado si se establece y_axis_id. |
fill_opacity | float | Opacidad de relleno (0.0-1.0). Para barras transparentes, use valores bajos como 0.2. |
stroke_width | integer | Ancho de trazo (0-5). Use 0 para barras sin bordes. |
stroke_dash | string | Patrón de guiones (p. ej., 6 3). |
stack_group | string | ID de grupo de apilamiento para apilar varias series de fórmulas. |
Líneas y áreas de referencia
Las líneas de referencia añaden líneas guía horizontales para resaltar valores específicos (p. ej. punto de equilibrio en 1.0, umbral de sobrecompra). Las áreas de referencia añaden zonas sombreadas para resaltar rangos de valores (p. ej. zona infravalorada, bandas tipo Bollinger). Ambas admiten valores estáticos y fórmulas dinámicas usando el mismo motor de fórmulas que el campo formulas.
Opciones de línea de referencia
| Campo | Tipo | Descripción |
|---|---|---|
y | number | Valor Y estático. |
y_formula | string | Expresión de fórmula para una Y dinámica (p. ej. "sma(m1, 200)"). Usa el mismo motor que formulas. |
y_axis_id | string | ID del eje Y (por defecto, el primer eje izquierdo). |
stroke | string | Color hexadecimal de la línea (predeterminado: #9ca3af). |
stroke_dasharray | string | Patrón de guiones, p. ej. "3 3" para discontinua. |
label | string | Texto de la etiqueta. |
Proporcione y (estático) o y_formula (dinámico), no ambos. Máximo 10 líneas de referencia por gráfico.
Opciones de área de referencia
| Campo | Tipo | Descripción |
|---|---|---|
y1 | number | Límite Y inferior estático. |
y2 | number | Límite Y superior estático. |
y1_formula | string | Fórmula para el límite inferior dinámico. |
y2_formula | string | Fórmula para el límite superior dinámico. |
y_axis_id | string | ID del eje Y (por defecto, el primer eje izquierdo). |
fill | string | Color hexadecimal de relleno (predeterminado: #3b82f6). |
fill_opacity | number | Opacidad de relleno 0–1 (predeterminado: 0.1). |
label | string | Texto de la etiqueta. |
Proporcione límites estáticos (y1/y2) o basados en fórmula (y1_formula/y2_formula) — puede combinarlos (p. ej. y1 estático con y2_formula dinámico). Máximo 10 áreas de referencia por gráfico.
Ejemplo: MVRV con zonas de valor
Añada una zona verde infravalorada (0–0.85), una zona roja sobrevalorada (8–100) y una línea de equilibrio discontinua en 1.0:
curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"metric": "mvrv",
"days": 1825,
"title": "MVRV Ratio — Value Zones",
"reference_lines": [
{"y": 1.0, "stroke": "#9ca3af", "stroke_dasharray": "3 3", "label": "Break-even"}
],
"reference_areas": [
{"y1": 0, "y2": 0.85, "fill": "#16a34a", "fill_opacity": 0.08, "label": "Undervalued"},
{"y1": 8, "y2": 100, "fill": "#dc2626", "fill_opacity": 0.08, "label": "Overvalued"}
]
}' --output mvrv_zones.png
Ejemplo: Banda basada en fórmula
Cree una banda tipo Bollinger alrededor de la primera fórmula (envolvente de ±10%):
curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"metrics": ["price"],
"days": 365,
"formulas": [
{"expression": "sma(m1, 50)", "label": "50-day SMA", "color": "#2563eb", "style": "line"}
],
"reference_areas": [
{"y1_formula": "f1 * 0.9", "y2_formula": "f1 * 1.1", "fill": "#2563eb", "fill_opacity": 0.06, "label": "±10% Band"}
],
"reference_lines": [
{"y_formula": "sma(m1, 200)", "stroke": "#9333ea", "stroke_dasharray": "6 3", "label": "200-day SMA"}
]
}' --output price_bands.png
Formato de salida
El campo format controla la salida:
| Formato | Content-Type | Descripción |
|---|---|---|
png (predeterminado) | image/png | Imagen de gráfico rasterizada |
svg | image/svg+xml | Gráficos vectoriales (escalables, incrustables) |
json | application/json | Metadatos del gráfico (sin renderizado) |
Alternativamente, use la cabecera Accept:
Accept: image/png- PNG (predeterminado)Accept: image/svg+xml- SVGAccept: application/json- Metadatos JSON
Respuesta de metadatos JSON
Cuando format=json o Accept: application/json:
{
"success": true,
"title": "BTC Price",
"metrics": [{"id": "price", "label": "BTC Price"}],
"days": 365,
"start_date": null,
"end_date": null,
"theme": "light",
"width": 1200,
"height": 600,
"formulas": [],
"data_points": 365,
"cached": false,
"render_time_ms": 0
}
Ejemplos
# POST with single metric
curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"metric": "price", "days": 365}' \
--output price.png
# Multi-metric with custom styling
curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"metrics": [
{"id": "price", "axis": "right", "style": "line", "color": "#374151"},
{"id": "lth_supply", "axis": "left", "style": "area", "color": "#2563eb"}
],
"days": 730,
"title": "BTC Price vs LTH Supply",
"theme": "dark"
}' \
--output chart.png
# SVG output
curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"template": "mvrv_ratio", "format": "svg"}' \
--output mvrv.svg
# JSON metadata
curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"metric": "price", "format": "json"}' | jq
Renderizado de mapas de calor
La Snapshot API puede renderizar mapas de calor para métricas basadas en distribución como la Distribución del Coste Base (Cost Basis Distribution). Los mapas de calor usan un conjunto de parámetros distinto al de los gráficos de métricas estándar.
Parámetros del mapa de calor
| Parámetro | Tipo | Predeterminado | Descripción |
|---|---|---|---|
heatmap_id | string | - | Identificador del mapa de calor (p. ej., cost-basis-distribution) |
heatmap_period | string | 1y | Periodo de tiempo: 3m, 6m, 1y, 2y, 3y, 5y, all |
heatmap_color_scale | string | viridis | Escala de color: viridis, plasma, inferno, magma, cividis |
heatmap_y_scale | string | linear | Escala del eje Y: linear o log |
theme | string | light | Tema de color: light o dark |
title | string | auto | Título del gráfico |
width | integer | 1200 | Ancho de la imagen en píxeles |
height | integer | 600 | Alto de la imagen en píxeles |
Ejemplo
curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"heatmap_id": "cost-basis-distribution",
"heatmap_period": "1y",
"heatmap_color_scale": "viridis",
"heatmap_y_scale": "log",
"theme": "dark",
"title": "Cost Basis Distribution"
}' --output cbd_heatmap.png
Nota: Los parámetros del mapa de calor (heatmap_id, etc.) son mutuamente excluyentes con los parámetros de métrica estándar (metric, metrics, template). Las métricas de mapa de calor requieren el nivel Enterprise.
La leyenda de la escala de color se incluye en la imagen renderizada, mostrando el rango de valores asignado a la paleta de colores seleccionada.
Gráficos de superposición de rendimiento de ciclos
Los gráficos de rendimiento de ciclos superponen varios ciclos de Bitcoin en el mismo eje X para que pueda compararlos en igualdad de condiciones. En lugar de representarse frente a fechas de calendario, el precio de cada ciclo se indexa a su propio evento ancla (mínimo del ciclo, ATH o halving) y se representa frente a los días transcurridos desde ese ancla.
Active el modo de superposición estableciendo x_axis: "day_offset" en una solicitud POST /v1/chart/snapshot y proporcionando métricas de ciclo en el array metrics. El renderizador usa el campo day_offset de cada punto de datos en lugar de date, de modo que todos los ciclos comienzan en el Día 0 del eje X.
Las etiquetas de las marcas muestran fechas de calendario del ciclo más reciente de la familia elegida. Por ejemplo, una superposición de ATH (cycle_ath_1…cycle_ath_5) se ancla en 2025-10-06 y las marcas indican Oct '25, Jan '26, Apr '26, etc. — no Day 0, Day 90, Day 180. Otros ciclos del mismo gráfico se alinean en las mismas posiciones del eje X, de modo que un valor en la marca Apr '26 de cycle_ath_3 significa "qué hacía BTC 182 días después del inicio del ciclo de 2017". La numeración por días vuelve a aparecer como alternativa únicamente si el backend no puede determinar el ancla.
Tipos de ancla
Hay disponibles tres familias de métricas de ciclo, una por cada evento ancla:
| Ancla | Prefijo del ID de métrica | Descripción | Pista del endpoint |
|---|---|---|---|
| Mínimo del ciclo → siguiente mínimo | cycle_low_* | Precio indexado al fondo del ciclo — cada serie comienza en 1.0 en la fecha del mínimo y se extiende hasta el mínimo del siguiente ciclo. | endpoint: "cycle-performance?type=low" |
| ATH → ATH | cycle_ath_* | Precio indexado al máximo histórico del ciclo — cada serie comienza en 1.0 en la fecha del ATH y se extiende hasta el siguiente ATH. | endpoint: "cycle-performance?type=ath" |
| Halving → halving | cycle_halving_* | Precio indexado al bloque del halving — cada serie comienza en 1.0 en la fecha del halving y se extiende hasta el siguiente halving. | endpoint: "cycle-performance?type=halving" |
Dentro de una familia de ancla, cada ciclo tiene la misma forma de datos — un índice que comienza en 1.0 y rastrea price(t) / price(anchor) hasta el siguiente evento ancla (o, para el ciclo actual, hasta hoy). Eso es lo que hace que la comparación por superposición sea significativa: un valor de 5.0 en el día 200 de cycle_ath_3 significa "BTC valía 5× su ATH de 2017 a los 200 días de ese ATH".
Todas las métricas de ciclo disponibles
| ID de métrica | Fecha ancla | Ancla → fecha de fin |
|---|---|---|
cycle_low_1 | 2011-11-18 | 2011-11-18 → 2015-01-14 |
cycle_low_2 | 2015-01-14 | 2015-01-14 → 2018-12-15 |
cycle_low_3 | 2018-12-15 | 2018-12-15 → 2022-11-21 |
cycle_low_4 | 2022-11-21 | 2022-11-21 → hoy (ciclo actual) |
cycle_ath_1 | 2011-06-11 | 2011-06-11 → 2013-11-30 |
cycle_ath_2 | 2013-11-30 | 2013-11-30 → 2017-12-17 |
cycle_ath_3 | 2017-12-17 | 2017-12-17 → 2021-11-10 |
cycle_ath_4 | 2021-11-10 | 2021-11-10 → 2025-10-06 |
cycle_ath_5 | 2025-10-06 | 2025-10-06 → hoy (ciclo actual) |
cycle_halving_1 | 2012-11-28 | 2012-11-28 → 2016-07-09 |
cycle_halving_2 | 2016-07-09 | 2016-07-09 → 2020-05-11 |
cycle_halving_3 | 2020-05-11 | 2020-05-11 → 2024-04-20 |
cycle_halving_4 | 2024-04-20 | 2024-04-20 → hoy (ciclo actual) |
- Todas las
metricsdeben provenir de la misma familia de ancla. Mezclarcycle_ath_*concycle_low_*(o cualquier cosa fuera dedaily_cycle_performance) devuelve400 invalid_params. - El indicador
x_axis: "day_offset"solo es válido para métricas de ciclo — combinarlo con cualquier otra métrica devuelve400 invalid_params. - Se aplica el límite estándar de "máximo 6 métricas por gráfico" — elija hasta 6 ciclos por superposición.
Parámetros de rendimiento de ciclos
Además de todos los parámetros estándar del gráfico (days, width, height, theme, scale, format, title, y_axes, reference_lines, reference_areas, formulas, etc.), el modo de superposición de ciclos usa estos campos:
| Campo | Tipo | Predeterminado | Descripción |
|---|---|---|---|
x_axis | "date" / "day_offset" | "date" | Establézcalo en "day_offset" para activar la superposición de ciclos. De lo contrario, el eje X es de fecha de calendario. |
metrics | array | obligatorio | 1–6 IDs de métricas de ciclo de la misma familia de ancla. Strings u objetos ({id, color, style, label, stroke_width, fill_opacity, show_in_legend, y_axis_id}). |
days | integer | 365 | Limita el desplazamiento de día máximo renderizado (rango del eje X, no días de calendario). Establézcalo en 1500 para ver ~4 años por ciclo. |
scale | "linear" / "log" | "linear" | La escala logarítmica es casi siempre lo que querrá — los multiplicadores de los primeros ciclos pueden ser de 100×–500×, lo cual resulta ilegible en escala lineal. |
theme | "light" / "dark" | "light" | El tema oscuro es el predeterminado del dashboard para estos gráficos. |
Las líneas de referencia (reference_lines) son especialmente útiles en los gráficos de superposición — p. ej. una línea horizontal en y: 1.0 marca el nivel del ancla, y: 2.0 marca "2× el ancla", y así sucesivamente.
Ejemplo: Superposición anclada en ATH (colores personalizados por ciclo)
Esta receta reproduce el gráfico "Price Performance Since ATH" del dashboard — cinco ciclos, cada uno en un color distinto, en un eje logarítmico.
curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"metrics": [
{"id": "cycle_ath_1", "color": "#8b5cf6", "label": "2011 ATH cycle"},
{"id": "cycle_ath_2", "color": "#3b82f6", "label": "2013 ATH cycle"},
{"id": "cycle_ath_3", "color": "#22c55e", "label": "2017 ATH cycle"},
{"id": "cycle_ath_4", "color": "#f59e0b", "label": "2021 ATH cycle"},
{"id": "cycle_ath_5", "color": "#ef4444", "label": "2025 ATH cycle (current)"}
],
"x_axis": "day_offset",
"scale": "log",
"y_axes": [
{"id": "left", "side": "left", "scale": "log", "format": "number"}
],
"reference_lines": [
{"y": 1.0, "stroke": "#9ca3af", "stroke_dasharray": "3 3", "label": "ATH = 1.0"}
],
"days": 1500,
"theme": "dark",
"title": "Price Performance Since ATH"
}' --output cycle_ath.png
Ejemplo: Superposición de mínimo de ciclo (forma abreviada)
Para una comparación rápida sin estilos por ciclo, pase los IDs de métrica como strings simples — los colores provienen automáticamente de la paleta del registro.
curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"metrics": ["cycle_low_1", "cycle_low_2", "cycle_low_3", "cycle_low_4"],
"x_axis": "day_offset",
"scale": "log",
"days": 1500,
"title": "Price Since Cycle Low"
}' --output cycle_low.png
Ejemplo: Superposición anclada en halving
Misma forma, cuatro ciclos anclados en cada evento de halving.
curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"metrics": [
"cycle_halving_1", "cycle_halving_2", "cycle_halving_3", "cycle_halving_4"
],
"x_axis": "day_offset",
"scale": "log",
"days": 1500,
"theme": "dark",
"title": "Price Since Halving"
}' --output cycle_halving.png
Equivalente con herramienta MCP
Desde un agente de IA conectado al servidor MCP, el mismo gráfico es una sola llamada a herramienta:
render_chart({
metrics: [
{ id: "cycle_ath_1", color: "#8b5cf6" },
{ id: "cycle_ath_2", color: "#3b82f6" },
{ id: "cycle_ath_3", color: "#22c55e" },
{ id: "cycle_ath_4", color: "#f59e0b" },
{ id: "cycle_ath_5", color: "#ef4444" }
],
x_axis: "day_offset",
scale: "log",
days: 1500,
theme: "dark",
title: "Price Performance Since ATH"
})
El servidor MCP acepta el mismo enum x_axis, los mismos IDs de métricas y las mismas reglas de validación que la API HTTP.
Control de leyenda por métrica
Use show_in_legend en los objetos de configuración de métricas individuales para controlar si una métrica aparece en la leyenda del gráfico. Esto es útil al combinar muchas series donde algunas son líneas de contexto/fondo.
{
"metrics": [
{"id": "price", "show_in_legend": true},
{"id": "sma_200", "show_in_legend": false}
]
}
| Campo | Tipo | Predeterminado | Descripción |
|---|---|---|---|
show_in_legend | boolean | true | Si la métrica aparece en la leyenda del gráfico |
Valores predeterminados inteligentes
La Snapshot API usa valores predeterminados inteligentes para que pueda obtener gráficos con buen aspecto con una configuración mínima:
| Parámetro | Cómo se determina el valor predeterminado |
|---|---|
| Estilo del gráfico | Del registro de métricas (chart_types[0]) |
| Color | Del registro de métricas, luego rotación de paleta |
| Lado del eje Y | Primera métrica a la izquierda; las métricas del mismo formato comparten eje; el formato distinto a la derecha |
| Escala del eje Y | linear (anular con scale=log) |
| Rango temporal | Según categoría: 365 días para precio/valoración/beneficio, 730 para oferta, 180 para blockchain |
| Título | Métrica única: nombre de la métrica. Múltiples: "Nombre1 vs Nombre2" |
| Tamaño de imagen | 1200 x 600 píxeles |
| Tema | light |
Respuestas de error
Todos los errores devuelven JSON:
// 400 Bad Request
{"success": false, "error": "invalid_params", "message": "Exactly one of 'metric', 'metrics', or 'template' must be provided"}
// 401 Unauthorized
{"success": false, "error": "unauthorized", "message": "API key required"}
// 403 Forbidden
{"success": false, "error": "insufficient_tier", "message": "Metric 'lth_sopr' requires Pro tier", "upgrade_url": "https://blocklens.co/pricing"}
// 429 Rate Limited
{"success": false, "error": "rate_limited", "message": "Snapshot rate limit exceeded. Max 60 per hour for pro tier.", "retry_after": 120}
// 504 Timeout
{"success": false, "error": "render_timeout", "message": "Chart rendering timed out after 20.0s. Try a shorter date range."}
Herramienta MCP: render_chart
El servidor MCP de Blocklens incluye una herramienta render_chart que permite a los agentes de IA generar imágenes de gráficos directamente en las conversaciones. La herramienta llama a la Snapshot API y devuelve la imagen en línea como PNG (ráster) o SVG (vectorial).
Parámetros
| Parámetro | Tipo | Predeterminado | Descripción |
|---|---|---|---|
metric | string | - | ID de una sola métrica |
metrics | array | - | Varias métricas (strings u objetos) |
template | string | - | ID de plantilla |
days | integer | 365 | Días de historial |
start_date | string | - | Fecha de inicio (YYYY-MM-DD) |
end_date | string | - | Fecha de fin (YYYY-MM-DD) |
overlay | price | - | Añade superposición de precio (actualmente BTC) |
theme | light / dark | light | Tema de color |
width | integer | 1200 | Ancho de la imagen |
height | integer | 600 | Alto de la imagen |
title | string | auto | Título del gráfico |
style | line / area / bar | auto | Estilo del gráfico |
scale | linear / log | linear | Escala del eje Y |
format | png / svg / json | png | Formato de salida: png (imagen ráster), svg (imagen vectorial, escala sin pérdida de calidad) o json (solo metadatos — sin renderizado) |
y_axes | array | - | Ejes Y personalizados con zonas (consulte Ejes Y personalizados) |
x_axis | date / day_offset | date | Modo del eje X. Use day_offset para superposiciones de rendimiento de ciclos — todas las metrics deben pertenecer a la misma familia de ciclo. |
heatmap_id | cost-basis-distribution | - | Renderiza un mapa de calor en lugar de un gráfico de líneas (consulte Renderizado de mapas de calor). Mutuamente excluyente con metric / metrics / template. |
heatmap_period | 3m / 6m / 1y / 2y / 3y / 5y / all | 1y | Ventana de agrupación del mapa de calor. |
heatmap_color_scale | viridis / plasma / inferno / magma / cividis | viridis | Paleta de colores del mapa de calor. |
heatmap_y_scale | linear / log | linear | Escala del eje Y de los intervalos de precio del mapa de calor. |
params | object | - | Parámetros por llamada para métricas parametrizadas (p. ej. { "exchange": "binance" }, { "ticker": "IBIT" }, { "entity": "tesla" }). |
reference_lines | array | - | Líneas de referencia horizontales (consulte Líneas y áreas de referencia) |
reference_areas | array | - | Zonas de referencia sombreadas (consulte Líneas y áreas de referencia) |
Ejemplos de uso
User: "Show me the MVRV ratio for the last 2 years"
Agent calls: render_chart({ template: "mvrv_ratio", days: 730 })
-> Returns PNG image inline
User: "Chart BTC price vs LTH supply"
Agent calls: render_chart({
metrics: [
{ id: "price", axis: "right" },
{ id: "lth_supply", axis: "left", style: "area" }
],
days: 365
})
-> Returns PNG image inline
User: "Is there capitulation? Show SOPR"
Agent calls: render_chart({ template: "sopr", days: 180, overlay: "price" })
-> Returns PNG image inline
User: "Render the MVRV chart as SVG so I can embed it in a slide deck"
Agent calls: render_chart({ template: "mvrv_ratio", format: "svg" })
-> Returns the chart inline as image/svg+xml and a /chart/renders/{id}.svg URL
Configuración de MCP
Añada esto a su configuración de Claude Desktop o Cursor para habilitar el renderizado de gráficos:
{
"mcpServers": {
"blocklens": {
"command": "npx",
"args": ["-y", "blocklens-mcp-server"],
"env": {
"BLOCKLENS_API_KEY": "your_api_key_here"
}
}
}
}
Consulte Servidor MCP para las instrucciones de configuración completas.
Ejemplo avanzado: gráfico de oferta de LTH
Este ejemplo reproduce el gráfico completo de Oferta de Holders a Largo Plazo (Long-Term Holder Supply) del dashboard de Blocklens — dos métricas, dos series de fórmula calculadas y tres ejes Y:
curl -X POST "https://api.blocklens.co/v1/chart/snapshot" \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"metrics": [
{"id": "price", "label": "BTC Price", "style": "line", "color": "#6b7280", "axis": "right", "fill_opacity": 0, "stroke_width": 1},
{"id": "lth_supply", "label": "LTH Supply", "style": "line", "color": "#2563eb", "axis": "left", "stroke_width": 2}
],
"y_axes": [
{"id": "axis-left", "side": "left", "scale": "linear"},
{"id": "axis-right", "side": "right", "scale": "log"},
{"id": "axis-diff", "side": "left", "scale": "linear"}
],
"formulas": [
{"expression": "max(lth_supply - shift(lth_supply, 30), 0)", "label": "LTH 30d+ diff", "color": "#16a34a", "style": "bar", "y_axis_id": "axis-diff", "fill_opacity": 0.2, "stroke_width": 0},
{"expression": "min(0, lth_supply - shift(lth_supply, 30))", "label": "LTH 30d- diff", "color": "#dc2626", "style": "bar", "y_axis_id": "axis-diff", "fill_opacity": 0.2, "stroke_width": 0}
],
"days": 730,
"title": "Long-Term Holder Supply"
}' --output lth_supply.png
Lo que esto produce:
- BTC Price — línea gris en el eje derecho (escala logarítmica)
- LTH Supply — línea azul en el eje izquierdo (lineal)
- Acumulación positiva de 30 días — barras verdes semitransparentes en un eje
axis-diffseparado - Distribución de 30 días — barras rojas semitransparentes en el mismo eje
axis-diff
Técnicas clave utilizadas:
shift(lth_supply, 30)calcula el valor retrospectivo de 30 díasmax(..., 0)ymin(0, ...)separan los cambios positivos y negativos en series distintasy_axis_id: "axis-diff"vincula ambas barras de fórmula a un eje dedicado independiente de los ejes principales de las métricasfill_opacity: 0.2+stroke_width: 0crea barras transparentes sutiles y sin bordes
Plantillas de gráficos
Las configuraciones completas de gráficos (incluyendo métricas, fórmulas, ejes y estilos) están disponibles como plantillas respaldadas por base de datos mediante:
GET /api/lab/templates
Estas plantillas pueden servir de referencia para construir sus propios cuerpos de solicitud POST. Cada plantilla contiene la configuración completa que produce un gráfico específico en el dashboard de Blocklens.
Marca de agua
Todas las imágenes de gráficos renderizadas incluyen una marca de agua blocklens.co y un aviso de copyright. Esto se aplica tanto al formato de salida PNG como SVG.
Caché
Los snapshots renderizados se cachean durante 1 hora en Redis. Comportamiento de la caché:
- Las configuraciones de gráfico idénticas devuelven resultados cacheados al instante
- La clave de caché se deriva de la configuración completa del gráfico (métricas, ejes, rango temporal, tema, tamaño) más el formato de salida — las variantes PNG y SVG del mismo gráfico se cachean de forma independiente
- La cabecera de respuesta
X-Snapshot-CacheindicaHIToMISS - La cabecera
X-Snapshot-Render-Msmuestra el tiempo de renderizado (0 para aciertos de caché) - Los archivos renderizados también se persisten en disco bajo
/v1/chart/renders/{render_id}.pngy/v1/chart/renders/{render_id}.svgdurante 1 hora, de modo que las URLs de gráfico devueltas en la cabeceraX-Render-Idsiguen siendo accesibles - Los gráficos populares se precalientan tras cada actualización diaria de datos (05:00 UTC)