Skip to content

문서 vs 실제 검증 노트 ​

공식 문서와 실제 API 응답의 불일치(확정·의심)를 기록한다. 각 항목은 검증 하니스(#14, scripts/verify/*)로 실측 후 상태를 갱신하며, 타입은 실제 응답을 우선한다.

상태 범례: 🔴 미검증(의심) · 🟡 검증 보류(자격증명/조건 필요) · 🟢 검증 완료

문서 vs 실제 대조표 ​

#상태대상문서기존 구현 관측판단·조치
1🟡토큰 폐기 경로POST /auth/v1/token/revokePOST /auth/v1/revoke 호출 (동작했던 것으로 추정)SDK(#5)는 문서 경로로 구현 (AuthClient.revokeToken). 실자격 검증은 보류 — 하니스(#14)에서 두 경로 실호출 확인 후 확정
2🟢토큰 응답 expiresInType: String ("86400")타입도 string으로 정의됨실측(2026-07-22, pnpm verify:token): 실제는 number(86400) — 문서가 틀림. 토큰 엔드포인트도 공통 envelope {code,message,content} 사용 확인. SDK는 양쪽 수용 유지
3🟡토큰 발급 응답 scope발급(authorization_code) 응답엔 없음, 갱신(refresh) 응답엔 있음기존 타입엔 항상 있음갱신 응답 scope 존재 실측 확인(2026-07-22) — 공백 구분 스코프명 나열 문자열 (예: "채널 정보 조회 채팅 메시지 쓰기 …"). 발급 응답은 다음 로그인 시 확인. SDK는 optional 유지
4🟢세션 목록 disconnectedDatedisconnectedDate (정상 철자)disconnedtedDate (오타)로 타입 정의실측(2026-07-22): 끊긴 세션에서 disconnectedDate(정상 철자) 확인 — 기존 타입의 오타였음. 연결 중 세션에는 필드 자체가 없음 → SDK 타입 optional 처리 예정(#13)
5🟢(문서상)세션 이벤트 타입CHAT|DONATION|SUBSCRIPTIONCHAT|DONATION만 정의 (SUBSCRIPTION 누락)SDK는 3종 전부 + subscribe/unsubscribe/subscription 포함. 실측으로 재확인
6🟢CHAT 이벤트 userRoleCode, chatChannelId존재 (2025.07 / 2026.03 추가)타입에 둘 다 없음 (구버전)실측(2026-07-22, CHAT 이벤트 수신): chatChannelId(짧은 코드, 예 "N2dODq") 존재. userRoleCode는 존재하나 위치가 문서와 다름 — #27 참조. getChatRole 뱃지 추론은 userRoleCode로 대체 가능
7🟢CHAT profile.badgesType Object[]만 표기, 필드 구성 미기술{ imageUrl: string }[] 실측실측(2026-07-22): [{ imageUrl: string }] 확정 — 문서 공백을 실측으로 채움. Normalize(#16) 타입에 반영
8🟢CHAT/DONATION emojisType Map (key: 식별자, value: URL){ [key: string]: string }[] — 배열로 정의(모순)실측(2026-07-22): plain object(Record<string,string>) 확정 (빈 채팅은 {}) — 기존 배열 타입 정의가 오류
9🔴DONATION payAmountType Stringstring문자열 맞는지 실측. 정규화 계층에서 number 파생 필드 제공 검토
10🟢이벤트 구독/취소 sessionKey 전달 위치"Request Param" (쿼리)쿼리 파라미터로 전송 (동작 확인됨)실측(2026-07-22): POST + 쿼리 sessionKey 동작 확인. SYSTEM(subscribed) 통지 형식도 문서 일치
11🟢채팅 설정 응답 필드명allowSubscriberInFollowerModeallowSubscriberFollowerMode (In 없음)실측(2026-07-22): allowSubscriberInFollowerMode — 문서가 정확, 기존 타입이 오타였음. SDK 타입(#10)은 문서 표기 채택
12🟢채팅 설정 응답 누락 필드chatSlowModeSec, chatEmojiMode 존재타입에 없음 (2025.07 이전 작성)실측(2026-07-22): chatSlowModeSec(number)·chatEmojiMode(boolean) 존재 확인. SDK 타입(#10)에 포함
13🟢minFollowerMinute 허용 값0~259200의 13개 값 (2025.12 확장)0~43200의 8개 값실측(2026-07-22): 허용 외 값(7) PUT 시 서버가 HTTP 400 + "minFollowerMinute 값이 올바르지 않습니다."로 거부. 문서 제약이 실서버에서도 강제됨 — SDK 사전 검증과 이중 안전망
14🟢채널 정보 verifiedMark존재 (2025.07 추가)타입에 없음실측(2026-07-22): boolean으로 존재 확인. SDK 타입(#7 Channel)에 포함
15🟢세션 목록 page 파라미터 타입String 표기 ("0부터 조회")number로 사용실측(2026-07-22): number로 전송해 정상 동작. Int로 확정
16🟢활동 제한 목록 조회 파라미터 위치GET인데 "Request Body" 표기 (size, next)(기존 구현 없음)실측(2026-07-22): 쿼리 파라미터(size, next)로 정상 동작. 문서의 "Request Body" 표기가 오기
17🟢활동 제한 목록 응답 래핑data[]/page 래핑 표기 없음 (필드 나열만)(기존 구현 없음)실측(2026-07-22): { data: [...], page: { next } } 래핑 확인 — 문서 미기재 구조를 실측으로 확정
18🟡드롭스 조회 page.from/page.size 쿼리 직렬화중첩 Object로 표기(기존 구현 없음)page.from/page.size(dotted) vs flat 실측 필요. 스코프 없이 호출 시 403 "드롭스 스코프가 필요합니다."만 반환(2026-07-22 실측) — 파라미터 검증 이전에 차단되어 판별 불가. SDK(#11)는 문서 중첩 표기(dotted) 채택, 스코프 확보 시 verify가 자동 실검증
19🟡드롭스 지급 갱신 응답status enum 중 UNAUTHORIZED 오타 포함(기존 구현 없음)UNAUTHORIZED로 구현. 법인 자격 필요 → 검증 보류
20🟢팔로워/구독자/세션 목록 응답 페이지 메타data[] 외 메타 없음(부분 미구현)실측(2026-07-22): followers/subscribers·세션 목록 모두 page/totalCount/totalPages(number) 존재 — 문서 미기재. SDK 타입 optional 포함, 자동 순회는 totalPages로 조기 종료
21🔴429 Retry-After 헤더미기술(미구현)실측 후 재시도 로직(#4)에 반영. 헤더 없으면 지수 백오프만 사용
22🟢(문서상)SUBSCRIPTION 이벤트 month 설명"사용된구독 기간치지직 이모티콘 정보" — 문서 자체 오타—의미는 "구독 개월 수"(Int)로 확정. 구현 영향 없음
23🟢users/me 응답 nickname문서에 없음 (channelId, channelName만 기재)(기존 타입에 없음)실측(2026-07-22, pnpm verify): 실제 응답에 nickname(string) 존재. SDK 타입(#6 UserMe)에 포함 — 문서 공백을 실측으로 채움
24🟢categories/search 응답data[]: categoryType/categoryId/categoryValue/posterImageUrl—실측(2026-07-22, pnpm verify): 문서와 일치 (query=게임, 5건 수신, 초과 필드 없음)
25🟢streaming-roles userRole 값STREAMING_CHANNEL_OWNER 등 4종 enum(기존 구현 없음)실측(2026-07-22): 채널 소유자가 문서에 없는 STREAMER 값으로 내려옴 (소유자 본인도 목록에 포함). SDK는 known 5종 + string 확장 허용(StreamingRole)
26🟢Live 4종 (lives / streams/key / lives/setting GET·PATCH)문서 스키마(기존 관측과 대체로 일치)실측(2026-07-22, pnpm verify): 4종 모두 문서와 일치. lives page.next 커서 동작 확인, PATCH는 동일 제목 라운드트립으로 200 확인. streamKey는 32자 문자열(값 미출력)
27🟢CHAT 이벤트 userRoleCode 위치최상위 필드로 표기(기존 구현 타입에 없음)실측(2026-07-22): 실제로는 profile 객체 내부에 위치 (profile.userRoleCode: "streamer") — 문서와 구조 불일치. Normalize(#16)에서 흡수
28🟢CHAT 이벤트 eventSentAt문서에 없음(기존 구현 타입에 없음)실측(2026-07-22): 나노초 정밀 타임스탬프 문자열 존재 ("2026-07-22T22:48:28.525460090", 타임존 표기 없음). Normalize 타입에 optional 포함
29🟢채팅/세션과 라이브 상태의 관계미기술(기존 구현은 라이브 중에만 사용)실측(2026-07-22): chats/send·chats/settings·sessions/auth·이벤트 구독·CHAT 수신 모두 라이브 OFF 상태에서 정상 동작. 채팅 채널은 상시 존재
30🟡chats/blind-messagechatChannelId + messageTime + senderChannelId(기존 구현 없음)파라미터는 세션 CHAT 이벤트에서만 획득 가능 → 실측은 Transport(#15) 구현 후. SDK(#10)는 문서 스펙으로 구현
31🟢chats/notice 두 방식message(신규) 또는 messageId(기존)(기존 구현은 둘 다 전송하는 형태)실측(2026-07-22): 두 방식 모두 200 확인 — message 직접 등록, chats/send 후 해당 messageId로 등록 모두 동작
32🟢설정 변경의 실반영 (뮤테이션 라운드트립)——실측(2026-07-22): 방송 제목 PATCH·채팅 저속모드 PUT 모두 변경→재조회 반영→원복 확인. 쓰기 경로가 200만 반환하는 게 아니라 실제로 반영됨을 확정
33🟢(부분)활동 제한 추가/해제 성공 경로targetChannelId로 등록/해제(기존 구현 없음)실측(2026-07-22): 임시제한의 실효 = 대상에게 채팅 1분 제한 (작성자가 대상 계정으로 직접 확인 — UI에 1분 제한 표시, 기존 채팅 블라인드 처리). DELETE로 제한 중 조기 해제 가능(200). 관리자 계정은 등록 거부(400) — 관리자 보호. 일반 활동 제한 추가는 위즈봇 대상 400 "BAD_REQUEST" 지속(앱 연동 계정 보호 추정, 요청 형식은 유효 확인) — 무관 계정 확보 시 재검증
34🔴활동 제한 추가(POST /restrict-channels) 서버 동작targetChannelId body로 등록(기존 구현 없음)실측 진단(2026-07-22): body 누락/오필드명은 400 "잘못된 값을 입력했습니다."(파라미터 에러), 올바른 {targetChannelId} body는 존재하지 않는 ID·본인·일반 계정 모두 400 "BAD_REQUEST"(generic). 파라미터 검증은 통과하나 내부 로직에서 전부 거부 → 서버측 결함 또는 미문서 선행 조건 의심. SDK 구현은 문서·파라미터 검증 실측에 부합 — 치지직 개발자 문의 권장
35🟢클라이언트 세션 + 유저 토큰 구독 조합명시 없음 (세션 생성 주체별 설명만)기존 구현이 이 패턴 사용실측(2026-07-22): 클라이언트 인증으로 만든 세션에 유저 Access Token으로 subscribe/chat 성공, SYSTEM(subscribed)·unsubscribed 통지 수신. 다중 채널 봇 아키텍처의 표준 패턴 확정. 클라이언트 세션 목록에도 page/totalCount/totalPages 메타 존재

실시간 연결 관련 중요 참고 ​

  • socket.io-client 지원 버전이 1.0.0+ ~ 2.0.3 로 문서에 명시됨 (socket.io v2 = EIO=3 프로토콜).
  • 실측(2026-07-22) — 프로토콜/연결 흐름 전부 확인 완료:
    • 세션 URL 형식: https://ssioNN.nchat.naver.com + ?auth=<128자 토큰>
    • GET {origin}/socket.io/?EIO=3&transport=polling&auth=... 핸드셰이크 성공 → sid 발급, upgrades: ["websocket"]
    • 이후 폴링 GET만으로 40(네임스페이스 연결) → 42["SYSTEM","{...connected, sessionKey...}"] 수신
    • 구독(POST + 쿼리) 후 SYSTEM(subscribed) → 채팅 발생 시 42["CHAT","{...}"] 수신까지 순수 fetch로 재현됨
    • #15 확정: 의존성 0의 자체 EIO=3 클라이언트 구현. WebSocket(globalThis.WebSocket, Node 22+/브라우저) 우선 + 순수 fetch 롱폴링 폴백(Node 18~20). 두 전송 모두 실서버 e2e(연결→구독→CHAT 수신→종료) 통과(2026-07-22). socket.io-client@2는 구버전 의존성이라 배제
    • 세션 등록은 핸드셰이크 시점에 발생 (라이브 여부 무관). 미유지 시 ping 타임아웃(~85초)으로 서버가 종료 처리
    • 날짜 형식: 세션 목록의 connectedDate/disconnectedDate는 "2026-07-22 22:44:39" (공백 구분, 타임존 없음)
  • 소켓 이벤트 payload는 JSON 문자열로 전달됨 (JSON.parse 필요) — 기존 관측과 문서 예제 모두 일치.
  • 구독 성공 통지는 HTTP 응답이 아니라 세션의 SYSTEM(subscribed) 메시지로 온다. Transport는 이 메시지를 구독 완료 신호로 사용한다 (고정 지연(setTimeout) 방식이 불필요한 근거).
  • 세션 연결 상한: 클라이언트 세션 10개 / 유저 세션 3개 / 세션당 구독 30개 — SDK에서 초과 시 명확한 에러 안내.

검증 절차 (하니스 #14에서 표준화) ​

  1. 문서 스펙으로 요청/응답 zod 스키마(passthrough) 1차 정의
  2. 실제 자격증명으로 호출 → 스키마 파싱. 문서에 없는 필드 수신 시 경고 로그, 알려진 필드 누락 시 실패
  3. 불일치 발견 시 이 문서의 표를 갱신하고 타입은 실제 응답 기준으로 수정
  4. 자격증명·조건(법인 스코프 등) 미비로 호출 불가한 항목은 🟡 유지 + 코드에 문서 링크 주석

공식 OPEN API만 지원 — 비공식 엔드포인트 0건