콘텐츠로 건너뛰기
Telemetry
문서 찾아보기
API 레퍼런스업데이트된 2026년 7월 27일Telemetry 편집 및 제품 팀의 검토17 최소 읽기

코딩 에이전트와 함께 이 문서를 사용하세요.

Claude Code, Codex, Cursor 또는 다른 코딩 에이전트에 대한 집중 프롬프트 팩을 연 다음 여기에서 다루는 워크플로에 맞게 조정하세요.

이 페이지에서
  1. 응답 나열
  2. 몸체 만들기
  3. 응답 만들기
  4. 본문 편집
  5. 응답 수정
  6. 본문 삭제
  7. 응답 삭제
  8. 일반적인 오류
  9. 위젯 필드
  10. 레이아웃 이해
  11. 쿼리 위젯 구성
  12. 예: 범주형 막대 차트 x축이 있는 쿼리 위젯
  13. 헤더 위젯 구성
  14. 무료 텍스트 위젯 구성
  15. 탐색기 위젯 구성
  16. 예: 빈 대시보드 만들기
  17. 예: 대시보드 나열
  18. 예: 빈 대시보드 만들기
  19. 예: 대시보드 이름 바꾸기 및 설명 업데이트
  20. 예: 기존 대시보드의 모든 위젯 교체
  21. 예: 대시보드 삭제
  22. 일반적인 위젯 예
  23. 예: 두 개의 일반적인 탐색 위젯이 포함된 대시보드 만들기
  24. 예: 코호트 유지 미소 곡선에 대한 쿼리 위젯 만들기
  25. 응답

대시보드

대시보드 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 /dashboardread, write 또는 read-and-write를 허용합니다.
  • POST /dashboard, PATCH /dashboardDELETE /dashboard에는 write 또는 read-and-write가 필요합니다.

응답 나열

GET /dashboardupdated_at DESC에서 주문한 API 키 팀의 모든 대시보드를 반환합니다.

지원되는 쿼리 매개변수:

필드 유형 필수 정확한 계약 기본값
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의 총 페이지 수입니다. total0인 경우 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입니다. API가 생성한 대시보드용 null입니다. null
created_by_api_key_id 문자열 또는 null API가 생성한 대시보드의 팀 API 키 ID입니다. UI로 생성된 대시보드용 null. "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 중 하나 편집할 기존 대시보드 슬러그입니다. 이것은 새로운 슬러그가 아닌 현재 슬러그입니다. "http-monitoring"
name 문자열 아니요 새롭게 정리된 대시보드 이름입니다. 제공되는 경우 비어 있지 않아야 합니다. name를 업데이트해도 슬러그가 자동으로 변경되지 않습니다. "HTTP Monitoring v2"
slug 문자열 아니요 새로운 슬러그 값. Telemetry는 생성과 동일한 규칙으로 정규화합니다. 생략하면 기존 슬러그가 변경되지 않고 유지됩니다. "http-monitoring-v2"
description 문자열 또는 null 아니요 새로운 대시보드 설명. null 또는 ""는 설명을 지웁니다. 생략하면 기존 설명이 변경되지 않습니다. "Updated on-call dashboard"
widgets 배열 아니요 전체 대체 위젯 목록. 생략하면 기존 위젯은 변경되지 않습니다. 제공된 경우 Telemetry는 현재 위젯 세트를 삭제하고 이를 정확히 이 배열의 위젯으로 대체합니다. []는 모든 위젯을 지웁니다. []

참고:

  • PATCH는 아직 단일 위젯 추가 또는 편집을 지원하지 않습니다.
  • widgets가 제공되면 API가 전체 위젯 세트를 대체하므로 위젯 ID가 다시 생성됩니다.

응답 수정

PATCH /dashboard는 create와 동일한 응답 형태로 200 OK를 반환합니다.

  • dashboard에는 저장된 대시보드 메타데이터와 url가 포함되어 있습니다.
  • widgets에는 API 모양의 전체 지속 위젯 목록이 포함되어 있습니다.
  • widgets가 교체된 경우 반환된 위젯 ID는 새로 삽입된 행을 반영합니다.

본문 삭제

DELETE /dashboard는 단일 대시보드와 해당 위젯을 모두 삭제합니다.

dashboardId 또는 dashboardSlug로 대상 대시보드를 식별해야 합니다.

필드 유형 필수 정확한 계약
dashboardId 문자열 dashboardId 또는 dashboardSlug 중 하나 삭제할 기존 대시보드 ID입니다. 두 식별자가 모두 전송되면 동일한 대시보드를 참조해야 합니다. "550e8400-e29b-41d4-a716-446655440000"
dashboardSlug 문자열 dashboardId 또는 dashboardSlug 중 하나 삭제할 기존 대시보드 슬러그입니다. "http-monitoring"

참고:

  • 삭제는 영구적입니다.
  • 대시보드를 삭제하면 현재 대시보드에 연결된 위젯도 모두 삭제됩니다.

응답 삭제

DELETE /dashboard200 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"
  }
}

일반적인 오류

  • JSON 본문이 유효하지 않거나 요청 본문이 JSON 개체가 아닌 경우 400 Bad Request
  • page 또는 pageSizeGET /dashboard에서 양의 정수가 아닌 경우 400 Bad Request
  • 400 Bad Request dashboardId 또는 dashboardSlugPATCH 또는 DELETE에 누락된 경우
  • PATCH가 편집 가능한 모든 필드를 생략하는 경우 400 Bad Request
  • name, slug, description 또는 widgets가 검증에 실패한 경우 400 Bad Request
  • 쿼리 위젯에 읽기 전용이 아닌 SQL이 포함된 경우 400 Bad Request
  • API 키에 요청된 작업에 대한 권한이 없는 경우 403 Forbidden
  • API 키가 없거나 잘못된 경우 401 Unauthorized
  • API 키 팀에 대한 대시보드가 없는 경우 404 Not Found
  • 같은 팀의 다른 대시보드가 이미 요청한 슬러그를 사용하는 경우 409 Conflict

위젯 필드

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 = 0
  • w = 12
  • queryexplorerh = 4
  • headerh = 2
  • free_texth = 3
  • y는 다음 열린 행에 배치됩니다.

Telemetry는 xw를 12열 그리드에 고정하지 않으며 겹치는 위치를 자동으로 해결하지 않습니다. 예측 가능한 렌더링을 원하는 경우 x + w <= 12를 유지하고 x/y 범위가 겹치지 않도록 하세요.

쿼리 위젯 구성

필드 유형 필수 정확한 값 또는 형식
querySql 문자열 읽기 전용 SQL 문자열이 잘렸습니다. 트리밍 후에는 비어 있지 않아야 합니다. 대시보드 쿼리 위젯은 INSERT, UPDATE, DELETE, DROP, ALTER, TRUNCATE, CREATE와 같은 쓰기 문을 거부합니다. GRANTREVOKE. "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 ChartStacked Area Chart의 경우 숫자 또는 시간형 열을 사용합니다. chartTypetable인 경우에만 빈 문자열일 수 있습니다. "hour"
yAxis 문자열 table 차트에 필수 y축에 사용할 잘린 숫자 결과 열 이름입니다. chartTypetable인 경우에만 빈 문자열일 수 있습니다. "errors"
groupBy 문자열 또는 null 아니요 차트를 여러 시리즈로 분할하는 데 사용되는 선택적인 잘린 결과 열 이름입니다. null를 사용하거나 그룹화하지 않으려면 생략하세요. "service"
queryId 문자열 또는 null 아니요 선택적으로 잘린 저장된 쿼리 ID입니다. API는 이를 문자열로 저장하고 그 모양을 검증하지 않습니다. "550e8400-e29b-41d4-a716-446655440000"
sourceUrl 문자열 또는 null 아니요 위젯 제목을 클릭하면 열리는 선택적 UI URL입니다. /team/acme/ops/draft/0?...와 같은 상대 앱 URL을 사용하는 것이 좋습니다. "/team/acme/ops/draft/0?tab=chart&chartType=Line+Chart&xAxis=hour&yAxis=errors"

참고:

  • 차트 대신 일반 결과 테이블을 원하는 경우 chartType: "table"를 사용하세요.
  • 대시보드 쿼리 위젯은 대시보드가 로드될 때 자동 실행되므로 읽기 전용 SQL만 허용됩니다.
  • table가 아닌 모든 차트의 경우 xAxisyAxisquerySql에서 반환된 실제 열과 일치해야 합니다.
  • Bar Chart의 경우 xAxis는 텍스트/범주형, 숫자 또는 시간형일 수 있습니다.
  • Scatter Plot, Line ChartStacked Area Chart의 경우 xAxis는 숫자 또는 시간 형식이어야 합니다.
  • table가 아닌 모든 차트의 경우 yAxis는 숫자여야 합니다.
  • 범주형 Bar Chart x축의 경우 위젯은 쿼리 결과 순서를 유지합니다. 막대 순서를 제어하려면 querySql에서 ORDER BY를 사용하세요.
  • sourceUrl를 생략하면 대시보드 UI는 가능한 경우 대체 초안 쿼리 URL을 파생합니다. 파생된 링크는 defaultQuery, tab, chartType, xAxis, yAxisgroupBy를 유지합니다.

예: 범주형 막대 차트 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"를 사용하세요.

필드 유형 필수 정확한 값 또는 형식
content 문자열 트리밍 후 비어 있지 않은 마크다운 콘텐츠. "Check [the latency recipe](/sql/api-latency-percentiles) before paging infra."

참고:

  • content는 마크다운을 지원합니다. 원시 HTML은 UI에서 렌더링되기 전에 이스케이프됩니다.
  • UI가 이 구성 요소 유형에 대한 마크다운 본문만 렌더링하더라도 위젯 title는 여전히 API에 필요합니다.

예:

{
  "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는 tableNameexplorerState에서 대체 탐색 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 아니요 집계할 잘린 열 또는 필드 경로입니다. count에는 null를 사용하세요. count가 아닌 집계의 경우 이는 기본 측정값이며 제공된 경우 자동 감지된 숫자 selectedColumns보다 우선합니다. null "latency_ms"
timeZone 문자열 또는 null 아니요 UTC 또는 America/Los_Angeles 또는 Europe/Berlin와 같은 IANA 시간대 식별자를 사용합니다. API는 현재 비어 있지 않은 문자열을 자르고 저장하지만 나중에 위젯 쿼리가 실행될 때 잘못된 시간대 이름이 실패할 수 있습니다. 생략하면 저장된 구성은 null를 유지하고 UI는 상황에 따라 클라이언트 시간대 또는 UTC로 대체됩니다. null "America/Los_Angeles"
timePreset 문자열 지원되는 값은 1h, 6h, 24h, 7d, 30d, 90d, custom입니다. API는 ​​현재 비어 있지 않은 문자열을 허용하지만 해당 값만 UI 및 SQL 생성기에서 지원됩니다. "7d" "7d"
customStart 문자열 아니요 timePresetcustom일 때 사용됩니다. 권장 형식: 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 배열 필터 그룹 배열. 각 그룹은 내부적으로 AND로 연결됩니다. 여러 그룹이 함께 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 상대 범위 대신 customStartcustomEnd를 사용하세요.

문서화되지 않은 timePreset를 보내는 경우 현재 SQL 생성기는 7일 동작으로 돌아갑니다. 위의 값을 지원되는 계약으로 취급하십시오.

granularity: "auto" 동작

granularityauto이면 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 배열 그룹의 필터 조건 배열입니다. 유효한 조건이 0인 그룹은 삭제됩니다. [{ "field": "queue_name", "operator": "=", "value": "email" }]

conditions의 각 항목은 다음을 지원합니다.

필드 유형 필수 정확한 값 또는 형식
field 문자열 비어 있지 않은 잘린 필드 경로입니다. attributes.queue_name와 같은 점으로 중첩된 JSON 경로가 지원됩니다. 빈 경로 세그먼트는 허용되지 않습니다. "latency_ms"
operator 문자열 API에 의해 검증된 정확한 열거형: =, !=, >, >=, <, <=, LIKE, NOT LIKE, IS NULL, IS NOT NULL. ">"
value 문자열, 숫자, 부울 또는 null 보통 정규화 중에 문자열로 저장됩니다. IS NULLIS 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 테이블을 가정합니다.

  • city
  • price
  • wait_time_minutes
  • status
  • user_id
  • timestamp_utc

예: 두 개의 일반적인 탐색 위젯이 포함된 대시보드 만들기

이 예에는 다음이 포함됩니다.

  • 도시별 탑승 수익을 합산하고 수익별로 내림차순으로 정렬하는 테이블 위젯
  • 도시별 평균 대기 시간을 그룹화된 선으로 차트로 표시하는 시계열 위젯
{
  "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"는 시간축을 시간순으로 유지합니다.

예: 코호트 유지 미소 곡선에 대한 쿼리 위젯 만들기

집단 유지는 Explore에서 표현하기가 훨씬 어렵기 때문에 이 예에서는 쿼리 위젯을 사용합니다. 다음을 사용합니다:

  • 첫 탑승 코호트 정의
  • 뚜렷한 주간 활동 표
  • 코호트 규모와 유지된 라이더 간의 결합

읽기 가능한 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 키는 사용자가 아니기 때문에 API가 생성한 대시보드의 경우 created_bynull입니다.
  • created_by_api_key_id는 키 생성을 위한 내부 team_api_keys.id 행입니다.
  • UI를 통해 생성된 대시보드는 여전히 사용자 ID와 함께 created_by를 사용하고 일반적으로 created_by_api_key_idnull로 유지합니다.

팀에 정규화된 슬러그가 이미 존재하는 경우 API는 409 Conflict를 반환합니다.

기타 일반적인 오류:

  • 필수 필드가 누락되었거나 유효하지 않은 경우 400 Bad Request
  • 쿼리 위젯에 읽기 전용이 아닌 SQL이 포함된 경우 400 Bad Request
  • 팀에 대한 대상 대시보드가 없는 경우 404 Not Found
  • API 키가 없거나 잘못된 경우 401 Unauthorized
  • API 키에 read 범위만 있는 경우 400 Bad Request

관련 기능

검증된 쿼리를 집중적이고 검토 가능한 운영 보기로 전환합니다.

페이지 작성자 및 참고 자료

이 설명은 Telemetry 편집팀의 소유입니다. 제품 팀은 동작, 예시, 경계를 검토합니다.

문서 검토 방법