API Reference¶
The CloviCharts API lets you integrate CloviCharts into your own applications and automations.
All endpoints are served over HTTPS from https://clovicharts.clovitek.com.
Authentication¶
Authenticate every request with a Bearer token in the Authorization header. Generate a
token from your account settings on the CloviCharts dashboard.
Keep your token secret
Treat your API token like a password. Send it only over HTTPS and never commit it to source control — load it from an environment variable instead.
Responses & errors¶
All responses are JSON. Successful calls return 2xx; client errors return 4xx with a
JSON body describing the problem. Common status codes:
| Status | Meaning |
|---|---|
200 |
Success |
400 |
Bad request — check your parameters |
401 |
Missing or invalid token |
404 |
Resource not found |
429 |
Rate limit exceeded — slow down and retry |
500 |
Server error — retry or contact support |
clovicharts API Reference¶
Service: CloviCharts Port: 8966 Engine: chartjs-node-canvas Note: This service uses Express (server.js). The api-doc-generator-agent handles Flask only; docs were extracted manually.
Rate limit: 120 requests/minute on all /api/ routes.
Supported chart types: bar, line, pie, donut, scatter, radar, polar, sparkline, competitive_radar, funnel, bullet, slope, heatcalendar, lollipop, waterfall
Themes: clovitek (dark navy + cyan, default), dark (Catppuccin), light (white)
Output formats: png (default), webp (requires sharp)
GET /health¶
Returns service health status.
Response:
{
"status": "ok",
"service": "CloviCharts",
"version": "1.0.0",
"port": 8966,
"charts_rendered": 42,
"uptime_seconds": 3600,
"supported_types": 15,
"output_dir": "/root/clovicharts/output"
}
GET /api/chart-types¶
Returns the full catalog of supported chart types with example configs.
Response:
{
"version": "1.0.0",
"engine": "chartjs-node-canvas",
"total": 15,
"chart_types": [
{
"type": "bar",
"label": "Bar Chart",
"engine": "chartjs",
"variants": ["vertical", "horizontal", "stacked", "grouped"],
"formats": ["png", "webp"],
"example_config": {
"type": "bar",
"data": { "labels": ["Q1","Q2","Q3","Q4"], "datasets": [{"label":"Revenue ($k)","data":[120,190,150,220]}] },
"options": { "width": 800, "height": 500, "theme": "clovitek" }
}
}
]
}
GET /api/chart-types/examples¶
Renders a preview PNG for every chart type and returns their URLs. Writes files to the output directory.
Response:
{
"examples": [
{ "type": "bar", "label": "Bar Chart", "url": "http://localhost:8966/charts/example_bar.png" },
{ "type": "line", "label": "Line Chart", "url": "http://localhost:8966/charts/example_line.png" }
]
}
error field replaces url for that entry.
POST /api/charts/generate¶
Generate a single chart image and return its URL.
Body:
{
"type": "bar",
"data": {
"labels": ["Q1", "Q2", "Q3", "Q4"],
"datasets": [
{ "label": "Revenue ($k)", "data": [120, 190, 150, 220] }
]
},
"options": {
"width": 800,
"height": 500,
"theme": "clovitek",
"format": "png",
"title": "Quarterly Revenue",
"colors": ["#06b6d4", "#8b5cf6"],
"ai_narrative": false,
"ai_title": false,
"base64": false
}
}
Field notes:
- type (required): one of the 15 supported chart types
- data (required): ChartJS-compatible data object; data.datasets must be a non-empty array
- options.width / options.height: capped at 2400×1600; product must not exceed 3,840,000 px
- options.theme: "clovitek" | "dark" | "light" (default: "clovitek")
- options.format: "png" | "webp" (default: "png")
- options.ai_narrative: if true, appends a one-sentence Gemini insight as chart subtitle
- options.ai_title: if true and no title provided, asks Gemini to generate a title
- options.base64: if true, includes raw base64 image in response
Response headers: X-Chart-ID, X-Chart-URL, X-Render-Ms, X-AI-Narrative (when narrative generated)
Response:
{
"chart_id": "uuid-v4",
"url": "http://localhost:8966/charts/uuid-v4.png",
"narrative": "Sales peaked in Q4 driven by holiday demand.",
"title": "Quarterly Revenue",
"width": 800,
"height": 500,
"theme": "clovitek",
"format": "png",
"render_ms": 142,
"created_at": "2026-06-10T12:00:00.000Z",
"base64": "<omitted unless options.base64=true>"
}
Error responses:
- 400 MISSING_TYPE — type field absent
- 400 MISSING_DATA — data field absent
- 400 DATASET_EMPTY — data.datasets is missing or empty
- 400 INVALID_CHART_TYPE — unrecognised type value
- 400 CHART_TOO_LARGE — width × height exceeds 3,840,000
- 500 RENDER_FAILED — chartjs-node-canvas rendering error
GET /api/charts/gallery¶
Returns the last 20 of the 100 most recently generated charts (in-memory, resets on restart).
Response:
{
"charts": [
{
"chart_id": "uuid-v4",
"type": "bar",
"theme": "clovitek",
"format": "png",
"width": 800,
"height": 500,
"title": "Quarterly Revenue",
"narrative": null,
"url": "http://localhost:8966/charts/uuid-v4.png",
"created_at": "2026-06-10T12:00:00.000Z",
"render_ms": 142
}
],
"total": 100
}
POST /api/charts/recommend¶
Ask the AI (Gemini) to recommend the best chart type for a given set of data columns.
Body:
{
"columns": [
{ "name": "month", "type": "string" },
{ "name": "revenue", "type": "number" },
{ "name": "expenses", "type": "number" }
]
}
Field notes:
- columns (required): array of column descriptors; must be a non-empty array
Response:
{
"recommended": "line",
"reason": "Two numeric series over a time-ordered string axis suit a line chart.",
"alternatives": ["bar", "scatter"]
}
{"recommended":"bar","reason":"AI unavailable — defaulted to bar","alternatives":["line","pie"]} when Gemini is unreachable or key is absent.
Error responses:
- 400 MISSING_COLUMNS — columns field absent or not an array
POST /api/charts/batch¶
Generate up to 10 charts in a single request. Each entry follows the same shape as the generate body.
Body:
{
"charts": [
{
"type": "bar",
"data": { "labels": ["A","B"], "datasets": [{"label":"X","data":[1,2]}] },
"options": { "width": 600, "height": 400, "theme": "light" }
},
{
"type": "pie",
"data": { "labels": ["A","B","C"], "datasets": [{"data":[30,50,20]}] }
}
]
}
Field notes:
- charts (required): array of chart specs (max 10)
- Each spec: same type, data, options as /api/charts/generate
- Batch renders always use png format; ai_narrative is not applied
- Per-entry errors do not abort the batch; failed entries get status: "error"
Response:
{
"charts": [
{ "status": "ok", "chart_id": "uuid1", "url": "http://localhost:8966/charts/uuid1.png", "render_ms": 110 },
{ "status": "error", "error": "Invalid type: xyz" }
],
"total": 2,
"failed": 1
}
Error responses:
- 400 MISSING_CHARTS — charts field absent or not an array
- 400 BATCH_TOO_LARGE — more than 10 charts in the array
GET /api/charts/:id¶
Retrieve metadata for a previously generated chart by its UUID.
Path params: id — chart UUID (.png/.webp/.json extensions are stripped automatically)
Response:
{
"chart_id": "uuid-v4",
"type": "bar",
"theme": "clovitek",
"format": "png",
"width": 800,
"height": 500,
"title": "Quarterly Revenue",
"narrative": null,
"url": "http://localhost:8966/charts/uuid-v4.png",
"created_at": "2026-06-10T12:00:00.000Z",
"render_ms": 142
}
Error responses:
- 404 NOT_FOUND — no metadata file found for the given ID
DELETE /api/charts/:id¶
Delete all files for a chart (.png, .webp, .json) and remove it from the in-memory gallery.
Path params: id — chart UUID (extensions stripped automatically)
Response:
Error responses:
- 404 NOT_FOUND — no files found for the given ID
GET /charts/:filename (static)¶
Serve a rendered chart image file directly. Files are cached for 1 day (Cache-Control: public, max-age=86400).
Examples:
- GET /charts/uuid-v4.png
- GET /charts/uuid-v4.webp
- GET /charts/example_bar.png