Docs menu
Quick start
Turn a JSON spec into a chart image with one URL, and put it in an <img>.
A chart is a JSON spec in a URL. The API reads the spec and sends back an image, so anything that shows an <img> can show the chart: an email, a Slack message, a link preview or a PDF.
Write a spec
A spec needs a type and its data. Everything else has a default. This one draws a bar chart in the ocean theme:
{
"type": "bar",
"theme": "ocean",
"data": {
"labels": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
"series": [
{
"name": "Signups",
"values": [142, 168, 155, 189, 204, 96, 88]
}
]
},
"options": {
"title": "Signups this week"
}
}The spec reference lists every field for each of the 11 chart types.
Make the URL
Encode the spec's JSON as base64url and put it in the c parameter of /v1/chart:
https://api.chartshot.dev/v1/chart?c=eyJ0eXBlIjoiYmFyIiwidGhlbWUiOiJvY2VhbiIsImRhdGEiOnsibGFiZWxzIjpbIk1vbiIsIlR1ZSIsIldlZCIsIlRodSIsIkZyaSIsIlNhdCIsIlN1biJdLCJzZXJpZXMiOlt7Im5hbWUiOiJTaWdudXBzIiwidmFsdWVzIjpbMTQyLDE2OCwxNTUsMTg5LDIwNCw5Niw4OF19XX0sIm9wdGlvbnMiOnsidGl0bGUiOiJTaWdudXBzIHRoaXMgd2VlayJ9fQOpen that URL and the API draws the chart:
To try a spec by hand, c also takes plain JSON that starts with {, percent-encoded as any URL value is. Base64url makes shorter URLs for most specs, so use it in code.
Build the URL in code
Any language that can make base64url can make the URL, with no library:
const spec = {
"type": "bar",
"theme": "ocean",
"data": {
"labels": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
"series": [
{
"name": "Signups",
"values": [142, 168, 155, 189, 204, 96, 88]
}
]
},
"options": {
"title": "Signups this week"
}
};
const c = Buffer.from(JSON.stringify(spec)).toString("base64url");
const url = `https://api.chartshot.dev/v1/chart?c=${c}`;
console.log(url);import base64, json
spec = {
"type": "bar",
"theme": "ocean",
"data": {
"labels": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
"series": [
{
"name": "Signups",
"values": [142, 168, 155, 189, 204, 96, 88]
}
]
},
"options": {
"title": "Signups this week"
}
}
text = json.dumps(spec, separators=(",", ":"), ensure_ascii=False)
c = base64.urlsafe_b64encode(text.encode()).rstrip(b"=").decode()
url = f"https://api.chartshot.dev/v1/chart?c={c}"
print(url)Python adds = padding at the end, which the API also accepts, but the code above strips it so both languages give the same URL.
Put it in a page
Use the URL as an image's src. Set width and height to the chart's size in CSS pixels, so the page keeps the space while the image loads:
<img src="https://api.chartshot.dev/v1/chart?c=eyJ0eXBlIjoiYmFyIiwidGhlbWUiOiJvY2VhbiIsImRhdGEiOnsibGFiZWxzIjpbIk1vbiIsIlR1ZSIsIldlZCIsIlRodSIsIkZyaSIsIlNhdCIsIlN1biJdLCJzZXJpZXMiOlt7Im5hbWUiOiJTaWdudXBzIiwidmFsdWVzIjpbMTQyLDE2OCwxNTUsMTg5LDIwNCw5Niw4OF19XX0sIm9wdGlvbnMiOnsidGl0bGUiOiJTaWdudXBzIHRoaXMgd2VlayJ9fQ" width="600" height="300" alt="Signups this week">The image is drawn at scale 2, twice those pixels, so it stays sharp on high-density screens.
Limits on keyless URLs
URLs without a key are free. Each image carries a small Chartshot badge, each IP address can draw 60 charts a minute, and an image can be up to 5,000,000 pixels (width × height × scale², enough for every preset at scale 2). A chart the CDN has already drawn doesn't count.
Next steps
- Build a spec in the playground, which writes the URL, HTML and code for you.
- In JavaScript or TypeScript, the SDK signs URLs and stores charts with your key.
- Let an AI assistant draw charts with the MCP server.
- Start from one of the gallery templates.
- Read the guides for email, Slack and Next.js OG images.