본문으로 건너뛰기
문서 메뉴서버 API

서버

서버 API

서버 API로 대화 목록을 가져오고, 답장하고, 상태를 바꾸고, 대화를 이슈로 만들 수 있어요. 자체 관리자 화면에 상담 기능을 붙일 때 쓰세요.

인증

모든 요청에 Authorization: Bearer ent_sk_…를 붙여요. 시크릿 키는 서버끼리만 쓰고, 브라우저나 앱에 넣지 마세요. 키는 발급된 채널에만 쓸 수 있어요. 다른 채널의 channelId로는 어떤 데이터도 읽거나 바꿀 수 없어요.

우리 서비스의 상담원이 답하는 경우, 누가 답했는지 X-Entropy-Operator 헤더로 알려 주세요. 값은 { id, name, avatarUrl } JSON을 base64url로 인코딩한 문자열이에요. 엔트로피 안에서 답하는 운영자는 엔트로피 로그인 세션을 쓰고, 메신저 권한이 있는 조직 멤버여야 해요.

X-Entropy-Operator 만들기 (Node.js)
const operator = { id: 'op_7', name: '상담원', avatarUrl: 'https://example.com/a/7.png' };
const header = Buffer.from(JSON.stringify(operator)).toString('base64url');

엔드포인트

운영자 API 엔드포인트
요청설명
GET /v1/channels/:channelId/conversations대화 목록. state, assignee, kind, q, cursor로 걸러요.
GET /v1/channels/:channelId/conversations/:id대화 한 건과 연락처 정보
GET /v1/channels/:channelId/conversations/:id/messages메시지 목록(운영자 메모 포함)
POST /v1/channels/:channelId/conversations/:id/messages{ body, attachmentIds?, internal? }로 답장하거나 메모를 남겨요.
PATCH /v1/channels/:channelId/conversations/:id{ state?, assignee?, tags?, kind? } — 종료, 보류, 담당자 지정
POST /v1/channels/:channelId/conversations/:id/read운영자 쪽 읽음 처리
GET /v1/channels/:channelId/contacts/:id연락처 조회
PATCH /v1/channels/:channelId/contacts/:id{ externalMemberId? } — 우리 회원과 잇기
POST /v1/channels/:channelId/conversations/:id/issue{ title?, projectId? } — 엔트로피 이슈를 만들고 대화와 이어요.
GET /v1/channels/:channelId/stream운영자용 실시간 이벤트(SSE)
GET /v1/channels/:channelId/stats채널 통계
POST /v1/channels/:channelId/contacts/erase{ externalMemberId } — 탈퇴한 회원의 연락처와 상담 기록을 모두 지워요.

예제

cURL
# 열린 대화 목록
curl https://entropy.ly/api/v1/channels/$CHANNEL_ID/conversations?state=open \
  -H "Authorization: Bearer $ENTROPY_SECRET_KEY" \
  -H "X-Entropy-Operator: $(printf '{"id":"op_7","name":"상담원"}' | base64 | tr '+/' '-_' | tr -d '=')"

# 답장 보내기 (internal: true면 고객에게 보이지 않는 메모)
curl -X POST https://entropy.ly/api/v1/channels/$CHANNEL_ID/conversations/$CONVERSATION_ID/messages \
  -H "Authorization: Bearer $ENTROPY_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"body":"확인해 보고 바로 알려 드릴게요."}'

대화 목록 응답

응답
{
  "items": [
    {
      "id": "cv_01J8Z3K6W2",
      "channelId": "ch_01J…",
      "contactId": "ct_01J…",
      "kind": "support",
      "state": "open",
      "assignee": {
        "type": "external",
        "id": "op_7",
        "name": "상담원",
        "avatarUrl": null
      },
      "tags": [
        "결제"
      ],
      "lastMessage": "영수증을 다시 받을 수 있을까요?",
      "lastMessageAt": "2026-10-27T08:59:40Z",
      "unreadForContact": 0,
      "unreadForOperator": 1,
      "linkedIssueId": null,
      "createdAt": "2026-10-27T08:58:02Z"
    }
  ],
  "nextCursor": "eyJ0IjoiMjAyNi0xMC0yN1QwODo1ODowMloifQ"
}

페이지 나누기

목록 응답은 { items, nextCursor } 형태예요. 다음 페이지는 nextCursor를 cursor로 넘겨서 받아요. nextCursor가 null이면 마지막 페이지예요. 커서는 그대로 전달만 하고 해석하지 마세요.

대화를 이슈로 만들기

요청
POST /v1/channels/:channelId/conversations/cv_01J8Z3K6W2/issue
Content-Type: application/json

{
  "title": "영수증 재발급 버튼 추가",
  "projectId": "prj_01J…"
}

이슈가 만들어지면 대화의 linkedIssueId가 채워져요. 이슈 상태가 바뀌면 웹훅 feedback.status_changed가 가고, 고객에게 반영 소식을 전할 수 있어요.

탈퇴 회원 삭제

회원이 탈퇴하거나 계정을 지우면 서버에서 바로 호출하세요. 그 회원과 이어진 연락처의 이름·이메일·휴대폰·동의 기록, 모든 대화와 메시지, 첨부 파일을 지우고 익명 집계 숫자만 남겨요. 시크릿 키로만 부를 수 있고, 다른 채널의 연락처는 지울 수 없어요.

요청
POST /v1/channels/:channelId/contacts/erase
Content-Type: application/json

{
  "externalMemberId": "user_2041"
}
응답
{
  "status": "erased",
  "contactId": "ct_01J…",
  "erasedAt": "2026-11-04T05:00:00Z",
  "counts": {
    "conversations": 2,
    "messages": 17,
    "attachments": 1
  }
}
  • erased(200) — 지금 지웠어요. not_found(200) — 남은 기록이 없어요. 여러 번 불러도 결과가 같으니 재시도해도 안전해요.
  • pending(202) — 접근은 바로 막았고 삭제는 백그라운드에서 마저 끝내요. held(202) — 법적 보존 요청으로 보관 중이라 해제되면 지워요. 둘 다 다시 부를 필요 없어요.
  • dry_run(202, dryRun: true) — 엔트로피가 시험 모드라서 아무것도 지우지 않고 지울 대상만 기록했어요. 이것도 다시 부를 필요 없어요.
  • 5xx·429·네트워크 오류일 때만 간격을 두고 다시 시도하세요. 이 호출 때문에 탈퇴 처리를 막지는 마세요.
  • 지운 뒤에는 웹훅 contact.erased가 가요. 대화는 채널의 보관 기간(기본 3년)이 지나도 자동으로 지워져요.

실시간 이벤트

GET /v1/channels/:channelId/stream은 Server-Sent Events로 채널의 message.created, conversation.updated, typing, read를 보내요. 25초마다 하트비트가 와요. 연결이 끊기면 다시 연결하고, 그동안 놓친 변경은 목록 API로 다시 가져오세요.