statsig-dashboard
Create or read Statsig dashboards through the Console API. Use when building a valid `POST /console/v1/dashboards` body, reading `GET /console/v1/dashboards/{id}` into a create-compatible shape, or appending or replacing dashboard widgets through the related widget endpoints.
Skill body
Create Statsig Dashboard
Build valid dashboard API requests for the console v1 dashboards API and execute them with the bundled scripts.
Read references/dashboard-api.md for the exact field-level schema, supported values, and ready-to-edit examples.
The command examples below assume you are running from this skill directory.
Quick Start
- Export the API key:
export STATSIG_CONSOLE_API_KEY="..." - Save the request body to a JSON file.
- Run the matching script:
python3 scripts/create_dashboard.py \
--body-file /tmp/dashboard.json
Companion Scripts
scripts/create_dashboard.py: create a new dashboard withPOST /console/v1/dashboardsscripts/read_dashboard.py: fetch a dashboard and print a create-compatible shape by default usingGET /console/v1/dashboards/{id}scripts/add_dashboard_widgets.py: append widgets withPOST /console/v1/dashboards/{id}/widgetsscripts/replace_dashboard_widgets.py: replace all widgets withPUT /console/v1/dashboards/{id}/widgets
Workflow
- Choose the correct endpoint:
- create a dashboard:
create_dashboard.py - read a dashboard in create-compatible shape:
read_dashboard.py - append widgets:
add_dashboard_widgets.py - replace all widgets:
replace_dashboard_widgets.py
- create a dashboard:
- Build the matching request body for the chosen endpoint.
- Include only supported fields:
namedescriptiondefaultswidgets
- Map each requested widget to one of the supported widget types:
headertexttimeseries- each widget may include optional
widthandheight
- For
timeseries, enforce the query contract exactly:- include exactly one of
sourceorsources - use
type: "event"for each source - include
aggregation - only use supported filter operators and chart types
- if the user wants to group by or filter by event value, use
!statsig_valuerather thanvalue
- include exactly one of
- Execute the matching script.
- Return the API response, or summarize the created dashboard ID or widget IDs if that is all the user needs.
Service Filters
When a widget needs to scope to a Statsig service, prefer filtering on:
{
"property": {
"key": "custom.service",
"column": "user_object"
},
"operator": "EQ",
"values": ["service-name"]
}
Do not default to bare service when building dashboard widgets. In Statsig event payloads this is commonly nested under user_object.custom, so custom.service is the safer default.
OTEL Aggregations
When a widget targets a metric that may come from OTEL, sample the metric first and inspect company_metadata.__metric_type.
- If
__metric_typeis present, treat the metric as OTEL-backed and prefer the matching OTEL aggregation family instead of the plain aggregation. - If
__metric_typeis absent on a representative sample, treat it as a non-OTEL metric and use the normal aggregation types.
Preferred mapping:
__metric_type = "gauge": useOTEL_GAUGE__AVG,OTEL_GAUGE__MAX,OTEL_GAUGE__MIN, orOTEL_GAUGE__SUM__metric_type = "counter": useOTEL_COUNTER__SUM,OTEL_COUNTER__AVG,OTEL_COUNTER__MIN, orOTEL_COUNTER__MAX__metric_type = "histogram": use the OTEL histogram aggregations documented inreferences/dashboard-api.md
Keep the aggregation intent the same when converting:
- average-style widgets should become
OTEL_GAUGE__AVGinstead ofAVG - max-style widgets should become
OTEL_GAUGE__MAXinstead ofMAX
Guardrails
- Do not invent unsupported widget types such as tables.
- Do not include layout fields when creating a dashboard. The create endpoint does not accept widget positions.
- Do not include
roworcolumn. The API currently supports widget sizing viawidthandheight, not explicit placement. - Do not include
idin the create request body. - If the user gives you a dashboard from
GET /console/v1/dashboards/{id}, reuse that create-compatible shape but removeid. - Do not use the create endpoint when the user wants to mutate an existing dashboard.
- Prefer markdown formatting in text widgets so the content is readable and structured.
Examples
Minimal dashboard:
cat > /tmp/dashboard.json <<'JSON'
{
"name": "Checkout Overview"
}
JSON
python3 scripts/create_dashboard.py \
--body-file /tmp/dashboard.json
Read an existing dashboard into a reusable create payload:
python3 scripts/read_dashboard.py \
--dashboard-id dash_123
Append widgets to an existing dashboard:
python3 scripts/add_dashboard_widgets.py \
--dashboard-id dash_123 \
--body-file /tmp/add-widgets.json
Replace all widgets on an existing dashboard:
python3 scripts/replace_dashboard_widgets.py \
--dashboard-id dash_123 \
--body-file /tmp/replace-widgets.json
Script Notes
- All scripts read
STATSIG_CONSOLE_API_KEYfrom the environment. - All scripts default
STATSIG_API_VERSIONto20240601. - Pass
--api-versionor setSTATSIG_API_VERSIONto override that default. - All scripts default to
https://api.statsig.com/console/v1/dashboards. - All scripts send the Console API key in the
statsig-api-keyheader. - All scripts send the configured
statsig-api-versionheader. create_dashboard.py,add_dashboard_widgets.py, andreplace_dashboard_widgets.pyaccept:--body-file--body- stdin
read_dashboard.py,add_dashboard_widgets.py, andreplace_dashboard_widgets.pyrequire--dashboard-id.- All scripts support
--dry-run. - All scripts support
--raw. read_dashboard.pyprints the raw GET response only when--rawis set. Otherwise it unwrapsdataand removesid.
Work with this as data
Every skill here is available over the APIs.io API and to AI agents over MCP.