Menu
On this page

API & MCP

Dashboards API

The Dashboards API programmatically drives what the app does on the dashboard canvas: generating a dashboard from your data, saving edits safely under concurrent access, and browsing version history. Most people build dashboards in the app — reach for this API when you're automating (nightly regeneration, provisioning a dashboard per new dataset, an external editor).

Generate a dashboard

There are three generate targets, matching the three kinds of dashboard:

EndpointFor
POST /datasets/{datasetId}/dashboard/generatea single dataset
POST /projects/{projectId}/views/{viewId}/dashboard/generatea saved view
POST /projects/{projectID}/dashboards/generatea whole project (multi-source)

The dataset and view forms take no body — control them with ?use_ai=true (default) and ?force=false (regenerate an existing one). They return the full dashboard object with a spec, plus an ETag header (see concurrency below).

The project form takes a JSON body naming the sources:

curl -X POST "https://<your-gopie-host>/v1/api/projects/…/dashboards/generate" \
  -H "Authorization: Bearer gp_pub_…" \
  -H "Content-Type: application/json" \
  -d '{"name": "Revenue overview", "intent": "track revenue and top products",
       "dataset_ids": ["…", "…"], "use_ai": true}'

At most 12 datasets and 6 reused views (18 sources total). Validation failures (name_required, no_sources, too_many_datasets) come back as 400.

Stream generation progress

Each generate endpoint has a /generate/stream twin that reports progress as Server-Sent Events while the dashboard is built — the same five phases the app shows:

data: {"type":"progress","message":"Analyzing your data","data":{"phase":"analyzing"}}
data: {"type":"progress","message":"Selecting key metrics","data":{"phase":"metrics"}}
data: {"type":"progress","message":"Validating queries","data":{"phase":"validating"}}
data: {"type":"progress","message":"Designing the layout","data":{"phase":"layout"}}
data: {"type":"progress","message":"Finalizing your dashboard","data":{"phase":"finalizing"}}
data: {"type":"complete","message":"Dashboard generated","data":{"id":"…","spec":{…}}}

Phases are analyzingmetricsvalidatinglayoutfinalizing, a heartbeat fires during long steps, and a terminal complete carries the finished dashboard. If the AI service is unavailable or use_ai=false, GoPie builds a deterministic dashboard in-process and the stream still completes — it never stalls.

Save edits safely

Dashboards use optimistic concurrency so two editors don't clobber each other. Every GET and PUT returns an ETag header — a fingerprint of the dashboard's current state:

ETag: "1720107000123456789"

To update, send that value back in If-Match:

curl -X PUT "https://<your-gopie-host>/v1/api/dashboards/…" \
  -H "Authorization: Bearer gp_pub_…" \
  -H 'If-Match: "1720107000123456789"' \
  -H "Content-Type: application/json" \
  -d '{"spec": {…}, "display_name": "Q3 revenue"}'

If someone else changed the dashboard since you read it, the tags won't match and you get a 412 — reload and retry:

{ "code": 412, "error": "dashboard_modified", "message": "The dashboard was modified by another session. Please reload." }

If-Match is optional; omit it to write unconditionally (at the cost of the safety check).

List, read & delete

Method + pathEffect
GET /dashboardslist dashboards (query, limit, page)
GET /dashboards/{dashboardId}one dashboard + can_edit + ETag
PUT /dashboards/{dashboardId}update spec / display_name (honours If-Match)
DELETE /dashboards/{dashboardId}delete it (204)
GET /projects/{projectId}/dashboardsdashboards in a project

Refine with a prompt — POST /dashboards/{dashboardId}/refine

Apply a natural-language edit ("add a discount KPI", "make the revenue chart a line") to a dashboard or a single tile — the API behind dashboard chat:

{ "user_prompt": "add an average-discount KPI", "scope": "dashboard" }

For a tile-scoped edit, set "scope": "tile" and a "tile_path" like rows.0.items.2. The refined dashboard comes back in the response.

Browse version history

Every generate, edit and refine records a version:

Method + pathEffect
GET /dashboards/{dashboardId}/versionslist versions (spec omitted, for a light payload)
GET /dashboards/{dashboardId}/versions/{versionId}one version, with its full spec
POST /dashboards/{dashboardId}/versions/{versionId}/restorerestore it (honours If-Match)
PATCH /dashboards/{dashboardId}/versions/{versionId}name it ({"message": "…"}) or clear the name
POST /dashboards/{dashboardId}/versions/{versionId}/pin · /unpinpin against cleanup

Plan a project dashboard (wizard)

The app's project dashboard wizard is three endpoints you can call directly to build a guided flow: POST /projects/{projectID}/dashboards/recommend-intent (suggest what the dashboard should cover), recommend-datasets (rank which datasets to include), and plan-views (propose the joins as validated view definitions). Each returns structured suggestions you can present, edit, then feed into the project generate call above. When the AI service is down, recommend-datasets falls back to ranking by row count so the flow still works.