You can automate full dashboard updates without touching the UI. The normal flow is to generate a new CSV, send only the rows to append with `mode: append`, and let Luminon recalculate the connected KPI cards and charts automatically. No token is needed for this flow because it uses the local renderer API.
For `Retail Analytics Overview` (`db_gxclrszt`), the idea is straightforward: update-retail-analytics.csv only contains the new rows for `March 2026`. That file can come from an automated dump from PostgreSQL, MySQL, or even from a plain file generated by another process.
#!/usr/bin/env bash
set -euo pipefail
CSV_FILE="${1:-update-retail-analytics.csv}"
DATASET_ID="${DATASET_ID:-ds_sgo6cmlj}"
DASHBOARD_ID="${DASHBOARD_ID:-db_gxclrszt}"
API_URL="${API_URL:-http://localhost:5173/api/datasets/${DATASET_ID}}"
jq -Rs --arg mode "append" --argjson allowSchemaChange false '{csv: ., mode: $mode, allowSchemaChange: $allowSchemaChange}' < "$CSV_FILE" \
| curl -sS -X PATCH "$API_URL" \
-H "Content-Type: application/json" \
--data-binary @- \
| jq -r '.dataset.id + " updated at " + (.dataset.updatedAt // "unknown")'
echo "Dashboard ${DASHBOARD_ID} will refresh automatically when the dataset update is broadcast."Execution example and output:
sh update_db_gxclrszt.sh
ds_sgo6cmlj updated at 2026-06-06T19:28:56.019Z
Dashboard db_gxclrszt will refresh automatically when the dataset update is broadcast.There is no separate dashboard mutation: when the dataset changes, Luminon broadcasts the update and the dashboard recalculates with the same filters, layout, and charts already defined. If the browser is not open at that moment, just refresh the dashboard page.
If you want to run this every month, add a `cron` entry for day 1. For example:
0 2 1 * * /bin/bash <your-script-path>/update_db_gxclrszt.sh >> /path/to/log/luminon-retail-analytics.log 2>&1The same strategy works if the CSV comes from PostgreSQL, MySQL, or any flat source. The important part is that the final file only includes new rows for `append` and keeps the same schema.
The pattern `${1:-update-retail-analytics.csv}` means: use the first argument if you pass one; otherwise use the default filename. That is why the script assumes you run it from `public/tutorials/build-first-dashboard` or from another directory where that CSV is already available.
You can also do the same thing from Python if you prefer a script that is easier to integrate with other processes.
#!/usr/bin/env python3
import pathlib
import sys
import requests
csv_path = pathlib.Path(sys.argv[1] if len(sys.argv) > 1 else "update-retail-analytics.csv")
dataset_id = "ds_sgo6cmlj"
api_url = f"http://localhost:5173/api/datasets/{dataset_id}"
payload = {
"csv": csv_path.read_text(encoding="utf-8"),
"mode": "append",
"allowSchemaChange": False,
}
response = requests.patch(api_url, json=payload, timeout=30)
response.raise_for_status()
dataset = response.json()["dataset"]
print(f"{dataset['id']} updated at {dataset.get('updatedAt', 'unknown')}")Important: if your file only contains an incremental update, use `append` in `mode`; do not use `replace`. Luminon keeps a previous snapshot and you can restore it with `restore_dataset_snapshot` through the MCP. If you want to replace the entire dataset, then use `replace`, but the file must contain the complete dataset.