API
엔드포인트
데이터 라우트는 전부 GET, 읽기 전용, ClickHouse 쿼리 하나가 뒤에 있습니다.
공개 base URL은 없습니다 — Basic Auth 뒤의 배포 도메인이나 로컬
http://localhost:8080으로 접근합니다.
공통 쿼리 파라미터
아래 파라미터는 모든 데이터 라우트가 받습니다(POST /api/chat만 JSON 본문을
받는 예외).
| 파라미터 | 타입 | 설명 |
|---|---|---|
from |
ISO 8601 | 범위 시작. 기본값 to - 2일(워크샵 기본). uniq/존재 여부 계열
엔드포인트는 서버에서 시각을 시간 단위로 내림하므로 좁은(1시간 미만) 범위에서는
최대 59분이 더 포함될 수 있습니다 — rollup 그레인과의 의도된 트레이드오프. |
to | ISO 8601 | 범위 끝. 기본값 now |
group |
bedrock | enterprise |
세션 그룹 필터. 그룹 스코프 쿼리는 unknown을 기본 제외하고,
조직 전체 합계를 보는 몇몇 엔드포인트는 포함합니다. |
user | string | 이메일 부분 일치 필터 |
model | string | 모델명 부분 일치(정규화 후) 필터 |
intervalHours |
number | 시계열 버킷 크기. 0.25=15분(차트 드래그 줌), 1=시간,
24=일, 168=주. 1 미만은 범위가 4시간을
넘으면 서버에서 1로 클램프됩니다(분 버킷은 원본 테이블을 스캔). |
email |
string | 유저 드릴다운 3개 라우트 전용(정확 일치). 다른 라우트는 무시합니다. |
Overview · Adoption
| Path | 반환 |
|---|---|
GET /api/overview/kpi | 그룹별 세션·유저·커밋·PR·토큰·LOC 요약 |
GET /api/overview/active-users | 그룹 무관 고유 활성 유저 수(unknown 포함) |
GET /api/overview/tokens-timeseries | 시계열 — 그룹별 토큰 사용량 |
GET /api/overview/cache-efficiency | 캐시 재사용률 + 토큰 타입 분해 |
GET /api/overview/model-distribution | 그룹 × 모델 토큰 분포 |
GET /api/adoption/levels | DAU/WAU/MAU 스냅샷 + 전체 멤버 |
GET /api/adoption/timeseries | 시계열 — 일별 DAU/WAU/MAU 롤링 |
Productivity · Usage
| Path | 반환 |
|---|---|
GET /api/productivity/normalized | 백만 토큰당 LOC/커밋 |
GET /api/productivity/decisions | 그룹별 수락/거절 수 |
GET /api/productivity/decisions-by-tool | 그룹 × 툴 수락/거절 |
GET /api/productivity/active-time | 시계열 — 활성 시간(초) |
GET /api/productivity/agenticness | 시계열 — 프롬프트당 툴 호출 수 |
GET /api/productivity/engagement | 시계열 — 일별 유저/세션/PR |
GET /api/productivity/loc-timeseries | 시계열 — 추가/삭제 라인 |
GET /api/usage/tool-mcp | 툴 · MCP 호출 수 |
GET /api/usage/skills | 스킬 호출 수(OTel 리댁션 영향 받음) |
GET /api/usage/connectors | MCP 커넥터 사용량 |
Users
| Path | 반환 |
|---|---|
GET /api/users/leaderboard |
유저 × 그룹 지표 + 생산성 점수. 두 그룹에 걸친 유저는 그룹당 1행이고,
user_active_days는 그룹 무관 값이라 조직 전체 점수를 다시 계산할 때
활성일이 이중 계산되지 않습니다. |
GET /api/users/tools | 유저 × 그룹 툴 사용량 |
GET /api/users/skills | 유저 × 그룹 스킬 사용량 |
GET /api/users/cost-efficiency | 유저 × 그룹 $/LOC, $/commit |
GET /api/users/daily | 시계열 — 한 유저의 일별 세션/LOC/토큰/커밋. email 필수 |
GET /api/users/decisions-by-tool | 한 유저의 툴별 수락/거절. email 필수 |
GET /api/users/heatmap | 최근 91일 일별 세션 히트맵. email 필수, from 무시 |
Cost
| Path | 반환 |
|---|---|
GET /api/cost/summary | 그룹별 계산 비용 + 보고 비용, 토큰 분해 |
GET /api/cost/by-model | 그룹 × 모델 비용·토큰 |
GET /api/cost/by-user-model | 유저 × 그룹 × 모델 비용·토큰 |
GET /api/cost/by-model-daily | 시계열 — 그룹 × 모델 일별 비용 |
GET /api/cost/by-model-compare | 직전 동일 길이 기간과의 모델별 비교 |
GET /api/cost/tiers | 토큰 티어별(uncachedInput/cacheRead/cacheWrite/output) 비용, 그룹 분리 |
계산 비용 vs 보고 비용. 화면의 기본값은 토큰 실측 × 모델 단가로 계산한
값입니다. Claude Code가 자체 보고하는 cost.usage는 근사치라 A/B 비교의
기준으로 쓰지 않고, 참고용으로 나란히 보여줍니다.
Chat · Config
| Path | 반환 |
|---|---|
POST /api/chat |
SSE 스트림. 본문 {"messages":[{"role","content"}]}. Bedrock
ConverseStream + 읽기 전용 SQL 툴콜 루프(최대 4 hop). LLM이 만든 SQL은
sanitizeSql() 샌드박스를 통과해야 하고, 결과는 200행으로 잘립니다. |
GET /api/config |
{"piiMask": bool} — 프론트가 이메일을 마스킹할지. 이미지는 한 번
빌드해 여러 배포에서 재사용하므로 빌드타임 플래그가 아니라 런타임 값입니다.
프론트는 fail-closed(오류·타임아웃이면 마스킹). |
GET /healthz | Basic Auth 면제. ClickHouse ping 결과 포함 |
마스킹은 표시 계층에만 적용됩니다 — 데이터 엔드포인트는 항상 원본 이메일을 반환하므로, Basic Auth를 통과한 사람은 네트워크 탭에서 볼 수 있습니다. 화면 공유나 공개 URL을 가리는 장치이고, 데이터 자체의 접근 제어가 아닙니다.
오류 · 레이트 리밋
401— Basic Auth 누락/불일치 (BASIC_AUTH_*가 설정된 경우에만)500— 대개 ClickHouse 쿼리 오류. 응답은{"error": "..."}, 원문 스택은 서버 로그에만 남습니다429—POST /api/chat의 IP당 분당 상한(단일 파드 in-memory)
데이터 라우트에는 애플리케이션 레벨 레이트 리밋이 없습니다. 워크샵 소규모 코호트를 전제한 결정이며, 전제가 바뀌면 이 문장을 지우기 전에 리밋을 먼저 넣어야 합니다.