---
title: "Get Widget Data"
method: GET
path: "/api/v1/public/widgets/{widget_id}/data"
tags: ["Widgets"]
---

# Get Widget Data

`GET /api/v1/public/widgets/{widget_id}/data`

## Request

- Base URL: `https://app.traceroot.ai`
- URL: `https://app.traceroot.ai/api/v1/public/widgets/{widget_id}/data`
- Auth: HTTP bearer

Answer one saved widget for a window, with a status instead of an exception.

## Path parameters

- `widget_id` string, required

## Query parameters

- `range` '30m' | '1h' | '3h' | '6h' | '1d' | '7d' | '14d' | '30d' | '60d' | '90d', nullable: A preset window ending now, by the site picker's id. Give this or explicit start_time/end_time; neither means the site's 24-hour default.
- `start_time` string, date-time, nullable
- `end_time` string, date-time, nullable
- `project_id` string, nullable: Target project for the request. Required when authenticating with a user session token (a user credential is only meaningful scoped to a project); for an API key it is optional and, if given, must match the key's project.

## Response `200`

Successful Response

- WidgetDataResponse: One saved widget answered for one window. The per-widget answer of a dashboard data read, addressed by widget id: ``status`` says what happened — ``ok`` carries the engine's columns/rows/ meta; ``skipped`` is a feed or legacy detector widget (a trace list, not an aggregate — read those with ``list_traces`` and the feed's filters); ``error`` carries a short reason and no rows when the stored spec no longer validates or the engine rejects it — so a broken widget is still a 200 a script can branch on. One widget has no fan-out to protect, so the rows follow ``run_widget_query``: a series comes back whole and every other display returns what the engine returns. ``truncated`` is kept for parity with the dashboard read and is always false here. ``window`` is the window the rows were answered for — the one to name with any figure.
  - `columns` string[], nullable
  - `error` string, nullable
  - `meta` object, nullable
  - `rows` array[], nullable
    - unknown[]
      - unknown
  - `status` 'ok' | 'skipped' | 'error', required
  - `truncated` boolean
  - `widget` WidgetRef, required: The identity of the widget a data read answered, with its dashboard. ``spec`` is the stored spec the read ran, as ``get_widget`` returns it.
    - `dashboard_id` string, required
    - `dashboard_name` string, nullable
    - `id` string, required
    - `spec` unknown
    - `title` string, required
    - `type` string, required
  - `window` QueryWindow, required: The window a query was actually answered for. ``range`` is the preset id the caller gave (or the default's, when they gave nothing) and None for explicit bounds. ``clamped`` is True when the plan's retention pulled ``start_time`` forward — the honest reason a caller's window and the answered one differ.
    - `clamped` boolean, required
    - `end_time` string, date-time, required
    - `range` '30m' | '1h' | '3h' | '6h' | '1d' | '7d' | '14d' | '30d' | '60d' | '90d', nullable, required
    - `start_time` string, date-time, required

## Other responses

- `401`: Authentication failed
- `404`: Widget not found
- `422`: Validation Error
- `503`: Authentication service unavailable

---

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