Chart URL maker
Set up a chart and get a URL that draws it, as SVG or PNG, for a README, an email, a status page or a doc. The URL is signed with your base's secret, right here in your browser, so only you can make URLs that bill your plan.
https://img.imageapis.com/s/sb_…/chart.svg?kind=line&values=40,52,48,61,70,66,80&labels=W1,W2,W3,W4,W5,W6,W7&sig=…What this makes
A URL that is the chart. Paste it anywhere an image goes: a README, a Notion page, an email, a status page, a slide. The first fetch draws the chart and every fetch after that comes from the cache, so a busy README costs one image, not one per view. New numbers make a new URL, and that URL draws the new chart.
SVG, the default, is drawn without a browser: a few KB, sharp at any size, and served with a policy that blocks scripts. Use PNG where SVG doesn't show: Gmail and most email clients, and social cards.
The preview above is free and makes no signed URL. The URL in the box is built as you type. Each new URL costs one image on the plan behind the base the first time anything fetches it.
Your base and its secret
A signed base is created once with your API key. Lock it to charts, so its secret can only ever sign chart URLs:
curl -X POST https://api.imageapis.com/v1/signed-bases -H 'X-API-Key: YOUR_KEY' \
-H 'Content-Type: application/json' -d '{"name": "Charts", "template": "chart"}'
The response has the base's id (sb_…) and secret (sbs_…). On this page the secret goes into a field the page never sends: your browser computes the signature itself, with WebCrypto, and the preview is made from the chart's settings alone. Delete the base and every URL built on it stops working.
The same URL from your own code
To chart live numbers, build the URL where the numbers are. For a README that redraws its chart every day, the charts in a README guide has a complete GitHub Action. Python:
import hmac, hashlib
from urllib.parse import urlencode
def chart_url(base, secret, ext="svg", **params):
path = f"/s/{base}/chart.{ext}?{urlencode(params, safe=',')}"
sig = hmac.new(secret.encode(), path.encode(), hashlib.sha256).hexdigest()
return f"https://img.imageapis.com{path}&sig={sig}"
print(chart_url("sb_…", "sbs_…", kind="line", values="40,52,48,61,70", labels="Mon,Tue,Wed,Thu,Fri", smooth="true"))
Node:
import { createHmac } from "node:crypto";
function chartUrl(base, secret, params, ext = "svg") {
const path = `/s/${base}/chart.${ext}?${new URLSearchParams(params)}`;
const sig = createHmac("sha256", secret).update(path).digest("hex");
return `https://img.imageapis.com${path}&sig=${sig}`;
}
Keep the secret on your server, in an environment variable, and never in code that runs in a reader's browser. The query takes every chart property, not only the ones on this form: padding, radius, transparent, axis_min, axis_max, unit, label_color, font and more. A per-value colors list is comma-separated. The charts guide lists them all, and the signed URLs guide covers expiry with exp. For a single PNG with a title instead of a URL, the chart to image tool makes one.