# Sigma Reports

> Build, validate, retrieve, and safely update Sigma report code representations through /v2/reports/spec. Use for fixed-layout or pixel-perfect reports, executive board packets, wide operational tables, invoices, statements, regulatory documents, and PDF delivery. Covers reusable report scaffolds, report pages, absolute pixel layout, header/footer panels, common elements, verification, full-document replacement, and workbook conversion to reports. Do not use for responsive dashboards; use sigma-workbooks instead. Requires SIGMA_API_TOKEN from the sigma-api skill.

- Skill: `twells89/sigma-reports` (Agent Skill, multi-file: 26 files)
- Install (CLI): `npx skillmds@latest add twells89/sigma-reports`
- Raw SKILL.md: https://api.skillmd.com/api/skills/twells89/sigma-reports/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: twells89 (https://skillmd.com/u/twells89)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/twells89/sigma-reports

---


# Sigma Reports (Code Representation via REST API)

Use this skill for Sigma **reports**, the fixed-page authoring surface exposed
by `/v2/reports/spec`. Reports are a private-beta resource. They share common
element shapes with workbooks but have a different resource lifecycle and a
different layout language.

## Choose the correct resource

Use a report for invoices, statements, regulatory packets, printable forms,
branded documents, and other outputs whose physical page size matters. Use
`sigma-workbooks` for responsive dashboards, exploratory analysis, application
workflows, containers, tabs, modals, drawers, or workbook navigation.

Never create a report by sending `kind: report` to a workbook endpoint. The
resource families are separate:

- Reports: `/v2/reports/spec`, `/v2/reports/{reportId}/spec`
- Workbooks: `/v2/workbooks/spec`, `/v2/workbooks/{workbookId}/spec`
- Conversion: `/v2/workbooks/{workbookId}/convertToReport`

## Source of truth

Use the current compiled OpenAPI for endpoint envelopes and published shapes:

```
https://assets.sigmacomputing.com/openapi/public-rest-api/sigma-computing-public-rest-api.json
```

The report endpoints currently declare `application/json` only. Author JSON
unless a live request proves another media type works. The schema is broader
than the documented report contract, so a published element kind is not proof
that reports can safely author it. Read
`reference/specification/support-matrix.md` before selecting elements.

Live baseline, verified 2026-08-11: a JSON report with a warehouse-table
source, text, KPI, combo-chart, bar-chart, grouped presentation table, data
bars, a hidden dependency page, and header/footer panels passed `/verify`,
created successfully, survived GET readback, updated as a new document version,
and exported as a one-page landscape PDF with populated data. The support
matrix records which findings this proves and which schema-published features
remain gated.

Expanded baseline, verified from a populated five-page PDF on 2026-09-19:
custom-SQL sources on a hidden data page, comparative KPI scorecards, inline
SVG hero/band images, themed multi-page output, conditional tables, and a
column-backed `waterfall-chart` all rendered successfully. This evidence
supersedes the earlier policy that rejected waterfall charts and treated
report settings as unproven.

Shared-shape refresh, verified 2026-09-15 against the compiled OpenAPI and
non-persistent report `/verify`: common element pointers now use
`{columnId: ...}`, pivot shelves use `{columnId: ...}`, and
`seriesLineAreaStyle` is a list of `{columnId, style}` objects. Text/KPI
alignment uses directional values (`left`/`center`/`right` and
`top`/`center`/`bottom`), not `start`/`middle`/`end`. The old pointer, map, and
alignment forms returned HTTP 400 while the replacement forms verified
`valid:true`. Report PUT also publishes optional `documentVersion` for
optimistic concurrency.

When documentation, this skill, and a live verify/readback disagree, prefer
the live result and preserve the evidence. Run the bundled OpenAPI contract
test against a fresh download when the API reports a shape error:

```bash
curl -sfL \
  https://assets.sigmacomputing.com/openapi/public-rest-api/sigma-computing-public-rest-api.json \
  -o /tmp/sigma-openapi.json
ruby scripts/test-openapi-contract.rb /tmp/sigma-openapi.json
```

## Prerequisites and safety

1. Authenticate with the `sigma-api` skill. Set `SIGMA_BASE_URL` and
   `SIGMA_API_TOKEN`.
2. Confirm reports are enabled for the organization and the caller has
   **Create, edit, and publish reports** permission. Updating also requires
   **Can edit** access to the report.
3. Treat every create as persistent. The current OpenAPI exposes no report
   DELETE endpoint. Do not create a probe report without explicit user
   approval and a named destination folder.
4. Treat PUT as full-document replacement. Always GET, back up, compare, edit,
   validate, verify, PUT with the retrieved `documentVersion`, and read back.
5. A report GET can omit unsupported UI-authored features. Never assume a GET
   representation is lossless merely because the request succeeded.

## Recommended workflow

### Step 1: Discover identity and folder; use references only when needed

```bash
curl -sf -H "Authorization: Bearer $SIGMA_API_TOKEN" \
  "$SIGMA_BASE_URL/v2/whoami" > /tmp/whoami.json
```

Do not browse arbitrary reports. If the OpenAPI, scaffolds, and references do
not answer a specific shape question, list reports once, choose one relevant
reference, cache its spec, and use it only for that question. Obtain the
current `schemaVersion` from a relevant report GET or a user-provided target;
do not hardcode the value shown in examples.

Load `reference/workflows/discover.md` and resolve the report's source,
columns, grain, period rules, and page-slice counts before drafting.

### Step 2: Classify and scaffold the report

Load `reference/workflows/generate.md`. Classify the request as an executive/
board report, wide operational table, or statement. Generate a complete local
starting point instead of drafting raw JSON from nothing:

```bash
ruby scripts/scaffold-report.rb \
  --template board \
  --name "Quarterly Business Review" \
  --folder-id "<folder-id>" \
  --connection-id "<connection-id>" \
  --company "ACME" \
  --output /tmp/report-spec.json
```

Use `--template wide-table` for multi-page tabloid-landscape tables. Replace
the synthetic SQL/data labels while retaining the proven geometry, panels,
hidden data page, and explicit column contracts.

### Step 3: Load the relevant references

Always read:

- `reference/specification/schema.md`
- `reference/specification/layout.md`
- `reference/specification/support-matrix.md`
- `reference/workflows/discover.md`
- `reference/workflows/validate.md`

Also read `reference/workflows/crud.md` before an API write and
`reference/workflows/convert.md` before converting a workbook.

Common element internals, source formulas, and column shapes are published in
the same OpenAPI union used by workbooks. If `sigma-workbooks` is installed,
its table, chart, map, KPI, control, source, formula, and formatting references
are useful shape recipes. Apply only kinds allowed by the report support
matrix, and never copy workbook grid layout or workbook-only elements.

For shared shapes changed by the released code contract:

- use `columnId`, never `id`, in map channels and pivot
  `rowsBy`/`columnsBy` shelf entries;
- emit `seriesLineAreaStyle` and theme `colorOverrides` as lists, not
  ID/name-keyed maps;
- use `verticalAlign: top|center|bottom`;
- use KPI `layout.anchor: left|center|right` and
  `layout.verticalAnchor: top|center|bottom`;
- wrap page background URLs as
  `backgroundImage: {source: {kind: url, url: ...}, style: ...}`;
- use `settings.theme.{name,overrides}`, not the removed document-level
  `themeName`/`themeOverrides`.

### Step 4: Draft the wrapped JSON representation

Start with `reference/specification/example-minimal.json`. The create and
verify envelope is:

```json
{
  "name": "Monthly Statement",
  "folderId": "<folder-id>",
  "document": {
    "schemaVersion": 1,
    "kind": "report",
    "config": {"pageWidth": 816, "pageHeight": 1056, "margin": 48},
    "elements": [],
    "pages": [{"id": "page-1", "name": "Page 1"}],
    "layout": "<Page id=\"page-1\"></Page>"
  }
}
```

Rules:

- Keep literal elements in flat `document.elements`.
- Keep pages and panels as metadata; never nest `elements` inside them.
- Put all placement in `document.layout` XML.
- Place leaves with absolute `x`, `y`, `width`, and `height` pixel values.
- Use report panels only for `header` and `footer` regions.
- Do not emit workbook `gridColumn`, `gridRow`, container, tab, overlay, or
  sidebar syntax.
- Compute horizontal positions from widths + gaps and vertical positions from
  a y-cursor. Never rely on unrelated magic-number offsets.
- Put reusable SQL/data-model sources on a hidden data page and declare every
  custom-SQL alias through `[Custom SQL/<alias>]`.
- For wide multi-page output, clone the visible table per page and filter each
  clone with an explicit page-slice key; do not rely on one tall table flowing
  without inspection.

### Step 5: Validate locally

```bash
ruby scripts/validate-spec.rb --mode create /tmp/report-spec.json
```

Fix every error. The validator catches pointer casing/targets, grouped-table
mistakes, SQL contracts, overlaps, geometry, and representation shape.
Warnings identify schema-only/unknown capabilities or visible detail columns
that need a deliberate decision.

### Step 6: Verify without persistence

```bash
curl -sf -X POST \
  -H "Authorization: Bearer $SIGMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  --data-binary @/tmp/report-spec.json \
  "$SIGMA_BASE_URL/v2/reports/spec/verify" \
  > /tmp/report-verify.json
```

Verification checks server-side representation and dependencies without
creating a report. It does not prove the PDF layout is correct or that GET will
round-trip every UI feature.

### Step 7: Create only with explicit approval

After the user approves the persistent write and destination folder:

```bash
curl -sf -X POST \
  -H "Authorization: Bearer $SIGMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  --data-binary @/tmp/report-spec.json \
  "$SIGMA_BASE_URL/v2/reports/spec" \
  > /tmp/report-create.json
```

Save the submitted representation under a report-ID-specific path. Report the
report URL, ID, and saved path.

### Step 8: Read back and inspect output

Immediately GET the representation and compare normalized documents. Confirm
that optional fields survived and that no element, panel, page, or setting was
silently dropped. Then export the affected pages to PDF and inspect the actual
page breaks, clipping, typography, header/footer repetition, and margins.

```bash
ruby scripts/verify-report.rb "<report-id>"
ruby scripts/render-report.rb "<report-id>" /tmp/report-render --layout portrait
```

Read every generated `page-N.png`. For dense tables, verify the final visible
row and each subtotal; for board reports, verify the narrative hierarchy,
KPI labels/deltas, chart axes, bridge start/end totals, and negative colors.

Do not claim parity from a successful POST or PUT alone.

### Step 9: Update with a loss check

Follow `reference/workflows/crud.md`. The short version is:

1. GET and back up the current report representation.
2. Inventory report pages, controls, and elements through their resource APIs.
3. Stop if the inventory contains content absent from the GET representation.
4. Edit the complete `document`.
5. Validate in `--mode update` and call `/v2/reports/spec/verify` with a create
   envelope assembled from the current name/folder and edited document.
6. PUT `{"document": {...}, "documentVersion": <version-from-GET>}`. The
   version is optional in OpenAPI but strongly recommended so a concurrent edit
   fails instead of being overwritten.
7. GET again, compare, export, and inspect.

## Reference index

| File | Load when |
|---|---|
| `reference/specification/schema.md` | Always. Wrapped envelope, document fields, pages, panels, response metadata. |
| `reference/specification/layout.md` | Always. Pixel XML, bounds, page and panel placement. |
| `reference/specification/support-matrix.md` | Always. Safe, gated, unsupported, and workbook-only kinds. |
| `reference/specification/example-minimal.json` | Starting a new report representation. |
| `reference/workflows/discover.md` | Finding sources/columns, proving grain, resolving periods, and sizing page slices. |
| `reference/workflows/generate.md` | Generating executive/board reports, statements, or wide multi-page operational tables. |
| `reference/workflows/crud.md` | Creating, retrieving, or replacing a report document. |
| `reference/workflows/validate.md` | Before every verify, POST, or PUT and after readback. |
| `reference/workflows/convert.md` | Converting an existing workbook into a report. |

## Troubleshooting

| Symptom | Action |
|---|---|
| `unknown field`, `unexpected property`, or missing field | Compare the endpoint against the compiled OpenAPI and rerun the contract test. |
| `Invalid kind` after adding a channel or shelf | Replace legacy `{id: ...}` with `{columnId: ...}` and check list-vs-map fields. |
| A field or element disappears on GET | Re-send it with a non-default value before concluding anything — a field set to the server default is normalized out of the readback (KPI `layout.verticalAnchor: center` does this; `top`/`bottom` persist). If it disappears for every value, treat the representation as lossy and do not PUT until the omitted feature is removed intentionally or preserved another way. |
| Content overlaps or clips | Check pixel bounds, page dimensions, margins, and repeated panel height; inspect a PDF export. |
| A wide table clips or loses its final rows | Split it into explicit page-filtered table clones, budget row height, and inspect every rendered page. |
| `columnID`, `{id: ...}`, or an unknown column pointer appears | Use exact `columnId` and a column ID declared on the owning element; run the local validator before verify. |
| A custom-SQL source renders unknown columns | Quote aliases in SQL and declare each with `[Custom SQL/<exact alias>]`. |
| A workbook grid attribute appears in report XML | Replace it with absolute `x`, `y`, `width`, and `height`. |
| `progress` or synced control is requested | Stop or redesign; the published schema is not a safe report-authoring guarantee. `waterfall-chart` is supported using the proven shape in the board scaffold. |
| Conversion succeeds with warnings | Review every warning and its element IDs before accepting the generated report. |
| `Unknown column` or `Circular column reference` in a rendered cell | Qualify the formula with the source element name (`[Order Fact View/Net Revenue]`). Bare `[Column]` against a `data-model` source passes verify, create, and readback, then renders as error text. |

Reports are private beta. Prefer explicit evidence and reversible local edits
over speculative API writes.

