Chart API Documentation
Generate beautiful charts with a simple API. No dependencies, render charts server-side as images (PNG, JPEG, SVG).
Quick Start
Basic Example
curl -X POST https://api.chartone.dev/v1/chart \
-H "Content-Type: application/json" \
-d '{
"type": "bar",
"data": {
"labels": ["Q1", "Q2", "Q3", "Q4"],
"datasets": [{
"label": "Revenue",
"data": [120, 190, 300, 500]
}]
}
}' \
--output bar-chart.pngURL Embedding
<img src="https://api.chartone.dev/v1/chart?type=bar&data={%22labels%22:[%22A%22,%22B%22,%22C%22],%22datasets%22:[{%22data%22:[10,20,30]}]}&theme=modern&width=600&height=400">Authentication
🎉 No API key required to get started! The API works without authentication, but charts will include a small watermark. Sign up for a free account to remove the watermark and get higher limits—no credit card required.
Anonymous (No Signup)
Start using the API immediately without any signup. Perfect for testing and low-volume use.
- No signup required
- 20 requests per day per IP
- Small watermark on charts
- 2 themes (Modern, Minimal)
- Max size: 800x600
Free Account
Sign up for a free account to remove the watermark and get tracked monthly limits.
- No watermark
- 2,000 requests/month
- All chart types
- 500 short URLs
- No credit card required
Using Your API Key
Once you have an API key, you can authenticate your requests using either method:
Method 1: Authorization Header (Recommended for POST)
curl -X POST https://api.chartone.dev/v1/chart \\
-H "Authorization: Bearer YOUR_API_KEY" \\
-H "Content-Type: application/json" \\
-d '{"type": "bar", "data": {...}}'Method 2: Query Parameter (For GET requests)
curl "https://api.chartone.dev/v1/chart?apiKey=YOUR_API_KEY&type=bar&data=..."Chart Types
We support all major chart types from Chart.js. Each type can be customized with themes, colors, and options.
Line Chart
Simple line chart with one or multiple series
{
"type": "line",
"data": {
"labels": ["Jan", "Feb", "Mar", "Apr", "May"],
"datasets": [{
"label": "Sales",
"data": [12, 19, 15, 25, 22]
}]
}
}Bar Chart
Vertical bar chart for comparisons
{
"type": "bar",
"data": {
"labels": ["Product A", "Product B", "Product C"],
"datasets": [{
"label": "Units Sold",
"data": [65, 59, 80]
}]
}
}Pie Chart
Circular pie chart for proportions
{
"type": "pie",
"data": {
"labels": ["Desktop", "Mobile", "Tablet"],
"datasets": [{
"data": [55, 35, 10]
}]
}
}Doughnut Chart
Pie chart with center hole
{
"type": "doughnut",
"data": {
"labels": ["Chrome", "Firefox", "Safari", "Edge"],
"datasets": [{
"data": [45, 25, 20, 10]
}]
}
}Area Chart
Line chart with filled area
{
"type": "area",
"data": {
"labels": ["Mon", "Tue", "Wed", "Thu", "Fri"],
"datasets": [{
"label": "Page Views",
"data": [1200, 1900, 1500, 2500, 2200]
}]
}
}Radar Chart
Multi-axis radar/spider chart
{
"type": "radar",
"data": {
"labels": ["Speed", "Power", "Accuracy", "Stamina", "Defense"],
"datasets": [{
"label": "Player Stats",
"data": [85, 70, 90, 75, 80]
}]
}
}Themes
Choose from 20+ professionally designed themes to match your brand or use case.
Modern
Balanced neutral background, soft gridlines, fresh palette
Classic
Traditional serif style with timeless color palette
Minimal
Clean, distraction-free with transparent background
Dark
High contrast dark mode with vibrant accent colors
Economist
Data journalism style with authoritative serif font
Financial
Bloomberg-inspired terminal style with monospace font
Scientific
Academic research style with viridis-inspired palette
Presentation
Bold colors and large fonts optimized for slides
Monochrome
Grayscale only, perfect for print and accessibility
Material
Google Material Design with bold primary colors
FiveThirtyEight
Data-driven journalism style inspired by FiveThirtyEight
Pastel
Soft muted colors perfect for lifestyle content
High Contrast
Maximum accessibility with WCAG AAA compliant colors
Corporate
Professional business blue tones for B2B and reports
Vibrant
Bold energetic palette for social media and campaigns
Ocean
Cool blue-green gradient inspired by the sea
Sunset
Warm gradient from yellow to pink for engaging visuals
Nature
Earth tones and organic greens for environmental data
Retro
Vintage 1970s palette with muted warm tones
Neon
Cyberpunk-inspired bright colors on dark background
Using Themes
{
"type": "bar",
"theme": "dark",
"data": { ... }
}API Endpoints
/v1/chartGenerate a chart from JSON configuration.
Request Body
{
"type": "bar",
"theme": "modern",
"data": {
"labels": ["Q1", "Q2", "Q3"],
"datasets": [{
"label": "Revenue",
"data": [100, 200, 300]
}]
},
"options": {
"title": "Quarterly Revenue"
},
"width": 800,
"height": 400,
"format": "png"
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| type | string | Yes | Chart type (line, bar, pie, etc.) |
| data | object | Yes | Chart data with labels and datasets |
| theme | string | No | Theme name (default: modern) |
| width | number | No | Chart width in pixels (100-4000) |
| height | number | No | Chart height in pixels (100-4000) |
| format | string | No | Output format (png, jpeg, svg) |
| xAxis | string | No | X-axis label |
| yAxis | string | No | Y-axis label |
| targetLine | number/object | No | Target line value or {value, label} (bar, line, area, stacked bar only) |
| averageLine | boolean | No | Show average line (bar, line, area, stacked bar only) |
| highlight | string | No | Comma-separated 1-based indices to highlight (e.g., "1,3,6") |
| devicePixelRatio | number | No | Pixel ratio for high-DPI (1-4, default: 2) |
/v1/chartGenerate a chart via URL parameters. Perfect for embedding charts in emails, Notion, or any platform that supports images.
Note: All parameters are the same as POST /v1/chart, but JSON values (like data) must be URL-encoded. Authentication via ?apiKey=YOUR_API_KEY query parameter.
⚠️ Security Warning: API Key in URLs
Including your API key in URLs (?apiKey=YOUR_KEY) exposes it in browser history, server logs, and referrer headers.
Safer alternatives:
- • Use POST /v1/chart with Authorization header (recommended)
- • Use POST /v1/short-url to create shareable URLs without exposing your key
- • Only use GET with
?apiKey=in server-side contexts
Basic Example
<img src="https://api.chartone.dev/v1/chart?type=bar&data={"labels":["A","B","C"],"datasets":[{"data":[10,20,30]}]}&theme=modern&width=600&height=400">Advanced Example (with axis labels and highlighting)
<img src="https://api.chartone.dev/v1/chart?apiKey=YOUR_API_KEY&type=bar&data={"labels":["Q1","Q2","Q3","Q4"],"datasets":[{"label":"Sales","data":[120,190,300,250]}]}&xAxis=Quarter&yAxis=Revenue ($)&highlight=3&theme=modern&width=800&height=400">/v1/short-urlCreate a short URL for easy sharing and embedding. Short URLs are permanent (until expiry) and don't expose your chart configuration.
Request Body
{
"chartConfig": {
"type": "line",
"data": {
"labels": ["Jan", "Feb", "Mar"],
"datasets": [{
"label": "Revenue",
"data": [100, 150, 200]
}]
}
},
"theme": "modern",
"width": 800,
"height": 400,
"format": "png",
"expiresInDays": 30
}Response
{
"id": "abc123xyz",
"shortUrl": "/render/abc123xyz",
"fullUrl": "https://api.chartone.dev/render/abc123xyz",
"expiresInDays": 30
}Plan Limits: Free accounts can create up to 500 short URLs with 7-day expiry. Paid plans get unlimited short URLs with 180-day expiry.
/v1/usageGet your current usage statistics and quota information.
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://api.chartone.dev/v1/usageResponse
{
"plan": "free",
"period": "monthly",
"quota": {
"limit": 2000,
"used": 456,
"remaining": 1544,
"exceeded": false
}
}/v1/themesList all available themes.
curl https://api.chartone.dev/v1/themesCode Examples
Advanced Features (Axis Labels, Target Line, Highlighting)
// Using new parameters for enhanced charts
const response = await fetch('https://api.chartone.dev/v1/chart', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY'
},
body: JSON.stringify({
type: 'bar',
theme: 'modern',
data: {
labels: ['Q1', 'Q2', 'Q3', 'Q4'],
datasets: [{
label: 'Sales',
data: [120, 190, 300, 250]
}]
},
xAxis: 'Quarter', // X-axis label
yAxis: 'Revenue ($K)', // Y-axis label
targetLine: { // Target line with label
value: 200,
label: 'Goal'
},
averageLine: true, // Show average line
highlight: '3', // Highlight Q3 (1-based index)
width: 800,
height: 400
})
});JavaScript (Fetch)
async function generateChart() {
const response = await fetch('https://api.chartone.dev/v1/chart', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY'
},
body: JSON.stringify({
type: 'bar',
theme: 'modern',
data: {
labels: ['Q1', 'Q2', 'Q3', 'Q4'],
datasets: [{
label: 'Revenue',
data: [120, 190, 300, 500]
}]
}
})
});
const blob = await response.blob();
const url = URL.createObjectURL(blob);
document.getElementById('chart').src = url;
}Python (Requests)
import requests
def generate_chart():
response = requests.post(
'https://api.chartone.dev/v1/chart',
headers={
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
'type': 'bar',
'theme': 'modern',
'data': {
'labels': ['Q1', 'Q2', 'Q3', 'Q4'],
'datasets': [{
'label': 'Revenue',
'data': [120, 190, 300, 500]
}]
}
}
)
with open('chart.png', 'wb') as f:
f.write(response.content)React Component
import React, { useEffect, useState } from 'react';
function ChartImage() {
const [chartUrl, setChartUrl] = useState('');
useEffect(() => {
async function generateChart() {
const response = await fetch('https://api.chartone.dev/v1/chart', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY'
},
body: JSON.stringify({
type: 'bar',
theme: 'modern',
data: {
labels: ['Q1', 'Q2', 'Q3', 'Q4'],
datasets: [{
label: 'Revenue',
data: [120, 190, 300, 500]
}]
}
})
});
const blob = await response.blob();
const url = URL.createObjectURL(blob);
setChartUrl(url);
}
generateChart();
}, []);
return chartUrl ? <img src={chartUrl} alt="Chart" /> : <p>Loading...</p>;
}Pricing
No signup needed
- 20 charts/day
- Watermark
- 2 basic themes
- PNG only
No watermark!
- 2,000/mo
- No watermark
- 5 themes
- PNG format
- Signed URLs
- 500 short URLs (7d)
Billed annually ($190/yr)
- 50,000/mo
- 10 premium themes
- PNG, JPEG, SVG
- Signed URLs
- Unlimited short URLs (180d)
Billed annually ($390/yr)
- 150,000 charts/mo
- All 20+ chart types
- All 20 themes
- PNG, JPEG, SVG
- Unlimited short URLs (180d)
Billed annually ($790/yr)
- 350,000 charts/mo
- All features
- Priority support
- Custom palettes
- 99.9% SLA
Rate Limits
We enforce rate limits to prevent server abuse and ensure reliable service for all users. Limits scale with your plan to support both casual usage and high-volume integrations.
Anonymous Users (No API Key)
- Per-minute: 20 requests
- Daily: 20 requests per IP
- Monthly: 600 requests per IP
Free Account
- Per-minute: 500 requests
- Monthly: 2,000 requests
Starter Plan
- Per-minute: 1,000 requests
- Monthly: 50,000 requests
Growth Plan
- Per-minute: 2,000 requests
- Monthly: 150,000 requests
Pro Plan
- Per-minute: 3,000 requests
- Monthly: 350,000 requests
Need higher limits? Contact us if you have legitimate use cases requiring higher throughput. We're happy to work with you on custom solutions.
Rate Limit Headers
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 856
X-Plan: freeTroubleshooting
Bad Request
Invalid data format or missing required fields
Solution: Ensure your data object includes all required fields
Unauthorized
Invalid or revoked API key
Solution: Check your API key is correct and active
Forbidden
Resource not available on your plan
Solution: Upgrade your plan or use an available resource
Too Many Requests
Rate limit exceeded
Solution: Wait for the rate limit to reset or upgrade your plan
Ready to Get Started?
Start creating beautiful charts today. No credit card required.