Skip to content

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.

curl https://clovicharts.clovitek.com/api/me \
  -H "Authorization: Bearer $CLOVI_TOKEN"
import requests

resp = requests.get(
    "https://clovicharts.clovitek.com/api/me",
    headers={"Authorization": f"Bearer {token}"},
)
resp.raise_for_status()
print(resp.json())
const resp = await fetch("https://clovicharts.clovitek.com/api/me", {
  headers: { Authorization: `Bearer ${token}` },
});
const data = await resp.json();
console.log(data);
import axios from "axios";

const { data } = await axios.get(
  "https://clovicharts.clovitek.com/api/me",
  { headers: { Authorization: `Bearer ${token}` } }
);
console.log(data);

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" }
  ]
}
On render failure an 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_TYPEtype field absent - 400 MISSING_DATAdata field absent - 400 DATASET_EMPTYdata.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"]
}
Falls back to {"recommended":"bar","reason":"AI unavailable — defaulted to bar","alternatives":["line","pie"]} when Gemini is unreachable or key is absent.

Error responses: - 400 MISSING_COLUMNScolumns 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_CHARTScharts 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:

{ "deleted": true, "id": "uuid-v4" }

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