Guide · 2026-10-10

Charts in images

A chart is a layer. Numbers go in as a comma-separated string, so a weekly report, a KPI card or a README badge is one template and one variable.

The layer

{ "name": "week", "type": "chart", "kind": "bar",
  "x": 72, "y": 330, "width": 700, "height": 240,
  "values": "120,180,150,210,260,190,174",
  "labels": "Mon,Tue,Wed,Thu,Fri,Sat,Sun",
  "fill": "#6366f1", "show_values": true }

kind is bar, line, area, pie or donut. values is an array of numbers or a comma-separated string; labels likewise, one per value. The chart is drawn as SVG inside the renderer at exactly the layer's size, so it is sharp at scale: 2 and needs no JavaScript library in the page.

The string form is the point: "values": "{{values}}" lets a variable carry the whole series, which is how the weekly report starter works.

A weekly report from Python

Copy the starter, keep it as your own template, render it every Monday.

import os, requests

API = "https://api.imageapis.com"
H = {"X-API-Key": os.environ["IMAGEAPIS_KEY"]}

starter = requests.get(f"{API}/v1/starters/weekly-report", headers=H).json()
tpl = requests.post(f"{API}/v1/templates", headers=H, json=starter["template"]).json()

week = [120, 180, 150, 210, 260, 190, 174]
img = requests.post(f"{API}/v1/images", headers=H, json={
    "template": tpl["id"],
    "variables": {
        "site": "example.com", "title": "Weekly signups",
        "total": f"{sum(week):,}", "change": "+12% vs last week",
        "values": ",".join(map(str, week)), "labels": "Mon,Tue,Wed,Thu,Fri,Sat,Sun",
        "split": "62,38", "split_labels": "Mobile,Desktop",
        "trend": "40,52,48,61,70,66,80",
    },
    "scale": 2,
}).json()
print(img["url"])

One image, one unit. The starter has three charts: the bar chart of the week, a donut with a legend, and a smoothed area trend. Change a colour or a position with modifications, like any layer:

"modifications": [{"name": "bars", "fill": "#22c55e", "show_values": False}]

A chart that re-renders when the numbers change

Signed URLs render on the first fetch and cache after that, and the query string is the variables. So a sparkline in a README, a status page or an email is a URL you build, not a render you schedule:

import hmac, hashlib
from urllib.parse import urlencode

base, secret, tpl_id = "sb_…", "sbs_…", "tpl_…"
query = urlencode({"values": "40,52,48,61,70,66,80", "labels": "W1,W2,W3,W4,W5,W6,W7"})
msg = f"/s/{base}/{tpl_id}.png?{query}"
sig = hmac.new(secret.encode(), msg.encode(), hashlib.sha256).hexdigest()
url = f"https://img.imageapis.com{msg}&sig={sig}"

Identical URLs are served from the edge for free; a new set of numbers is a new URL and one new render. The signed URLs guide has the rest: expiry, locking a base to one template, revocation.

Properties

Property Applies to What it does
kind all bar (default), line, area, pie, donut
values all Numbers: an array, or a comma-separated string (placeholders work). Up to 200
labels all One per value. Under bars and points; a legend beside a pie or donut
fill bar, line, area The series colour. Default indigo
colors all A colour per value; cycles when shorter. Pies use a built-in palette without it
track bar, line, area Grid line colour. none hides the grid
show_values all Writes each value above its bar or point, or a percentage on each slice
unit all Appended to each value: %, k, ms
show_labels all Default on when labels are given
label_color, label_size, font all Label styling. Font is any Google Fonts family, like a text layer
axis_min, axis_max bar, line, area Pin the scale. Default 0 to the largest value (negatives extend the bottom)
gap bar Pixels between bars
line_width, smooth line, area Stroke width; curve through the points
thickness donut Ring thickness as a fraction of the radius, default 0.38
padding, background, radius, opacity, rotation all The usual layer box properties

From an agent

Over MCP, "render a bar chart of these numbers as a dark card" is one create_image call with an inline template: the agent writes the chart layer, you get the URL. The free chart to image tool shows the exact request for any combination of the options above.

Get a free key: 150 images a month API reference