Sigma Workbooks (Spec via REST API)
This skill helps you build effective Sigma workbooks by navigating the Sigma OpenAPI and applying style guidance + proven recipes beyond what the OpenAPI alone teaches.
Scope
The workbook spec — the JSON you send as the contents field in POST /v2/workbooks (or PUT /v2/workbooks/{id}/contents), defining pages, elements, sources, formulas, and layout. Lifecycle around the workbook (embeds, grants, materialization schedules, bookmarks, sharing) is a separate API surface and out of scope here.
Sources of truth
Sigma's public API docs are an index at https://help.sigmacomputing.com/openapi.json that lists two canonical split specs (split from one large spec to fix compilation / out-of-memory errors — so the structure changed subtly). That index now serves an HTML page, not JSON (verified 2026-08-05) — it renders links to the two specs rather than returning a machine-readable list, so treat it as a human landing page and go straight to the two URLs below:
https://help.sigmacomputing.com/openapi/openapi/sigma-rest-api.json— the REST API: endpoint request/response shapes (workbooks, data models, members, connections, exports, materialization, …). Use for API calls.https://help.sigmacomputing.com/openapi/openapi/code-representation.json— the "code representation" (as-code) spec. Today it documents the data-model spec (/v2/dataModels/spec); use it for data-model element shapes.
Workbook element/control/format shapes (the bar-chart / kpi-chart / control / format kinds that go under a workbook's contents) are not inlined in either split spec — get them from one of, roughly in this order.
The split specs don't document the workbook content endpoints in any depth:
sigma-rest-api.jsondocumentsGET /v2/workbooks/{id},POST /v2/workbooks, andPUT /v2/workbooks/{id}/contentsonly at the bare resource-metadata level — thecontentsbody itself (element/control/format shapes) isn't inlined — andcode-representation.jsoncarries only the two/v2/dataModels/spec*paths. So for workbook authoring the split specs are not merely missing the inlined element shapes; thecontentsshape itself is absent. Use a per-endpoint reference page, the compiled asset, or a live readback (all below).
A live workbook readback —
GET /v2/workbooks/{id}?includeContents=trueon the user's org. Read literal elements from flatcontents.elements[]; pages, overlays, and panels are metadata and layout determines placement.A single endpoint's stable reference page —
https://help.sigmacomputing.com/reference/<endpoint-slug>. Use it to confirm one endpoint's current request/response envelope. Create accepts{name, folderId, description?, contents: {...}}; update (PUT .../contents) accepts exactly{contents: {...}, documentVersion?}.The full compiled OpenAPI — one document covering every workbook
kind, and the only source that documents the workbookcontentsshape at all. Use it for bulk discovery ("list every kind the API accepts") that no single per-endpoint page can do. This is the canonical, stable, unauthenticated URL — use it directly:https://assets.sigmacomputing.com/openapi/public-rest-api/sigma-computing-public-rest-api.json
Fetching the compiled asset
curl -sfL https://assets.sigmacomputing.com/openapi/public-rest-api/sigma-computing-public-rest-api.json \
-o /tmp/sigma-api.json
Plain GET, no auth, no signature, no content hash — safe to hardcode. Title "Sigma Computing Public REST API", version: 2.0.0, ~6.8 MB (it uses $refs into components.schemas, so deref as you walk — element kinds are behind #/components/schemas/WorkbookElement).
Do not use the old Fern docs asset (
fdr-prod-docs-files-public.s3.amazonaws.com/sigma.docs.buildwithfern.com/<hash>/…). It is content-addressed, now requires AWS presigned query params (a bare fetch 403s), and — the reason that actually matters — it lags the live API. As of 2026-08-05 it was missing report content support entirely, still documented the pre-contents-wrapper request body, and did not contain therepeated-containerelement kind, which caused this skill to previously assert that repeated containers were not spec-authorable. They are. Working from a stale asset produces confidently wrong documentation; prefer theassets.sigmacomputing.comURL above, and treat a live workbook readback as the tiebreaker.
The old help.sigmacomputing.com/openapi.json index is now an HTML landing page and does not link the compiled asset at all.
When this skill and the spec (or a live readback) disagree, the spec wins. When a feature isn't covered here, consult the spec / a live workbook and use what it documents.
Consulting the shapes (per-endpoint pages, compiled OpenAPI, or a live readback)
The field lists and examples in this skill are illustrative, not exhaustive — when you need the complete, current shape of anything, pick the right tool for the question:
- One endpoint, one doubt (does this field still exist, is the body wrapped or flat, what's required) — go straight to that endpoint's stable reference page,
https://help.sigmacomputing.com/reference/<endpoint-slug>(see Sources of truth). No caching, nojq, just read the page. - Every
kindthe API accepts, or every field on akind(bulk discovery — e.g. building outreference/specification/*.md) — the per-endpoint pages don't help here (one endpoint each); use the compiled OpenAPI or a live workbook readback instead. Fetch the compiled spec once per session and inspect withjq:
# Assumes /tmp/sigma-api.json from "Fetching the compiled asset" above.
# If a field looks wrong, check that field's per-endpoint page, or read a live workbook spec
# (GET /v2/workbooks/{id}?includeContents=true) and navigate contents.elements[] by kind.
# The workbook create request body. NOTE: the outer object is {name, folderId, description?, contents},
# so elements/pages/overlays/panels/layout/settings/agents are under .contents:
jq '.paths."/v2/workbooks".post.requestBody.content."application/json".schema' /tmp/sigma-api.json
Element, source, control, and format shapes are identified by their kind value (e.g. bar-chart, kpi-chart, join, warehouse-table) rather than by a top-level schema name. They live in components.schemas and are reached by $ref (element kinds hang off #/components/schemas/WorkbookElement) — so deref as you walk if you're writing your own traversal. The jq recipes below scan the whole document, so they work regardless:
# List every kind the spec accepts (elements, sources, controls, formats, …):
jq -r '[.. | objects | select(.properties.kind.enum) | .properties.kind.enum[0]] | unique[]' /tmp/sigma-api.json
# Full field list (required + optional) for one kind — swap bar-chart for any kind above:
jq --arg k bar-chart 'first(.. | objects | select((.allOf? and any(.allOf[]?; .properties?.kind?.enum==[$k])) or .properties?.kind?.enum==[$k]))
| {required: ([.allOf[]?.required // .required] | add | unique), properties: ([(.allOf[]?.properties // .properties) | keys[]] | unique)}' /tmp/sigma-api.json
# The full nested shape for that kind (to inspect sub-objects like source, yAxis, format, comparison):
jq --arg k bar-chart 'first(.. | objects | select((.allOf? and any(.allOf[]?; .properties?.kind?.enum==[$k])) or .properties?.kind?.enum==[$k]))' /tmp/sigma-api.json
WebFetch works for the JSON too. Either path is fine.
No curl/jq on the machine (e.g. Windows without WSL)? scripts/wb-rep.rb
ships a capabilities subcommand that does the same three queries with
pure-Ruby Net::HTTP + JSON.parse — no external tools required:
ruby scripts/wb-rep.rb capabilities # list every kind
ruby scripts/wb-rep.rb capabilities --kind bar-chart # field list for one kind
ruby scripts/wb-rep.rb capabilities --kind bar-chart --field source # one field's shape
Why bother: the API ships new fields and viz configurations regularly, and this skill covers the common surface, not every field. If you want a capability and don't see it documented here, assume it may exist and check the spec before concluding it doesn't — the kind query above answers in seconds.
Auth
Authenticate via the sigma-api skill first to populate $SIGMA_BASE_URL and $SIGMA_API_TOKEN. Two options there: client credentials (SIGMA_CLIENT_ID/SIGMA_CLIENT_SECRET, best for headless/automation) or interactive browser login (sigma-api/scripts/browser-login.sh → refresh headlessly with refresh-token.sh, no client ID/secret). Either yields a $SIGMA_API_TOKEN; the rest of this skill is identical.
Recommended Workflow
These are guidelines, not mandates — but they prevent the failure modes that show up most often when drafting from scratch.
Schema drift signal: an error about request shape (
invalid argument,unknown field,missing required field,unexpected property) usually means this skill is stale on that detail. Fetch the OpenAPI and compare; the canonical shape is there.
Step 0 — Authenticate, capture user identity
USER_ID=$(curl -s -H "Authorization: Bearer $SIGMA_API_TOKEN" \
"$SIGMA_BASE_URL/v2/whoami" | jq -r '.userId')
HOME_FOLDER_ID=$(curl -s -H "Authorization: Bearer $SIGMA_API_TOKEN" \
"$SIGMA_BASE_URL/v2/members/$USER_ID" | jq -r '.homeFolderId')
If the user provided a target image or design artifact (a screenshot,
mockup, PDF, or Claude-generated app design they want reproduced), pause here
and load reference/workflows/from-image.md — it adds mandatory whole-screen
inventory, behavior classification, design-manifest, native-first routing,
render-diff, and iteration gates that happen before and alongside normal data
discovery. The standard workflow alone tends to reproduce the data visuals
while missing the app shell and behavior.
If the user asked to generate / build / scaffold a Sigma app (planning,
approval, allocation, exception, or an unspecified “app”) and did not
supply a target image, pause here and load
reference/workflows/generate-apps.md — it classifies the app type,
interviews before it builds (which fields users may edit, whether the
workflow needs approvals, whether to add a Sigma Agent and what it is
for), records an intake manifest, states a build plan, and clones a
best-practice architecture fixture.
Design is a separate pass: load styling.md as a library and compose for
this type (do not stamp the five-recipe dashboard or the navy-hero
command-center example). A
target image still wins: load from-image.md instead.
Step 1 — Find a reference workbook to study
Any existing workbook on the user's org doubles as a template. List and pick one with similar content:
curl -s -H "Authorization: Bearer $SIGMA_API_TOKEN" \
"$SIGMA_BASE_URL/v2/workbooks?limit=50" | jq '.entries[] | {workbookId, name}'
If no relevant workbook exists, pick any — the goal is studying spec structure, not matching content. If the org has no workbooks at all, draft from scratch using the OpenAPI shapes + this skill's recipes.
Step 2 — Study the reference spec
YAML is the canonical format for workbook specs in this skill — easier to read, diff, and review than JSON. Sigma's API accepts both (Content-Type: application/yaml or application/json); Accept: application/yaml is the default on GET /v2/workbooks/<id>?includeContents=true. Use yq to inspect spec YAML the same way you'd use jq on JSON.
curl -s -H "Authorization: Bearer $SIGMA_API_TOKEN" \
"$SIGMA_BASE_URL/v2/workbooks/<reference-workbook-id>?includeContents=true" \
> /tmp/reference-spec.yaml
Look at source structure, column IDs, formulas, flat contents.elements, page
metadata, and layout XML. Do not copy an obsolete pages[].elements shape.
Step 3 — Discover data sources
Load reference/workflows/discover.md. Quick summary:
GET /v2/connections— find the user's connection by name or type.- Ask the user for the table path; verify with
POST /v2/connection/<id>/lookup. - Discover columns directly via
GET /v2/connections/tables/{inodeId}/columns(full mechanics inreference/workflows/discover.md). Only fall back to asking the user when the endpoint doesn't return what's needed.
Never invent column names — only use names returned by the API or supplied by the user.
Verify literal values before writing predicates. If your task involves filtering on a categorical column (e.g., CountIf([Status] = "active"), If([Type] = "sale", ...)), you need to know what values that column actually contains — the /v2/connections/tables/{inodeId}/columns endpoint gives you names and types but not values. Run a SELECT DISTINCT <col> via any tool that reaches the warehouse — an MCP server (warehouse or Sigma), a SQL CLI, or just ask the user. Don't guess literals. See reference/workflows/discover.md.
Verify the composed source grain before drafting. Name the expected grain
key (or composite key), then prove that the source as the workbook will read it
has one row per key. For a single key, assert
COUNT(*) = COUNT(DISTINCT <grain-key>); for a composite key, group by all key
columns and require zero duplicate groups. For a 1:1 or many:1 join intended to
preserve the left grain, compare row count and distinct left-grain count before
and after the join and require both to stay unchanged. Inner joins and
intentional 1:many joins need a written expected shrink/expansion instead.
Do not draft plausible-looking counts over an unproven fanout. See
reference/workflows/discover.md.
Step 4 — Identify features and load only what you need
Map the user's request to the Reference Index below. State the features you identified, then read the listed reference files before drafting. If the user asks for a feature this skill doesn't cover, fetch the OpenAPI and inspect the relevant schema.
When choosing a visualization, use the data-shape selector at the top of
reference/specification/charts.md before copying a chart recipe. A ranked
categorical comparison defaults to a horizontal bar, not a sorted table used
as the primary visualization.
If the user asked to generate an app, run generate-apps.md first (Step 0)
before choosing an input-table architecture here. That interview already
recorded which fields users may edit, whether the workflow needs
approvals, and whether to include a workbook agent. Load
reference/specification/styling.md as a library and compose for this
app's job — do not stamp the five-pattern exec-dashboard stack or the
navy-hero command-center example.
If the request includes an input table, writeback, “populate,” “seed,” planning,
approval, allocation, or exception workflow, load
reference/specification/input-tables.md before choosing an architecture.
Creating an input-table element, loading initial rows, composing a downstream
read path, and submitting a runtime action are four different operations. Do
not substitute actions, unions, or joins for one another when the first
approach leaves the table empty.
Step 5 — Draft the spec to a local file
Write the spec YAML to disk (e.g., /tmp/workbook-spec.yaml). YAML is preferred over JSON in this skill — easier to read, diff, and comment for human review. The API accepts either; pick YAML unless something downstream specifically needs JSON. Key rules:
- Every element needs a unique
idand a descriptivename. - Every column needs a unique
id, aname, and aformula. - Follow the formula reference rules in
reference/specification/formulas.mdexactly — most spec errors happen here. - Write explicit
contents.layoutXML whenever elements are non-empty. It is the source of truth for page/container/tab organization. - Emit
<Element>for layout leaves and<Container>for nested grids, including repeated-container elements.<TabbedContainer>/<Tab>remain valid. Never emit the legacy<LayoutElement>/<GridContainer>aliases; live verification rejects<LayoutElement>(valid:false; some API versions returned HTTP 400 instead). - Start with 1–2 pages. Add more later via update.
For create, include outer name/folderId and contents with required
schemaVersion, kind: workbook, flat elements, and metadata-only pages.
Optional contents fields include overlays, panels, settings, and agents.
This skill requires layout whenever elements is non-empty. See
reference/specification/schema.md.
Step 6 — Validate the spec
Run the bundled validator first — do not skip.
./scripts/validate-spec.sh /tmp/workbook-spec.yaml
Then do the manual formula pass and final shape checks per reference/workflows/validate.md. Fix everything reported before continuing.
Step 7 — Create the workbook
curl -s -X POST -H "Authorization: Bearer $SIGMA_API_TOKEN" \
-H "Content-Type: application/yaml" \
-H "Accept: application/yaml" \
--data-binary @/tmp/workbook-spec.yaml \
"$SIGMA_BASE_URL/v2/workbooks" > /tmp/create-response.yaml
WORKBOOK_ID=$(yq -r '.workbookId' /tmp/create-response.yaml)
cp /tmp/workbook-spec.yaml "/tmp/workbook-spec-${WORKBOOK_ID}.yaml"
Persist the spec after a successful create so subsequent PUT updates can start from it. Report both the workbook URL and the saved spec path.
If creation fails, read the error, fix the spec, re-validate, retry. See reference/workflows/validate.md for decoding cryptic errors.
Step 7b — Verify the workbook actually compiles
Do not skip. A successful POST is necessary but not sufficient — Sigma accepts specs whose formulas don't resolve, then surfaces the failures at query time by embedding the error as a string literal in the compiled SQL ('Unknown column "[X]"', 'Circular column reference to [Y]'). Affected elements render empty in the UI. Only Sigma's compiler knows whether your formula references actually resolve.
./scripts/verify-workbook.sh "$WORKBOOK_ID"
If any element reports [FAIL], fix the column formulas in the spec (most often a missing source prefix, a self-referencing column, or a friendly-name mismatch with the warehouse — see reference/specification/formulas.md), PUT the corrected spec, and re-verify.
Step 8 — Iterate
After initial creation, use PUT /v2/workbooks/<id>/contents to add pages or refine the workbook.
For anything beyond ~1 page / ~10 elements, switch to the element rep (reference/workflows/element-rep.md): scripts/wb-rep.rb pull <id> <dir> explodes the spec into one file per element so each edit touches a ~½KB file instead of the whole spec, push handles drift-check + validation + PUT, and render exports page PNGs you can actually look at. The raw GET/PUT flow below remains fine for small workbooks and one-off tweaks.
IDs are preserved on CREATE. The
idvalues you POST (pages, elements, columns) are kept verbatim, andlayoutelementIdreferences stay valid — so you can edit your saved spec andPUTit back, re-wrapped as just{contents: {...}}(see below — PUT does not take the outername/folderId).GETthe current spec first only if you don't have your latest copy. Seereference/workflows/crud.md.
PUT /v2/workbooks/<id>/contentsis contents-only. Sendingname,folderId, ordescriptionalongsidecontentsis silently ignored — usePUT /v2/files/{fileId}to rename or move a workbook.
curl -s -H "Authorization: Bearer $SIGMA_API_TOKEN" \
"$SIGMA_BASE_URL/v2/workbooks/<workbook-id>?includeContents=true" \
> /tmp/current-spec.yaml
# Edit /tmp/current-spec.yaml inside .contents; preserve elements, pages,
# overlays, panels, layout, settings, and agents.
# then PUT only the contents object — see reference/workflows/crud.md for why
# sending the outer name/folderId/response-only fields alongside it is ignored:
yq '{"contents": .contents}' /tmp/current-spec.yaml > /tmp/current-spec-put.yaml
curl -s -X PUT -H "Authorization: Bearer $SIGMA_API_TOKEN" \
-H "Content-Type: application/yaml" \
-H "Accept: application/yaml" \
--data-binary @/tmp/current-spec-put.yaml \
"$SIGMA_BASE_URL/v2/workbooks/<workbook-id>/contents" | yq .
cp /tmp/current-spec.yaml "/tmp/workbook-spec-<workbook-id>.yaml"
./scripts/verify-workbook.sh "<workbook-id>"
Step 9 — Report back
Report the workbook URL and the saved spec path. Do not tack on generic "improvement ideas" or "next steps." Match the response to what was asked.
Surface follow-up items only when they're load-bearing, and name them concretely:
- Tradeoffs you made during the build — dropped a chart, simplified a formula, skipped a control because the shape wasn't in your reference.
- Obvious gaps revealed by the column list — e.g., the user asked for "sales by region" and the table has a
region_tiercolumn that would make the breakdown richer. One sentence, named.
If none apply, just report the URL + spec path and stop.
Reference Index
The reference is feature-sliced — don't read every file up-front. The index has three sections: elements (the visual / interactive pieces), sources (where each element gets its data), and cross-cutting (formulas, layout, formatting, validation, CRUD).
Elements
| File | When to load |
|---|---|
reference/specification/tables.md |
Table element, tabular data, data grid, spreadsheet-style list. Also element-level filters (list, top-n, number-range, date-range, text-match, hierarchy), groupings (pivot, group by), the pivot-table and editable input-table element kinds, and conditionalFormats (threshold-based cell coloring, on pivot/input tables). |
reference/specification/charts.md |
Load before choosing a visualization. Data-shape → chart selection, then chart/graph recipes for line / bar / column / stacked / grouped / combo / donut / pie / scatter / waterfall / share-of / breakdown. Cartesian axes, color, trellis, legend, trendlines, reference marks. |
reference/specification/maps.md |
Map visualizations — geography-map (GeoJSON shapes), point-map (lat/long bubbles), region-map (states / counties / countries). |
reference/specification/kpis.md |
KPI, stat, big number, single value, metric card — including layout / value styling, the comparison Δ badge (comparisonColumn + comparison:{display:"delta"} — spec-authorable and readback-stable; the house default), and the trend/sparkline block (still UI-bound). |
reference/specification/controls.md |
Filter, dropdown, picker, multi-select, date range, date picker, text filter, number range, slider, segmented, hierarchy, legend, and drill controls. Also entry controls and formula handles. |
reference/specification/content-elements.md |
The non-data elements — text (Markdown + inline styling), image, divider, embed (external URLs), page-break (PDF/print pagination), form, progress, navigation, plugin. Titles, callouts, logos, rules, embedded content. |
reference/specification/input-tables.md |
Load for every input-table or “populate/seed” request. Operational supplement for input-table: supported row-arrival decision tree, write connection, UI-only published permission, publish gate, linked-key correlation, warehouse views, and why actions/unions/joins are not bulk seeding mechanisms. |
reference/specification/styling.md |
Load when composing a look from spec. A library of options (hero bands, KPI cards, gradients, section headers, chart color, formats) plus an anti-pattern checklist. Not a house style — do not stamp the five-pattern exec dashboard onto every app. PNG fail: skill chrome, invisible entry controls, Dark-by-default on data-entry, 3-KPI status on operational apps. |
reference/specification/agents.md |
Workbook AI agent, chat with your data, agent, chatbot, AI assistant. The workbook-top-level agents:[] array + page-level chat element; Analyze / Configure / Navigate / Act capability profiles; direct control/navigation/write action tools; read-only analyst vs. operator; the four tools[] kinds (action, mcp-connector, warehouse-agent, search-service), greeting, requiresApproval, why action sequences are referenceable but not authorable; org-feature gate + graceful degrade. |
Sources
| File | When to load |
|---|---|
reference/specification/sources-warehouse.md |
Always — load before drafting any spec. Warehouse-table source (Snowflake, BigQuery, Databricks, Redshift, Postgres/MySQL). |
reference/specification/sources.md |
Reference another chart/table/element, derive from existing element, join, combine tables, data model / semantic-layer source, custom SQL, union, transpose, unpivot. |
Cross-cutting
| File | When to load |
|---|---|
reference/specification/schema.md |
Always — wrapped shape, required flat contents.elements, metadata-only pages, overlays, panels, settings, backgrounds, and the PUT-only-contents rule. |
reference/specification/formulas.md |
Always — load before drafting any spec. Formula syntax, qualification, special characters, the #1 mistake. |
reference/specification/formatting.md |
Format, currency, percentage, date format, decimals — column formatting. |
reference/specification/layout.md |
Always load. Required layout policy; page/container organization; backgrounds/spacing; panels, headers, sidebars, navigation; repeated and tabbed containers. |
reference/specification/example-full.yaml |
A real multi-page reference spec (KPIs, charts, joins, controls, layout) — copy shapes from when in doubt. |
reference/specification/comparative-kpi-card.yaml |
Minimal clone-able comparative KPI card — value + comparisonColumn + comparison:{display:"delta"}, the house-default comparative shape (see kpis.md). |
reference/specification/trellis-chart-support.md |
The empirical coverage matrix for trellis charts — how each kind was verified live (POST + readback + render). Load when charts.md's trellis guidance needs the underlying evidence. |
Workflows
| File | When to load |
|---|---|
reference/workflows/discover.md |
Finding connections, tables, and column names. Load before composing a new spec. |
reference/workflows/composition.md |
Open-ended design decisions, named asymmetric splits/mosaic, and the content-prescriptive ledger record-lookup archetype. Covers when to ask, chart-vs-table defaults, editorial sizing, and hidden source pages. Load before drafting when the prompt leaves design choices unmade or asks users to find/browse records. |
reference/workflows/app-compositions.md |
Operational app visual composition. Load with generate-apps.md: keeps semantic architecture separate from appearance, selects workbench / queue-rail / builder-preview, requires a local design manifest, emits asymmetric work-surface-first layout via Composition.compose, and adds a two-render PNG polish gate. |
reference/workflows/actions.md |
Buttons, write-back, and all twelve action effects — insert/update/delete-rows, clear-control, set-control-value, open/close-overlay (modal and drawer), open-url, open-document (incl. passing targetControls into another workbook), navigate, select-tab, refresh-element — plus the append-only-log pattern and the masked-error catalog. Load when the user wants a button, a "log/save/submit" action, tab/page navigation, a deep link, or a write-back workflow. |
reference/workflows/generate-apps.md |
Generate a Sigma app. Load first when the user asks to build a planning, approval, allocation, or exception app (and did not supply a target image). Classifies the type, interviews for editable fields / approvals / an Analyze–Configure–Navigate–Act workbook-agent contract, clones an architecture fixture (planning is a multi-page studio shell), then composes an app shell + workbench / queue-rail / builder-preview look. Fail the PNG pass on skill chrome, invisible entry controls, Dark-by-default on data-entry, a 3-KPI status strip, an empty work surface, or Unknown column / Invalid Query on a page measure. |
reference/workflows/fixtures/README.md |
Rules for cloning an operational-app architecture fixture (placeholders only — never commit real org/user/folder/workbook IDs). Load alongside generate-apps.md, not standalone. |
reference/workflows/fixtures/planning-app.yaml |
Starting spec for a planning app. Clone via generate-apps.md; don't read standalone. |
reference/workflows/fixtures/allocation-app.yaml |
Starting spec for an allocation app. Clone via generate-apps.md; don't read standalone. |
reference/workflows/fixtures/approval-app.yaml |
Starting spec for an approval app. Clone via generate-apps.md; don't read standalone. |
reference/workflows/fixtures/exception-app.yaml |
Starting spec for an exception app. Clone via generate-apps.md; don't read standalone. |
reference/workflows/planning-apps.md |
Scenario planning, budgeting, and forecasting apps. Scenario × Period × Planning Line grain, governed baseline, scenario matrix, linked override grid, financial sign, filter-propagation choices, approval/audit, and runtime gates. |
reference/workflows/allocation-apps.md |
Allocation and capacity apps. Budget/target vs. baseline at Period × Allocation Dimension grain, linked editable units/uplifts, working allocation, request queue, and exact variance gates. |
reference/workflows/approval-apps.md |
Approval and decision apps. Stable entity-key queues, counter-values, immutable audit logs, one-row status updates, agent boundaries, and runtime tests. |
reference/workflows/exception-apps.md |
Exception command centers. Stable operational-key queues, deterministic recommendations, overrides, ownership, resolution logs, and exact KPI-delta tests. |
reference/workflows/crud.md |
POST / GET / PUT against the workbook content endpoints. Load when creating, retrieving, or updating a workbook. |
reference/workflows/validate.md |
Pre-submit + post-create structural validation. Load before any POST or PUT; for joins, controls, writeback, agents, or numeric claims continue to runtime-verification.md. |
reference/workflows/runtime-verification.md |
Runtime evidence loop: compile, render, export, cardinality, numeric oracle, published writeback, linked-row correlation, control scope, approval scope, and agent tests. |
reference/workflows/from-image.md |
The user supplied a target image or Claude design artifact to reproduce. Load before discovery — it inventories the entire app shell and behavior, routes native Sigma vs plugin/UI-only surfaces, requires a local design manifest, and enforces first-render → diff → final-render acceptance. |
reference/workflows/element-rep.md |
Large or multi-page workbooks, parallel element work, or iterative refinement. scripts/wb-rep.rb explodes the spec into one small file per element (pull/status/push/render) so edits never drag the whole spec through context — element-level semantics over the whole-spec API, plus PNG renders to inspect what you built. |
reference/workflows/element-rep-companion.md |
Design rationale for the element rep (why per-element files instead of a middleware layer). Background reading — not required to use element-rep.md. |
Quick Formula Rules
The single most common spec error is bare [column_name] references to warehouse columns. Full rules in reference/specification/formulas.md. Skeleton:
Outside the element — use [SourceName/column_name]:
- Warehouse-table source:
SourceName= last segment of thepatharray (e.g.,[ORDERS/Revenue]) - Another element:
SourceName= that element'sname - Join legs: prefix by the leg's
name, or by the join's top-levelnameforprimarySourcecolumns
Inside the same element — use [column_name] (no prefix):
- References a column defined in this element by its
namefield. - A column cannot reference itself (circular reference error).
Data-model metrics — use [Metrics/<metric name>]:
Metricsis a reserved namespace; use the metric'sname, not its ID.[<element name>/<metric>]is a column reference and can fail withDependency not foundeven though the metric exists.- Confirm the metric survives the data-model GET readback before binding it.
Troubleshooting
"I don't see this field in the skill"
Fetch the OpenAPI. The skill documents stable, common surface area; the API has more. See Consulting the shapes above.
API schema mismatch (skill is stale)
A 400 about request shape — invalid argument, unknown field, unexpected property, missing required field — usually means the API moved past the skill. Fetch the OpenAPI (see Consulting the shapes), diff the live shape for that kind, and retry once with the correction. Tell the user it looks like the skill is out of date and worth updating through whatever channel they installed it from; don't loop on retries.
401 Unauthorized
Sigma OAuth tokens expire after ~1 hour. Long workbook-building sessions (orchestrated batch conversions, multi-step iterations, anything that runs >50 minutes) will hit this mid-flight.
Ruby callers (scripts/wb-rep.rb, or anything using scripts/lib/code_rep.rb): there's no automatic refresh-and-retry wrapper in this skill — wb-rep.rb's api() helper dies loudly on any non-2xx, including 401. Re-export SIGMA_API_TOKEN (eval "$(scripts/get-token.sh)") and re-run the command.
Bash / curl callers: re-run eval "$(scripts/get-token.sh)" to refresh manually. For long shell loops, wrap the curl in a small helper that retries once on 401:
sigma_curl() {
local resp code
resp=$(curl -sS -w '\n%{http_code}' -H "Authorization: Bearer $SIGMA_API_TOKEN" "$@")
code=$(echo "$resp" | tail -1)
if [ "$code" = "401" ]; then
eval "$(scripts/get-token.sh)"
resp=$(curl -sS -w '\n%{http_code}' -H "Authorization: Bearer $SIGMA_API_TOKEN" "$@")
fi
echo "$resp" | sed '$d' # strip trailing status code
}
If 401 persists after refresh, re-authenticate via sigma-api: for client credentials verify SIGMA_BASE_URL, SIGMA_CLIENT_ID, SIGMA_CLIENT_SECRET; for browser login re-run sigma-api/scripts/refresh-token.sh (or browser-login.sh if the refresh token has expired).
403 Forbidden on workbook create
The credentials authenticated but aren't permitted to create workbooks here. Ask the user's Sigma admin to confirm the credential's permissions and folder access.
"Invalid column reference" or formula errors on creation
The most common spec issue. A bare [column_name] was used where [TABLE/column_name] is needed. See reference/specification/formulas.md for the full rules and reference/workflows/validate.md for the manual checklist.
"Unknown column" errors
The column name in the formula doesn't match what the warehouse actually has. Re-confirm the column names via GET /v2/connections/tables/{inodeId}/columns (raw warehouse names) and the readback (GET /v2/workbooks/<id>?includeContents=true, which may preserve the raw spelling or show Sigma's canonicalized friendly form). Raw names are accepted authoring input; use the returned readback form for later edits.
jq or yq not installed
jq is used for OpenAPI inspection (the OpenAPI is JSON). yq is used for workbook-spec inspection (specs are YAML).
jq:brew install jq(macOS) orapt install jq(Debian/Ubuntu).yq: two different tools share this name — the Go mikefarah/yq (brew install yq) and the Pythonpip install yqwrapper around jq. Reading works the same in both (yq -r '.workbookId' f.yaml), but in-place editing differs: mikefarah usesyq -i '…' f.yaml, while the Python wrapper needsyq -y -i '…' f.yaml. Runyq --helpto see which you have and adapt.
Cryptic validation errors / silent bad data
See reference/workflows/validate.md for contents.elements[N] and layout error triage.