---
title: "Render custom chart snapshot"
method: POST
path: "/v1/chart/snapshot"
tags: ["Chart Snapshots"]
---

# Render custom chart snapshot

`POST /v1/chart/snapshot`

## Request

- Base URL: `https://api.blocklens.co` (the document declares no server; this is the origin it was published from)
- URL: `https://api.blocklens.co/v1/chart/snapshot`
- Auth: none declared

Render a fully customized chart snapshot from a JSON body. Returns PNG, SVG, or JSON.

Designed for AI agents (MCP), automated pipelines, and advanced users. Supports per-metric styling,
custom Y-axes, formulas (SMA, EMA, ratios), dark theme, stack groups, and stroke patterns.

**`metrics` field supports mixed types:**
- Strings (shorthand): `["price", "lth_supply"]`
- Objects (full config): `[{"id": "price", "axis": "right", "style": "line"}]`
- Mixed: `["price", {"id": "lth_supply", "axis": "left", "style": "area"}]`

**Output format** is controlled via the `format` field or `Accept` header:
- `"png"` (default) — PNG image
- `"svg"` — SVG vector graphic
- `"json"` — chart metadata (no image rendered)

All fields except `metrics` (or `metric`/`template`) are optional with smart defaults.

**Formula warmup:** When using formulas with rolling windows, set `warmup_days` (0-730) to the largest
rolling window period used. Extra data is fetched before the display range and trimmed after evaluation.

## Request body

- SnapshotPostRequest: Full chart snapshot configuration (POST body). The `metrics` field supports mixed types: strings (shorthand) and objects (full config). Example: ["price", {"id": "lth_supply", "axis": "left", "style": "area"}] Field names accept both snake_case (canonical) and camelCase forms — e.g. `start_date` or `startDate`, `y_axes` or `yAxes`, `warmup_days` or `warmupDays`.
  - `metric` string, nullable: Single metric ID
  - `metrics` union[], nullable: Metric IDs or config objects (max 6)
    - union
      - string
      - object
  - `template` string, nullable: Template ID
  - `days` integer, nullable
  - `startDate` string, nullable
  - `endDate` string, nullable
  - `warmupDays` integer: Extra days before start_date for formula rolling window warmup (0-730). Data is fetched from (start - warmup_days) but only displayed from start_date.
  - `title` string, nullable
  - `width` integer
  - `height` integer
  - `theme` 'light' | 'dark'
  - `format` 'png' | 'svg' | 'json'
  - `yAxes` YAxisPostConfig[], nullable
    - `id` string, nullable: Axis ID. Auto-generated if omitted.
    - `side` 'left' | 'right', required: left or right
    - `scale` 'linear' | 'log': linear or log
    - `format` 'number' | 'currency' | 'percent' | 'ratio', nullable: Value format: number, currency, percent, ratio
    - `label` string, nullable: Axis label
    - `domain` union[], nullable: [min, max] — use "auto" or number
      - union
        - number
        - integer
        - 'auto'
    - `range` union[], nullable: [from%, to%] — vertical zone in % of chart height (0=bottom, 100=top)
      - union
        - number
        - integer
    - `domainMin` union: Hard minimum domain value (clips from below)
      - number
      - integer
    - `domainMax` union: Hard maximum domain value (clips from above)
      - number
      - integer
    - `noPadding` 'top' | 'bottom' | 'both', nullable: Remove 10% padding from specified edges
  - `overlay` 'price', nullable
  - `formulas` FormulaConfig[], nullable
    - `id` string, nullable: Unique formula ID. Auto-generated if omitted.
    - `expression` string, required: Formula expression, e.g. 'sma(m1, 200)'
    - `label` string, required: Display label
    - `color` string, nullable: Hex color
    - `style` 'line' | 'area' | 'bar': Chart style: line, area, bar
    - `axis` 'left' | 'right': Y-axis side: left or right
    - `y_axis_id` string, nullable: Exact Y-axis ID (e.g. 'axis-diff'). Overrides 'axis' when set.
    - `stroke_width` integer, nullable
    - `fill_opacity` number, nullable
    - `stroke_dash` string, nullable: Dash pattern
    - `stack_group` string, nullable
    - `visible` boolean, nullable
    - `show_in_legend` boolean, nullable: Show in chart legend. Default true.
  - `referenceLines` ReferenceLinePostConfig[], nullable: Horizontal reference lines
    - `y` number, nullable: Static Y value
    - `yFormula` string, nullable: Formula expression for dynamic Y (e.g. 'sma(m1, 200)'). Uses same engine as formulas.
    - `yAxisId` string, nullable: Y-axis ID (defaults to first left axis)
    - `stroke` string, nullable: Line color (default: #9ca3af)
    - `strokeDasharray` string, nullable: Dash pattern, e.g. '3 3' for dashed
    - `label` string, nullable: Label text
  - `referenceAreas` ReferenceAreaPostConfig[], nullable: Shaded reference zones
    - `y1` number, nullable: Static lower Y bound
    - `y2` number, nullable: Static upper Y bound
    - `y1Formula` string, nullable: Formula for lower bound
    - `y2Formula` string, nullable: Formula for upper bound
    - `yAxisId` string, nullable
    - `fill` string, nullable: Fill color (default: #3b82f6)
    - `fillOpacity` number, nullable: Fill opacity (default: 0.1)
    - `label` string, nullable
  - `layerOrder` string[], nullable: Render order (back to front)
  - `params` object, nullable: Runtime parameters for entity-filtered metrics (e.g., {"ticker": "IBIT"})
  - `xAxis` 'date' | 'day_offset', nullable: X axis field. Default 'date'. Use 'day_offset' for indexed series (cycle performance).
  - `heatmapId` string, nullable: Heatmap ID (e.g., 'cost-basis-distribution'). When set, renders a heatmap PNG instead of a line chart. Mutually exclusive with metric/metrics/template.
  - `heatmapPeriod` 'all' | '10y' | '5y' | '3y' | '1y' | '6m' | '3m' | '1m' | '1w', nullable: Period for heatmap bin optimization (default: 'all')
  - `heatmapColorScale` 'soft' | 'viridis' | 'plasma', nullable: Heatmap color scale (default: 'soft')
  - `heatmapYScale` 'linear' | 'log', nullable: Heatmap Y-axis scale (default: 'log')
  - `style` 'line' | 'area' | 'bar', nullable
  - `scale` 'linear' | 'log'

## Response `200`

Chart image (PNG/SVG) or JSON metadata, depending on format field or Accept header

- object

## Other responses

- `400`: Invalid parameters (e.g., unknown metric, conflicting inputs)
- `401`: Missing or invalid API key
- `403`: Requires Pro+ tier, or insufficient grade for requested metrics
- `422`: Validation Error
- `429`: Snapshot rate limit exceeded (per-tier hourly limit)
- `504`: Chart rendering timed out — try a shorter date range

---

[API](https://skmtc.dev/blocklens/apis/blocklens-on-chain-api.md) · [All operations](https://skmtc.dev/blocklens/apis/blocklens-on-chain-api/llms.txt) · [OpenAPI document](https://skmtc.dev/blocklens/apis/blocklens-on-chain-api/revisions/dacc02ae0f9a?raw)
