---
title: "Run one panel"
method: GET
path: "/api/v1/ackdb/observe/dashboards/{id}/data"
tags: ["ackDB"]
---

# Run one panel

`GET /api/v1/ackdb/observe/dashboards/{id}/data`

## Request

- Base URL: `http://localhost:3009`
- URL: `http://localhost:3009/api/v1/ackdb/observe/dashboards/{id}/data`
- Auth: HTTP bearer

Run ONE saved panel and return its envelope. Authorization is on the DASHBOARD, not the pinned segment: sharing a dashboard shares what it shows. Always 200 for a data-shaped failure (the console fetches panels in parallel and renders each independently). Cached 30s, keyed on the panel spec + the segment's filterHash + its sync seq, so a filter edit or a membership change busts it immediately. Rate limited to 60 reads per dashboard per minute, applied AFTER authorization.

## Path parameters

- `id` string, required

## Query parameters

- `panel` string, required

## Response `200`

The panel envelope (data | degraded | error).

- union: A panel's whole answer, always HTTP 200 for a data-shaped outcome. EXACTLY one arm: `data` (it ran), `degraded` (a scrub path disarmed it, or its segment is gone: no data, no 400), or `error` (timeout, read-only guard rejection, stale field - isolated to this panel).
  - object
    - `data` union, required
      - AckdbKpiData: One number. An empty segment and a NULL aggregate both read null ("nothing to average", not 0).
        - `value` number, nullable, required
      - AckdbBreakdownData
        - `groups` object[], required: At most topN, ordered per the spec. A null label is a real group ("unset"), never dropped.
          - `label` string, nullable, required
          - `value` number, nullable, required
        - `total` number, nullable, required: The AGGREGATE across ALL groups, pre-topN, in the same unit as `value` - NOT a row count (it is a row count only when agg is `count`). This is what a percent-of-total label needs.
        - `groupCount` integer, required: How many groups exist in total.
        - `others` object, nullable, required: Present only with othersBucket:true AND more groups than were returned. Exact, derived from the two window functions.
          - `value` number
          - `groupCount` integer
      - AckdbTimeseriesData: Dense: one point per bucket, `t` is the bucket START (ISO-8601), ascending. Event and membership values are zero-filled numbers; a score month with no scored member is null.
        - `buckets` object[], required
          - `t` string, date-time, required
          - `value` number, nullable, required
      - AckdbTableData: Rows verbatim from the grain's row compiler - byte-identical to GET /observe/segments/{id}/results.
        - `rows` object[], required
        - `columns` string[], required: The projected keys in projection order (base columns included).
      - AckdbFeedData
        - `changes` object[], required
          - `seq` integer, required
          - `id` string, required: Member id: entity_id / contact_id / person_id per the segment's grain.
          - `kind` 'enter' | 'exit', required: A stored `reenter` is reported as `enter`.
          - `at` string, date-time, required
          - `name` string, nullable, required
          - `domain` string, nullable: Company grain only.
        - `asOfSeq` integer, required: The segment sync seq this page was read at.
        - `historySince` string, date-time, nullable, required: The segment's sync bootstrap time. The feed structurally cannot show anything older - caption it so an empty feed does not read as "nothing happened".
      - AckdbSqlData
        - `columns` object[], required: Echoed from the spec.
        - `rows` object[], required
  - object
    - `degraded` true, required
    - `reason` string, required
  - object
    - `error` object, required: PANEL_COMPILE | SCORE_NOT_FOUND | SYNC_UNAVAILABLE | QUERY_ERROR | QUERY_TIMEOUT | ...
      - `code` string, required
      - `message` string, required

## Other responses

- `400`: The `panel` query parameter is missing, or names no panel on this dashboard.
- `403`: The caller cannot see this dashboard.
- `404`: DASHBOARD_NOT_FOUND.
- `429`: RATE_LIMITED - more than 60 data reads for this dashboard this minute. `Retry-After` is set.

---

[API](https://skmtc.dev/floqer/apis/floqer-public-api.md) - [All operations](https://skmtc.dev/floqer/apis/floqer-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/floqer/apis/floqer-public-api/revisions/fce50dc07b20?raw)
