고객센터

블로그 팩토리 · CS 연동 · v1

VOC 수집 API 문서

blogfactory.kr 에 접수되는 고객 문의(VOC)와 앱 자동 진단(버그 리포트)을 외부 CS 시스템이 읽고 답변을 다는 API 입니다. 관리자가 발급한 키로만 호출할 수 있습니다. 읽기 권한이 기본이고, 관리자가 답변 권한을 허용한 키는 문의에 답변을 달고 상태를 바꿀 수 있습니다.

기준 주소
https://blogfactory.kr
인증 헤더
x-voc-api-key: <키>
호출 제한
키당 분당 120회 · 페이지 최대 100건
권한
voc:read (읽기) · voc:write (답변 등록·상태 변경)

1. 인증

모든 요청에 발급받은 키를 헤더로 보냅니다. x-voc-api-key 가 기본이고 Authorization: Bearer <키> 도 같은 뜻으로 받습니다. 키는 bfvoc_ 로 시작하는 54자 문자열이며 서버에는 해시만 저장되므로, 분실하면 관리자에게 폐기·재발급을 요청해야 합니다.

연동을 시작할 때 키 확인부터 합니다.

curl -H "x-voc-api-key: $VOC_KEY" https://blogfactory.kr/api/v1/voc/me
# {"key":{"id":"…","name":"CS팀 개발 관리자","scopes":["voc:read"]},
#  "server_time":"2026-09-17T10:20:00.000Z","endpoints":[…]}
키는 서버 간 통신에만 씁니다. 브라우저·모바일 앱·공개 저장소·로그·티켓 본문에 넣지 마세요. 유출이 의심되면 즉시 관리자에게 알려 폐기하고 새 키를 받습니다. 폐기·만료된 키는 401 을 받습니다.

2. 엔드포인트

GET/api/v1/voc/threads문의 목록

공개·비공개 문의와 자동 버그 리포트를 모두 돌려주며, 관리자 화면과 같은 범위입니다.

파라미터설명기본
statusopen(답변 대기) · answered(답변 완료) · closed(종료)전체
category제품 · 결제 · 기술 · 체험판 · 기타 · 자동 버그 리포트 (URL 인코딩 필수)전체
sincelast_message_at >= since. ISO 8601, 예 2026-09-01T00:00:00Z없음
untillast_message_at < until없음
orderasc · desc. last_message_at 기준, 같은 시각은 id 오름차순desc
page / page_size1부터 시작, 페이지 크기 1~1001 / 50
includediagnostics 를 넣으면 자동 버그 리포트 행에 진단 요약(diagnostic)을 함께 붙입니다없음
curl -G -H "x-voc-api-key: $VOC_KEY" "https://blogfactory.kr/api/v1/voc/threads" \
  --data-urlencode "since=2026-09-01T00:00:00Z" \
  --data-urlencode "order=asc" \
  --data-urlencode "page_size=100" \
  --data-urlencode "include=diagnostics"
{
  "threads": [
    {
      "id": "8f4c2a1e-5b7d-4c3e-9a1f-2d6b8e0c4a71",
      "kind": "inquiry",
      "category": "기술",
      "title": "네이버 발행 시 주제 선택",
      "status": "answered",
      "author_name": "홍길동",
      "has_account": true,
      "is_public": true,
      "is_faq": false,
      "message_count": 2,
      "last_message_at": "2026-09-17T06:34:10.123Z",
      "created_at": "2026-09-16T23:01:00.000Z"
    },
    {
      "id": "c5b36e87-1a2b-4c3d-8e9f-0a1b2c3d4e5f",
      "kind": "bug_report",
      "category": "자동 버그 리포트",
      "title": "네이버 사진 업로드 실패",
      "status": "open",
      "author_name": "앱 자동 접수",
      "has_account": false,
      "is_public": false,
      "is_faq": false,
      "message_count": 1,
      "last_message_at": "2026-09-17T02:10:44.000Z",
      "created_at": "2026-09-17T02:10:44.000Z",
      "diagnostic": {
        "diagnostic_kind": "publishing",
        "error_code": "NAVER_IMAGE_SESSION_HTTP_400",
        "feature": "writing.publish",
        "surface": "step3",
        "failure_stage": "upload",
        "action": "publish",
        "error_message": "확정 이미지 전부를 업로드하지 못했습니다 …",
        "app_version": "1.0.99",
        "release_channel": "prod",
        "os_name": "Windows",
        "ai_provider": "",
        "ai_model": "",
        "license_mask": "••••-7235",
        "user_comment": "",
        "occurrence_count": 3,
        "first_seen_at": "2026-09-16T22:00:00.000Z",
        "last_seen_at": "2026-09-17T02:10:44.000Z",
        "expires_at": "2026-10-17T02:10:44.000Z",
        "image_count": 2
      }
    }
  ],
  "page": 1,
  "page_size": 100,
  "total": 137,
  "total_pages": 2,
  "next_page": 2
}
GET/api/v1/voc/threads/{id}문의 상세

스레드, 메시지 전체, 작성자 이메일, 그리고 자동 버그 리포트라면 진단 상세와 캡처 이미지 URL 을 돌려줍니다.

{
  "thread": { "… 목록과 같은 필드 …" },
  "author_email": "user@example.com",
  "messages": [
    { "id": "…", "author_role": "user",  "author_name": "홍길동",
      "body": "마크다운 본문", "attachments": [{ "type": "image", "url": "https://…" }],
      "created_at": "2026-09-16T23:01:00.000Z" },
    { "id": "…", "author_role": "admin", "author_name": "블로그팩토리",
      "body": "답변 본문", "attachments": [], "created_at": "2026-09-17T06:34:10.123Z" }
  ],
  "diagnostic": {
    "… 목록 요약 필드 …",
    "context_snapshot": { "channel": "naver", "failure_code": "…" },
    "log_excerpt": ["[발행로그] …", "[이미지진단] …"]
  },
  "diagnostic_images": [{ "url": "https://…signed…", "expires_in": 3600 }]
}
  • author_email 은 로그인 회원이 남긴 문의에만 값이 있습니다. 자동 버그 리포트는 항상 빈 문자열이고, 대신 diagnostic.license_mask(라이선스 끝 4자)로 고객을 식별합니다.
  • diagnostic 과 diagnostic_images 는 kind = "bug_report" 일 때만 채워집니다. 이미지 URL 은 1시간 뒤 만료되므로 필요하면 그때 내려받습니다.
  • body 는 마크다운 원문입니다(HTML 아님). 문의 id 는 UUID 이며 다른 형식은 400 입니다.
GET/api/v1/voc/me키 확인

키 이름·권한·서버 시각·엔드포인트 목록을 돌려줍니다. 배포 뒤 헬스체크로 써도 됩니다.

POST/api/v1/voc/threads/{id}/replies답변 등록 · 권한 voc:write

관리자 화면에서 답변을 다는 것과 같은 효과입니다. 관리자 메시지로 저장되고 문의 상태가 answered 로 바뀌며, 로그인 회원의 문의면 고객에게 답변 알림 메일이 갑니다(응답의 mailed).

본문 필드설명기본
body답변 본문(마크다운, 5,000자 이내). 필수 — 비어 있으면 첨부가 있어도 400—
author_name고객에게 보이는 답변자 이름(40자 이내)블로그팩토리
attachments[{ type: "image" | "youtube", url }] 최대 10개, https 만[]
closetrue 면 답변과 함께 문의를 종료(closed)false
curl -X POST -H "x-voc-api-key: $VOC_KEY" -H "Content-Type: application/json" \
  "https://blogfactory.kr/api/v1/voc/threads/8f4c2a1e-5b7d-4c3e-9a1f-2d6b8e0c4a71/replies" \
  -d '{
    "body": "안녕하세요, 확인해 보니 설정 → 계정설정 → 네이버 블로그에서 연결 테스트를 다시 해 주시면 됩니다.",
    "author_name": "블로그팩토리 고객센터",
    "attachments": [{ "type": "image", "url": "https://example.com/guide.png" }],
    "close": false
  }'
{
  "message": { "id": "…", "author_role": "admin", "author_name": "블로그팩토리 고객센터",
               "body": "안녕하세요, …", "attachments": [{ "type": "image", "url": "https://example.com/guide.png" }],
               "created_at": "2026-09-17T11:02:10.000Z" },
  "thread": { "id": "8f4c2a1e-…", "kind": "inquiry", "status": "answered", "message_count": 3, "…": "…" },
  "mailed": true
}
PATCH/api/v1/voc/threads/{id}상태 변경 · 권한 voc:write

본문 { "status": "open" | "answered" | "closed" }. 답변 없이 상태만 바꿀 때 씁니다(예: 처리 완료 후 종료). 공개 여부·FAQ 는 바꿀 수 없습니다.

curl -X PATCH -H "x-voc-api-key: $VOC_KEY" -H "Content-Type: application/json" \
  "https://blogfactory.kr/api/v1/voc/threads/8f4c2a1e-5b7d-4c3e-9a1f-2d6b8e0c4a71" -d '{ "status": "closed" }'
# { "thread": { "id": "8f4c2a1e-…", "status": "closed", "…": "…" } }

3. 응답 필드

thread

kind
inquiry(사람이 남긴 문의) 또는 bug_report(앱 자동 진단)
status
open 답변 대기 · answered 답변 완료 · closed 종료
has_account
로그인 회원의 문의인지. true 면 상세에서 author_email 을 받을 수 있습니다
is_public / is_faq
공개 게시판 노출 여부 / 대표 질문(FAQ) 지정 여부
message_count / last_message_at
메시지 수와 마지막 메시지 시각. 증분 동기화의 기준입니다

diagnostic (자동 버그 리포트)

오류 코드·기능·단계·메시지·앱 버전·채널·OS·AI 공급자/모델·라이선스 마스킹·사용자 코멘트·발생 횟수·최초/최근 발생·만료 시각·이미지 수. 상세 응답에는 context_snapshot(진단 문맥, 비밀값 제거됨)과 log_excerpt(로그 발췌, 최대 200줄)가 추가됩니다.

내보내지 않는 것 — 내부 라이선스 id, 기기 지문, 클러스터 서명, 원문 프롬프트, 작성 상태 JSON, 이미지 메타데이터와 저장 경로. 업무상 필요하면 관리자에게 별도로 요청하세요.

4. 증분 동기화 권장 방식

  1. 마지막으로 성공한 동기화 시각 T 를 저장해 둡니다(처음엔 충분히 과거).
  2. since = T − 5분, order=asc, page_size=100, include=diagnostics 로 next_page 가 null 이 될 때까지 넘깁니다. 같은 id 는 최신 값으로 덮어씁니다(멱등).
  3. 메시지·진단 문맥이 필요한 스레드는 message_count 나 last_message_at 이 바뀐 것만 상세로 다시 읽습니다.
  4. 응답에서 가장 큰 last_message_at 을 새 T 로 저장합니다.

자동 진단은 접수 뒤 30일이 지나면 서버에서 지워집니다(diagnostic.expires_at). 오래 보관하려면 그 전에 가져가세요.

5. 오류

코드뜻조치
400파라미터 오류. 본문 error 에 이유가 있습니다요청을 수정합니다
401키 없음 · 형식 오류 · 폐기 · 만료관리자에게 키 확인 또는 재발급을 요청합니다
403권한 범위 밖(읽기 키로 답변 등록·상태 변경 호출)관리자에게 답변 권한(voc:write) 부여를 요청합니다
404없는 문의 id—
429분당 120회 초과잠시 뒤 재시도(지수 백오프)
500서버 오류잠시 뒤 재시도. 반복되면 시각과 요청 URL 을 관리자에게 전달합니다

오류 응답은 항상 {"error": "사람이 읽을 수 있는 이유"} 형태입니다.

6. 운영 정보

  • 키 발급·폐기·만료·권한(읽기 / 읽기+답변) 설정은 블로그 팩토리 관리자가 합니다. 키마다 발급자와 마지막 사용 시각이 기록됩니다.
  • 답변 등록은 고객에게 바로 보이고 알림 메일이 나가므로, 연동 테스트는 반드시 관리자와 합의한 테스트 문의에서만 하세요.
  • 호출 제한은 키 단위 분당 120회입니다. 대량 초기 적재는 page_size=100 으로 페이지를 넘기면 분당 최대 12,000건까지 읽을 수 있습니다.
  • 응답은 모두 JSON(UTF-8)이며 시각은 ISO 8601 UTC 입니다. 한글 파라미터는 반드시 URL 인코딩해 보냅니다.
  • 키 발급이나 범위 확장이 필요하면 고객센터로 문의하세요.

문서 버전 2026-09-17 (답변 등록·상태 변경 추가) · API 버전 v1