curl --request GET \
--url https://app.traceroot.ai/api/v1/public/widgets/{widget_id}/data \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.traceroot.ai/api/v1/public/widgets/{widget_id}/data"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.traceroot.ai/api/v1/public/widgets/{widget_id}/data', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.traceroot.ai/api/v1/public/widgets/{widget_id}/data",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://app.traceroot.ai/api/v1/public/widgets/{widget_id}/data"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://app.traceroot.ai/api/v1/public/widgets/{widget_id}/data")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.traceroot.ai/api/v1/public/widgets/{widget_id}/data")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"status": "ok",
"widget": {
"dashboard_id": "<string>",
"id": "<string>",
"title": "<string>",
"type": "<string>"
},
"window": {
"clamped": true,
"end_time": "2023-11-07T05:31:56Z",
"range": "30m",
"start_time": "2023-11-07T05:31:56Z"
},
"columns": [
"<string>"
],
"error": "<string>",
"meta": {},
"rows": [
[
"<unknown>"
]
],
"truncated": false
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"ctx": {},
"input": "<unknown>"
}
]
}{
"detail": "<string>"
}Get Widget Data
Answer one saved widget for a window, with a status instead of an exception.
curl --request GET \
--url https://app.traceroot.ai/api/v1/public/widgets/{widget_id}/data \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.traceroot.ai/api/v1/public/widgets/{widget_id}/data"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.traceroot.ai/api/v1/public/widgets/{widget_id}/data', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.traceroot.ai/api/v1/public/widgets/{widget_id}/data",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://app.traceroot.ai/api/v1/public/widgets/{widget_id}/data"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://app.traceroot.ai/api/v1/public/widgets/{widget_id}/data")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.traceroot.ai/api/v1/public/widgets/{widget_id}/data")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"status": "ok",
"widget": {
"dashboard_id": "<string>",
"id": "<string>",
"title": "<string>",
"type": "<string>"
},
"window": {
"clamped": true,
"end_time": "2023-11-07T05:31:56Z",
"range": "30m",
"start_time": "2023-11-07T05:31:56Z"
},
"columns": [
"<string>"
],
"error": "<string>",
"meta": {},
"rows": [
[
"<unknown>"
]
],
"truncated": false
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"ctx": {},
"input": "<unknown>"
}
]
}{
"detail": "<string>"
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Query Parameters
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.
30m, 1h, 3h, 6h, 1d, 7d, 14d, 30d, 60d, 90d 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
Successful Response
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.
ok, skipped, error The identity of the widget a data read answered, with its dashboard.
Show child attributes
Show child attributes
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.
Show child attributes
Show child attributes

