儀表板
儀表板 API 允許您使用已用於攝取和查詢操作的相同 API 金鑰以程式設計方式列出、建立、編輯和刪除儀表板。
支援的操作:
- 列表.
GET https://api.telemetry.sh/dashboard - 建立.
POST https://api.telemetry.sh/dashboard - 編輯.
PATCH https://api.telemetry.sh/dashboard - 刪除.
DELETE https://api.telemetry.sh/dashboard
標題
| 名稱 | 型別 | 描述 |
|---|---|---|
Content-Type |
字串 | 必須是 application/json。 |
Authorization |
字串 | 您的 API 金鑰,作為原始金鑰或 Bearer <key>。 |
範圍規則:
GET /dashboard接受read、write或read-and-writePOST /dashboard、PATCH /dashboard和DELETE /dashboard需要write或read-and-write
列出回應
GET /dashboard 返回 API 金鑰團隊的每個儀表板,由 updated_at DESC 訂購。
支援的查詢參數:
| 領域 | 型別 | 必填 | 精確合約 | 預設 |
|---|---|---|---|---|
page |
整數 | 否 | 正整數頁碼。小於 1 的值將被拒絕。 |
1 |
pageSize |
整數 | 否 | 正整數頁面大小。大於 100 的值將被限制為 100。 API 還接受舊別名 page_size。 |
50 |
每個專案都包含儀表板後設資料、url、widget_count 以及 API 形狀的完整小工具列表。
高層回應:
| 領域 | 型別 | 精確合約 |
|---|---|---|
status |
字串 | 總是 "success" 就成功。 |
pagination |
物件 | 當前頁面的分頁後設資料。參見下表。 |
dashboards |
陣列 | API 金鑰團隊的儀表板物件陣列。當團隊沒有儀表板時,陣列為空。 |
pagination 包括:
| 領域 | 型別 | 精確合約 | 範例 |
|---|---|---|---|
page |
整數 | 當前從 1 開始的頁碼。 | 2 |
pageSize |
整數 | 預設和最大尺寸限制後的有效頁面尺寸。 | 25 |
total |
整數 | 分頁之前團隊的儀表板總數。 | 63 |
totalPages |
整數 | 當前總頁數為pageSize。 0,當 total 為 0 時。 |
3 |
hasNextPage |
布林值 | 噹噹前頁面之後存在另一個頁面時,true。 |
true |
hasPreviousPage |
布林值 | true 噹噹前頁面之前存在另一個頁面時。 |
true |
dashboards中的每一項包括:
| 領域 | 型別 | 精確合約 | 範例 |
|---|---|---|---|
id |
字串 | 儀表板 ID。 | "550e8400-e29b-41d4-a716-446655440000" |
team_id |
字串 | 擁有團隊 ID。 | "a7d4..." |
name |
字串 | 儀表板名稱。 | "Operations Overview" |
slug |
字串 | 儀表板蛞蝓。 | "operations-overview" |
description |
字串或 null |
儲存的儀表板描述。 | "Core service health and latency" |
created_by |
字串或 null |
UI 建立的儀表板的使用者 ID。 null 用於 API 建立的儀表板。 |
null |
created_by_api_key_id |
字串或 null |
API 建立的儀表板的團隊 API 金鑰 ID。 null 用於 UI 建立的儀表板。 |
"key_123" |
created_at |
字串 | 儀表板資料表中的時間戳字串。 | "2026-03-27T00:09:03.797Z" |
updated_at |
字串 | 儀表板資料表中的時間戳字串。 | "2026-03-27T00:09:03.797Z" |
url |
字串 | Telemetry UI 中的相對儀表板 URL。 | "/team/acme/dashboard/operations-overview" |
widget_count |
整數 | 附加到儀表板的小工具數量。 | 2 |
widgets |
陣列 | 建立和編輯回應返回的形狀相同的小工具陣列。 | [] |
建立身體
| 領域 | 型別 | 必填 | 精確合約 | 範例 |
|---|---|---|---|---|
name |
字串 | 是的 | 修剪後的儀表板名稱。修剪後必須非空。 | "HTTP Monitoring" |
slug |
字串 | 否 | 可選的定製塊。 Telemetry 透過修剪、小寫、刪除除 a-z、0-9、空格和 - 之外的所有字元、將空白執行轉換為 -、摺疊重複的 - 以及修剪前導/尾隨來對其進行規範化-。如果省略,則 Telemetry 源自 name。標準化結果仍必須至少包含一個字母數字字元。 |
"HTTP Monitoring!!!" 變為 "http-monitoring" |
description |
字串或 null |
否 | 可選描述。空字串標準化為 null。 |
"Core service health and latency" |
widgets |
陣列 | 否 | 要立即建立的可選小工具陣列。如果省略,儀表板將建立為空。如果任何小工具無效,則整個請求將被拒絕,並顯示 400。 |
[] |
建立回應
POST /dashboard 返回 201 Created 以及儲存的儀表板和規範化的小工具列表。
{
"status": "success",
"dashboard": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"team_id": "a7d4...",
"name": "HTTP Monitoring",
"slug": "http-monitoring",
"description": "Core service health and latency",
"created_by": null,
"created_by_api_key_id": "key_123",
"created_at": "2026-03-27T00:09:03.797Z",
"updated_at": "2026-03-27T00:09:03.797Z",
"url": "/team/acme/dashboard/http-monitoring"
},
"widgets": [
{
"id": "0b3cb3f5-1147-4f2f-bf64-5044147c3e9a",
"title": "Errors Per Hour",
"widget_type": "query",
"config": {
"querySql": "SELECT hour, errors FROM error_rollups",
"chartType": "Line Chart",
"xAxis": "hour",
"yAxis": "errors",
"groupBy": null,
"queryId": null,
"sourceUrl": null
},
"layout": {
"x": 0,
"y": 0,
"w": 12,
"h": 4
},
"sort_order": 1
}
]
}
編輯正文
PATCH /dashboard 是部分更新端點。省略的欄位保持不變。
您必須使用 dashboardId 或 dashboardSlug 標識目標儀表板。
| 領域 | 型別 | 必填 | 精確合約 | 範例 |
|---|---|---|---|---|
dashboardId |
字串 | dashboardId 或 dashboardSlug 之一 |
要編輯的現有儀表板 ID。如果傳送兩個識別符號,它們必須引用同一個儀表板。 | "550e8400-e29b-41d4-a716-446655440000" |
dashboardSlug |
字串 | dashboardId 或 dashboardSlug 之一 |
要編輯的現有儀表板 slug。這是當前的 slug,而不是新的 slug。 | "http-monitoring" |
name |
字串 | 否 | 新修剪的儀表板名稱。提供時必須非空。更新 name 不會自動更改 slug。 |
"HTTP Monitoring v2" |
slug |
字串 | 否 | 新的段頭值。 Telemetry 使用與 create 相同的規則對其進行規範化。如果省略,現有的 slug 保持不變。 | "http-monitoring-v2" |
description |
字串或 null |
否 | 新的儀表板描述。 null 或 "" 清除描述。如果省略,則現有描述保持不變。 |
"Updated on-call dashboard" |
widgets |
陣列 | 否 | 完整的替換小工具列表。如果省略,現有小工具將保持不變。如果提供,Telemetry 將刪除當前小工具集並將其替換為該陣列中的小工具。 [] 清除所有小工具。 |
[] |
注意事項:
PATCH尚不支援附加或編輯單個小工具。- 當提供
widgets時,會重新生成小工具 ID,因為 API 會替換完整的小工具集。
編輯回覆
PATCH /dashboard 返回 200 OK ,其回應形狀與建立相同:
dashboard包含儲存的儀表板後設資料和urlwidgets包含 API 形狀的完整持久小工具列表- 如果
widgets被替換,則返回的小工具 id 反映新插入的行
刪除正文
DELETE /dashboard 刪除單個儀表板及其所有小工具。
您必須使用 dashboardId 或 dashboardSlug 標識目標儀表板。
| 領域 | 型別 | 必填 | 精確合約 | 範例 |
|---|---|---|---|---|
dashboardId |
字串 | dashboardId 或 dashboardSlug 之一 |
要刪除的現有儀表板 ID。如果傳送兩個識別符號,它們必須引用同一個儀表板。 | "550e8400-e29b-41d4-a716-446655440000" |
dashboardSlug |
字串 | dashboardId 或 dashboardSlug 之一 |
要刪除的現有儀表板 slug。 | "http-monitoring" |
注意事項:
- 刪除是永久性的。
- 刪除儀表板也會刪除當前附加到其的所有小工具。
刪除回覆
DELETE /dashboard 返回 200 OK:
{
"status": "success",
"deleted_dashboard": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "HTTP Monitoring",
"slug": "http-monitoring",
"description": "Core service health and latency",
"widget_count": 2,
"url": "/team/acme/dashboard/http-monitoring"
}
}
常見錯誤
400 Bad Request如果 JSON 主體無效或請求主體不是 JSON 物件400 Bad Request如果page或pageSize不是GET /dashboard上的正整數400 Bad Request(如果PATCH或DELETE缺少dashboardId或dashboardSlug)400 Bad Request(如果PATCH省略所有可編輯欄位)400 Bad Request(如果name、slug、description或widgets驗證失敗)400 Bad Request如果查詢小工具包含非只讀 SQL403 Forbidden如果 API 金鑰沒有請求操作的權限401 Unauthorized(如果 API 金鑰丟失或無效)404 Not Found(如果 API 金鑰的團隊不存在儀表板)409 Conflict如果同一團隊中的另一個儀表板已使用請求的 slug
小工具欄位
widgets中的每個專案都支援:
| 領域 | 型別 | 必填 | 精確合約 | 範例 |
|---|---|---|---|---|
title |
字串 | 是的 | 修剪後的小工具標題。修剪後必須非空。 | "Errors Per Hour" |
widget_type |
字串 | 是的 | 精確列舉:query、explorer、header 或 free_text。 |
"query" |
config |
物件 | 是的 | 小工具設定物件。其必填欄位取決於widget_type。 |
{ "querySql": "...", "chartType": "Line Chart" } |
layout |
物件 | 否 | 可選的網格放置。如果省略,Telemetry 使用小工具型別預設值垂直堆疊小工具。 | { "x": 0, "y": 0, "w": 12, "h": 4 } |
瞭解佈局
Telemetry 儀表板使用 12 列網格。
layout 物件使用網格單位,而不是畫素:
| 領域 | 型別 | 預設 | 精確合約 | 範例 |
|---|---|---|---|---|
x |
整數 | 0 |
非負整數。 0 是最左邊的。無效值回退到 0。 |
0 |
y |
整數 | 下一個空行 | 非負整數。 0是儀表板的頂部。如果省略,Telemetry 會將小工具放置在前一個小工具的 y + h 之後。無效值會回退到該計算行。 |
0 |
w |
整數 | 12 |
網格列中的正整數寬度。 12 表示全形,6 表示半形。無效值回退到 12。 |
12 |
h |
整數 | 小工具型別預設值 | 網格行中的正整數高度。無效值會回退到下面列出的小工具型別預設值。 | 4 |
所以這個:
"layout": { "x": 0, "y": 0, "w": 12, "h": 4 }
意思是:
- 將小工具放置在儀表板的左上角
- 使其跨越所有 12 列
- 使其高為 4 行儀表板網格
這個:
"layout": { "x": 6, "y": 0, "w": 6, "h": 4 }
意思是:
- 將小工具放在頂行
- 從儀表板的一半開始
- 讓它佔據行的右半部分
例如,這兩個小工具並排呈現:
[
{ "layout": { "x": 0, "y": 0, "w": 6, "h": 4 } },
{ "layout": { "x": 6, "y": 0, "w": 6, "h": 4 } }
]
如果省略 layout,Telemetry 將使用以下預設值垂直堆疊小工具:
x = 0w = 12h = 4適用於query和explorerh = 2為headerh = 3為free_texty放置在下一個空行上
Telemetry 不會將 x 和 w 鉗位到 12 列網格,並且不會為您解決重疊位置。如果您想要可預測的渲染,請保留 x + w <= 12 並避免重疊 x/y 範圍。
查詢小工具設定
| 領域 | 型別 | 必填 | 精確值或格式 | 範例 |
|---|---|---|---|---|
querySql |
字串 | 是的 | 已修剪只讀 SQL 字串。修剪後必須非空。儀表板查詢小工具拒絕寫入語句,例如 INSERT、UPDATE、DELETE、DROP、ALTER、TRUNCATE、CREATE、GRANT 和REVOKE。 |
"SELECT endpoint, COUNT(*) AS errors FROM http_logs GROUP BY endpoint" |
chartType |
字串 | 是的 | 由 API 驗證的精確列舉:table、Scatter Plot、Bar Chart、Line Chart 或 Stacked Area Chart。 |
"Line Chart" |
xAxis |
字串 | 非 table 圖表需要 |
用於 x 軸的修剪結果列名稱。對於 Bar Chart,這可以是文字/分類、數字或類似時間的列。對於 Scatter Plot、Line Chart 和 Stacked Area Chart,請使用數字或類似時間的列。僅當 chartType 為 table 時才可以為空字串。 |
"hour" |
yAxis |
字串 | 非 table 圖表需要 |
修剪後的數字結果列名稱用於 y 軸。僅當 chartType 為 table 時才可以為空字串。 |
"errors" |
groupBy |
字串或 null |
否 | 可選的修剪結果列名稱,用於將圖表拆分為多個系列。使用 null 或省略它以不進行分組。 |
"service" |
queryId |
字串或 null |
否 | 可選的修剪儲存查詢 ID。 API 將其儲存為字串,並且不驗證其形狀。 | "550e8400-e29b-41d4-a716-446655440000" |
sourceUrl |
字串或 null |
否 | 點選小工具標題時開啟的可選修剪 UI URL。建議使用相關應用程式 URL,例如 /team/acme/ops/draft/0?...。 |
"/team/acme/ops/draft/0?tab=chart&chartType=Line+Chart&xAxis=hour&yAxis=errors" |
注意事項:
- 如果您想要簡單的結果資料表而不是圖表,請使用
chartType: "table"。 - 儀表板查詢小工具會在儀表板載入時自動執行,因此僅接受只讀 SQL。
- 對於所有非
table圖表,xAxis和yAxis必須與querySql返回的實際列匹配。 - 對於
Bar Chart,xAxis可以是文字/分類、數字或類時間。 - 對於
Scatter Plot、Line Chart和Stacked Area Chart,xAxis必須是數字或類時間。 - 對於所有非
table圖表,yAxis必須是數字。 - 對於分類
Bar Chartx 軸,小工具保留查詢結果順序。使用querySql中的ORDER BY來控制條順序。 - 如果省略
sourceUrl,則儀表板 UI 會在可能的情況下派生後備草稿查詢 URL。派生連結保留defaultQuery、tab、chartType、xAxis、yAxis和groupBy。
範例:帶有分類條形圖 x 軸的查詢小工具
{
"title": "Requests by Endpoint",
"widget_type": "query",
"config": {
"querySql": "SELECT endpoint, COUNT(*) AS requests FROM http_logs GROUP BY endpoint ORDER BY requests DESC",
"chartType": "Bar Chart",
"xAxis": "endpoint",
"yAxis": "requests",
"groupBy": null
}
}
在那個例子中:
endpoint是文字 x 軸列requests是 y 軸數字列ORDER BY requests DESC控制從左到右的條形順序
標題小工具設定
使用 widget_type: "header" 作為對相關小工具進行分組的部分標題。
| 領域 | 型別 | 必填 | 精確值或格式 | 範例 |
|---|---|---|---|---|
description |
字串或 null |
否 | 可選的降價描述顯示在標題標題下。空字串標準化為 null。 |
"Watch these charts during deploys and incident triage." |
注意事項:
- 小工具
title是可見部分標題。 description支援降價。原始 HTML 在 UI 中呈現之前會被轉義。
範例:
{
"title": "Deploy Health",
"widget_type": "header",
"config": {
"description": "Use this section during rollout checks and incident response."
}
}
自由文字小工具設定
使用 widget_type: "free_text" 獲取獨立的 Markdown 註釋、連結或執行手冊說明。
| 領域 | 型別 | 必填 | 精確值或格式 | 範例 |
|---|---|---|---|---|
content |
字串 | 是的 | 修剪後的非空 Markdown 內容。 | "Check [the latency recipe](/sql/api-latency-percentiles) before paging infra." |
注意事項:
content支援降價。原始 HTML 在 UI 中呈現之前會被轉義。- 即使 UI 僅呈現此元件型別的 Markdown 主體,API 仍然需要小工具
title。
範例:
{
"title": "API Runbook Note",
"widget_type": "free_text",
"config": {
"content": "Check the on-call runbook first, then compare request volume with deploy timestamps."
}
}
資源管理器小工具設定
| 領域 | 型別 | 必填 | 精確值或格式 | 範例 |
|---|---|---|---|---|
tableName |
字串 | 是的 | 修剪後的源資料表名稱。修剪後必須非空。 | "queue_metrics" |
explorerState |
物件 | 是的 | 用於呈現小工具的完整探索設定。請參閱下面的詳細欄位資料表。 | { "graphType": "line", "aggregation": "p95", ... } |
sourceUrl |
字串或 null |
否 | 點選小工具標題時開啟的可選修剪 UI URL。如果省略,Telemetry 將從 tableName 和 explorerState 派生回退探索 URL。 |
"/team/acme/table/queue_metrics?tab=explore&graphType=line" |
explorerState 欄位
| 領域 | 型別 | 必填 | 精確值或格式 | 預設 | 範例 |
|---|---|---|---|---|---|
graphType |
字串 | 是的 | 由 API 驗證的精確列舉:samples、table、line、bar、stacked-area。 |
"samples" |
"line" |
aggregation |
字串 | 是的 | 由 API 驗證的精確列舉:count、sum、avg、min、max、p50、p90、 p95、p99。 |
"count" |
"p95" |
metric |
字串或 null |
否 | 修剪後的列或欄位路徑進行聚合。將 null 用於 count。對於非 count 聚合,這是主要度量,並且優先於自動檢測到的數字 selectedColumns(如果提供)。 |
null |
"latency_ms" |
timeZone |
字串或 null |
否 | 使用 UTC 或 IANA 時區識別符號,例如 America/Los_Angeles 或 Europe/Berlin。 API 當前會修剪並儲存任何非空字串,但無效的時區名稱稍後在小工具查詢執行時可能會失敗。如果省略,儲存的設定將保留 null,並且 UI 根據上下文回退到客戶端時區或 UTC。 |
null |
"America/Los_Angeles" |
timePreset |
字串 | 是的 | 支援的值為 1h、6h、24h、7d、30d、90d、custom。 API 當前接受任何非空字串,但 UI 和 SQL 生成器僅支援這些值。 |
"7d" |
"7d" |
customStart |
字串 | 否 | 當 timePreset 為 custom 時使用。推薦格式:YYYY-MM-DDTHH:mm、YYYY-MM-DD HH:mm、YYYY-MM-DDTHH:mm:ss 或 YYYY-MM-DDTHH:mm:ss.sss,可選地後跟 Z 或數字偏移量(如 -07:00)。如果不存在時區字尾,則以 timeZone 解釋該值。 |
未設定 | "2026-03-20T00:00:00Z" |
customEnd |
字串 | 否 | 與 customStart 格式相同。如果自定義範圍被省略,則查詢沒有時間上限。 |
未設定 | "2026-03-26T00:00:00-07:00" |
granularity |
字串 | 是的 | 由 API 驗證的精確列舉:auto、minute、hour、day、week、month。 |
"auto" |
"hour" |
splitBy |
字串陣列 | 是的 | 非空修剪欄位名稱陣列。巢狀 JSON 欄位允許使用點路徑,例如 attributes.queue_name。 |
[] |
["queue_name"] |
seriesLimit |
整數或 null |
否 | 正整數或 null。 null 表示無明確系列上限。對於分割圖最有用。 |
100 |
10 |
filters |
陣列 | 是的 | 過濾器組陣列。每個組在內部進行“與”運算;多個組透過 OR 組合在一起。在規範化過程中,空的或無效的組將被刪除。 | [] |
[] |
selectedColumns |
字串陣列 | 是的 | 要在 samples 或 table 檢視中顯示的非空修剪欄位名稱陣列。允許使用點狀 JSON 路徑。使用 [] 讓 Telemetry 選擇預設值。 |
[] |
["timestamp_utc", "queue_name", "latency_ms"] |
orderBy |
字串或 null |
否 | 用於對錶格結果進行排序的可選欄位名稱。允許使用點狀 JSON 路徑。 | null |
"timestamp_utc" |
limit |
整數 | 是的 | 正整數行或組限制。無效值將恢復為預設值。 | 200 |
200 |
orderDirection |
字串 | 是的 | 由 API 驗證的精確列舉:ASC 或 DESC。 |
"DESC" |
"DESC" |
timePreset 值
| 價值 | 含義 |
|---|---|
1h |
最後 1 小時 |
6h |
最後 6 小時 |
24h |
過去 24 小時 |
7d |
過去 7 天 |
30d |
過去 30 天 |
90d |
過去 90 天 |
custom |
使用 customStart 和 customEnd 代替相對範圍 |
如果您傳送未記錄的 timePreset,則當前的 SQL 生成器將回退到 7 天行為。將上述值視為受支援的合約。
granularity: "auto" 行為
當 granularity 為 auto 時,Telemetry 解析如下:
timePreset |
有效粒度 |
|---|---|
1h、6h、24h |
minute |
7d |
hour |
30d、90d、custom |
day |
過濾組和條件
filters 的形狀應如下所示:
[
{
"logic": "AND",
"conditions": [
{ "field": "queue_name", "operator": "=", "value": "email" },
{ "field": "latency_ms", "operator": ">", "value": "1000" }
]
}
]
filters中的每一項都是一個過濾器組:
| 領域 | 型別 | 必填 | 精確值或格式 | 範例 |
|---|---|---|---|---|
logic |
字串 | 是的 | 必須是 AND。儀表板建立 API 將每個組標準化為 AND;沒有每組 OR。要表達 OR,請使用多個組,因為組是透過 OR 組合在一起的。 |
"AND" |
conditions |
陣列 | 是的 | 組中的過濾條件陣列。有效條件為零的組將被刪除。 | [{ "field": "queue_name", "operator": "=", "value": "email" }] |
conditions中的每個專案都支援:
| 領域 | 型別 | 必填 | 精確值或格式 | 範例 |
|---|---|---|---|---|
field |
字串 | 是的 | 非空修剪欄位路徑。支援點巢狀 JSON 路徑,例如 attributes.queue_name。不允許有空路徑段。 |
"latency_ms" |
operator |
字串 | 是的 | 由 API 驗證的精確列舉:=、!=、>、>=、<、<=、LIKE、 NOT LIKE、IS NULL、IS NOT NULL。 |
">" |
value |
字串、數字、布林值或 null |
通常 | 在標準化期間儲存為字串。對於 IS NULL 和 IS NOT NULL,使用 "" 或省略語義值。 null 變為 ""。 |
"1000" |
生成的SQL執行時:
- 組內條件與
AND相連線 - 組加入
OR - 點狀欄位路徑(例如
attributes.queue_name)被轉換為巢狀欄位存取
範例:建立一個空儀表板
範例:列出儀表板
curl "https://api.telemetry.sh/dashboard?page=1&pageSize=25" \
-H "Authorization: $API_KEY"
回應範例:
{
"status": "success",
"pagination": {
"page": 1,
"pageSize": 25,
"total": 1,
"totalPages": 1,
"hasNextPage": false,
"hasPreviousPage": false
},
"dashboards": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"team_id": "team_123",
"name": "Operations Overview",
"slug": "operations-overview",
"description": "Core service health and latency",
"created_by": null,
"created_by_api_key_id": "key_123",
"created_at": "2026-03-27T00:09:03.797Z",
"updated_at": "2026-03-27T00:09:03.797Z",
"url": "/team/acme/dashboard/operations-overview",
"widget_count": 1,
"widgets": [
{
"id": "widget_123",
"title": "Requests Per Hour",
"widget_type": "query",
"config": {
"querySql": "SELECT DATE_TRUNC('hour', timestamp_utc) AS hour, COUNT(*) AS requests FROM http_logs GROUP BY 1 ORDER BY 1",
"chartType": "Line Chart",
"xAxis": "hour",
"yAxis": "requests",
"groupBy": null,
"sourceUrl": "/team/acme/ops/draft/0?tab=chart&chartType=Line+Chart&xAxis=hour&yAxis=requests"
},
"layout": { "x": 0, "y": 0, "w": 12, "h": 4 },
"sort_order": 0
}
]
}
]
}
範例:建立一個空儀表板
curl -X POST https://api.telemetry.sh/dashboard \
-H "Content-Type: application/json" \
-H "Authorization: $API_KEY" \
-d '{
"name": "Operations Overview",
"description": "Core service health and latency"
}'
範例:重新命名儀表板並更新其描述
curl -X PATCH https://api.telemetry.sh/dashboard \
-H "Content-Type: application/json" \
-H "Authorization: $API_KEY" \
-d '{
"dashboardSlug": "operations-overview",
"name": "Operations Overview v2",
"description": "Updated to focus on API latency and error rates"
}'
範例:替換現有儀表板上的所有小工具
此請求保留相同的儀表板,但用新的 widgets 陣列替換完整的小工具集。
curl -X PATCH https://api.telemetry.sh/dashboard \
-H "Content-Type: application/json" \
-H "Authorization: $API_KEY" \
-d '{
"dashboardSlug": "operations-overview",
"widgets": [
{
"title": "Revenue by City",
"widget_type": "explorer",
"config": {
"tableName": "uber_rides",
"explorerState": {
"graphType": "table",
"aggregation": "sum",
"metric": "price",
"timePreset": "30d",
"granularity": "auto",
"splitBy": ["city"],
"filters": [],
"selectedColumns": [],
"orderBy": "price",
"limit": 10,
"orderDirection": "DESC"
}
},
"layout": { "x": 0, "y": 0, "w": 12, "h": 4 }
}
]
}'
範例:刪除儀表板
curl -X DELETE https://api.telemetry.sh/dashboard \
-H "Content-Type: application/json" \
-H "Authorization: $API_KEY" \
-d '{
"dashboardSlug": "operations-overview"
}'
常見小工具範例
下一個範例僅顯示您傳送到 POST /dashboard 的 JSON 請求正文。
這些範例假設 uber_rides 資料表包含以下欄位:
citypricewait_time_minutesstatususer_idtimestamp_utc
範例:建立一個包含兩個常見 Explore 小工具的儀表板
該範例包括:
- 一個表格小工具,按城市彙總乘車收入並按收入降序排序
- 一個時間序列小工具,將按城市的平均等待時間繪製為分組線
{
"name": "Uber Marketplace Overview",
"widgets": [
{
"title": "Revenue by City",
"widget_type": "explorer",
"config": {
"tableName": "uber_rides",
"explorerState": {
"graphType": "table",
"aggregation": "sum",
"metric": "price",
"timePreset": "30d",
"granularity": "auto",
"splitBy": ["city"],
"filters": [
{
"logic": "AND",
"conditions": [
{ "field": "status", "operator": "=", "value": "completed" }
]
}
],
"selectedColumns": ["city", "price"],
"orderBy": "price",
"limit": 20,
"orderDirection": "DESC"
}
},
"layout": { "x": 0, "y": 0, "w": 6, "h": 4 }
},
{
"title": "Average Wait Time by City",
"widget_type": "explorer",
"config": {
"tableName": "uber_rides",
"explorerState": {
"graphType": "line",
"aggregation": "avg",
"metric": "wait_time_minutes",
"timePreset": "7d",
"granularity": "hour",
"splitBy": ["city"],
"seriesLimit": null,
"filters": [
{
"logic": "AND",
"conditions": [
{ "field": "status", "operator": "=", "value": "completed" }
]
}
],
"selectedColumns": ["city", "wait_time_minutes"],
"limit": 200,
"orderDirection": "ASC"
}
},
"layout": { "x": 6, "y": 0, "w": 6, "h": 4 }
}
]
}
在那個例子中:
Revenue by City是一個探索表格小工具selectedColumns: ["city", "price"]加上aggregation: "sum"為每個city生成一個聚合price色譜柱orderBy: "price"按彙總收入列排序Average Wait Time by City是一個探索行小工具splitBy: ["city"]每個城市建立一條線路orderDirection: "ASC"保持時間軸按時間順序排列
範例:建立佇列保留微笑曲線的查詢小工具
此範例使用查詢小工具,因為群組保留在探索中更難表達。它使用:
- 首次乘坐群體定義
- 獨特的每週活動資料表
- 佇列規模和保留乘客之間的聯絡
可讀querySql:
WITH first_rides AS (
SELECT
user_id,
date_trunc('week', MIN(timestamp_utc)) AS cohort_week
FROM
uber_rides
WHERE
status = 'completed'
GROUP BY
user_id
),
weekly_activity AS (
SELECT DISTINCT
user_id,
date_trunc('week', timestamp_utc) AS activity_week
FROM
uber_rides
WHERE
status = 'completed'
),
cohort_activity AS (
SELECT
f.cohort_week,
a.activity_week,
date_part('day', a.activity_week - f.cohort_week) / 7 AS weeks_since_first_ride,
COUNT(DISTINCT a.user_id) AS retained_riders
FROM
first_rides f
JOIN weekly_activity a ON a.user_id = f.user_id
WHERE
a.activity_week >= f.cohort_week
GROUP BY
f.cohort_week,
a.activity_week,
date_part('day', a.activity_week - f.cohort_week) / 7
),
cohort_sizes AS (
SELECT
cohort_week,
COUNT(*) AS cohort_size
FROM
first_rides
GROUP BY
cohort_week
)
SELECT
weeks_since_first_ride,
100.0 * retained_riders / cohort_size AS retention_pct,
CAST(ca.cohort_week AS VARCHAR) AS cohort_week
FROM
cohort_activity ca
JOIN cohort_sizes cs ON ca.cohort_week = cs.cohort_week
WHERE
weeks_since_first_ride BETWEEN 0 AND 12
ORDER BY
weeks_since_first_ride ASC,
cohort_week ASC
{
"name": "Uber Rider Retention",
"widgets": [
{
"title": "Weekly Rider Retention Smile Curves",
"widget_type": "query",
"config": {
"querySql": "WITH first_rides AS ( SELECT user_id, date_trunc('week', MIN(timestamp_utc)) AS cohort_week FROM uber_rides WHERE status = 'completed' GROUP BY user_id ), weekly_activity AS ( SELECT DISTINCT user_id, date_trunc('week', timestamp_utc) AS activity_week FROM uber_rides WHERE status = 'completed' ), cohort_activity AS ( SELECT f.cohort_week, a.activity_week, date_part('day', a.activity_week - f.cohort_week) / 7 AS weeks_since_first_ride, COUNT(DISTINCT a.user_id) AS retained_riders FROM first_rides f JOIN weekly_activity a ON a.user_id = f.user_id WHERE a.activity_week >= f.cohort_week GROUP BY f.cohort_week, a.activity_week, date_part('day', a.activity_week - f.cohort_week) / 7 ), cohort_sizes AS ( SELECT cohort_week, COUNT(*) AS cohort_size FROM first_rides GROUP BY cohort_week ) SELECT weeks_since_first_ride, 100.0 * retained_riders / cohort_size AS retention_pct, CAST(ca.cohort_week AS VARCHAR) AS cohort_week FROM cohort_activity ca JOIN cohort_sizes cs ON ca.cohort_week = cs.cohort_week WHERE weeks_since_first_ride BETWEEN 0 AND 12 ORDER BY weeks_since_first_ride ASC, cohort_week ASC",
"chartType": "Line Chart",
"xAxis": "weeks_since_first_ride",
"yAxis": "retention_pct",
"groupBy": "cohort_week"
},
"layout": { "x": 0, "y": 0, "w": 12, "h": 5 }
}
]
}
在那個例子中:
weeks_since_first_ride是 x 軸retention_pct是 y 軸groupBy: "cohort_week"為每個註冊佇列建立一條線,從而生成微笑曲線風格比較- 這是一個查詢小工具而不是探索小工具,因為佇列邏輯依賴於多個 CTE 和連線
回應
成功的 POST 請求返回 201 Created。
成功的 PATCH 請求返回 200 OK。
兩者都返回這個形狀:
{
"status": "success",
"dashboard": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"team_id": "team_123",
"name": "HTTP Monitoring",
"slug": "http-monitoring",
"description": null,
"created_by": null,
"created_by_api_key_id": "8dff0c1a-8b36-49c3-9e6b-dc0d3ff51d74",
"created_at": "2026-03-26T00:00:00.000Z",
"updated_at": "2026-03-26T00:00:00.000Z",
"url": "/team/acme/dashboard/http-monitoring"
},
"widgets": [
{
"id": "9a6e4f27-d3bf-4a70-bf3a-38fe63211f93",
"title": "Errors Per Hour",
"widget_type": "query",
"config": {
"queryId": null,
"querySql": "SELECT ...",
"chartType": "Line Chart",
"xAxis": "hour",
"yAxis": "errors",
"groupBy": null,
"sourceUrl": null
},
"layout": {
"x": 0,
"y": 0,
"w": 12,
"h": 4
},
"sort_order": 1
}
]
}
成功的 DELETE 請求返回 200 OK 以及刪除摘要:
{
"status": "success",
"deleted_dashboard": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "HTTP Monitoring",
"slug": "http-monitoring",
"description": null,
"widget_count": 6,
"url": "/team/acme/dashboard/http-monitoring"
}
}
透過此 API 建立的儀表板是團隊範圍的,並歸因於建立它們的 API 金鑰:
- 對於 API 建立的儀表板,
created_by是null,因為 API 金鑰不是使用者 created_by_api_key_id是建立金鑰的內部team_api_keys.id行- 透過 UI 建立的儀表板仍然使用
created_by和使用者 ID,並且通常將created_by_api_key_id保留為null
如果您的團隊已存在標準化的段,則 API 將返回 409 Conflict。
其他常見錯誤:
400 Bad Request(如果必填欄位缺失或無效)400 Bad Request如果查詢小工具包含非只讀 SQL404 Not Found(如果您的團隊不存在目標儀表板)401 Unauthorized(如果 API 金鑰丟失或無效)400 Bad Request如果 API 金鑰僅具有read範圍