Skip to main content

웹훅

웹훅을 사용하면 vox.ai 플랫폼과 외부 시스템 간에 실시간으로 데이터를 주고받을 수 있습니다. 에이전트 설정의 웹훅 섹션에서 두 종류의 웹훅을 각각 구성할 수 있습니다.
웹훅방향시점용도
인바운드 웹훅vox.ai → 외부 서버 → vox.ai통화 시작 직전통화 전 동적 변수 주입
통화 데이터 웹훅vox.ai → 외부 서버통화 시작 · 중간 이벤트 · 종료 · 분석 완료 시외부 시스템에 통화 이벤트 전송

인바운드 웹훅

인바운드 웹훅은 통화가 시작되기 직전 외부 시스템에 발신/수신 번호를 보내고, 응답으로 받은 키-값 쌍을 에이전트의 동적 변수로 주입합니다. 앞단 CRM에서 고객 정보를 조회해 에이전트 프롬프트에 바로 연결할 수 있습니다. 요청 (vox.ai → 외부 서버):
{ "call_from": "01012345678", "call_to": "0212345678" }
응답 (외부 서버 → vox.ai):
{
  "call_inbound": {
    "dynamic_variables": { "user_name": "홍길동" },
    "metadata": { "user_id": "17632" }
  }
}
endpoint 에서 호출자를 검증해야 하면 인바운드 웹훅 서명을 켜세요. 워크스페이스 웹훅과 같은 HMAC-SHA256 방식으로 서명됩니다 (기본 꺼짐) — 인바운드 웹훅 가이드의 보안 섹션을 참고하세요.

인바운드 웹훅 전체 가이드

웹훅 URL 설정, 타임아웃·재시도 정책, 서버 구현 예시 (Python/JS), HMAC 서명, 보안 권장 사항, SIP 헤더 보조 수단, 예외 상황까지 다룹니다.

통화 데이터 웹훅

통화 데이터 웹훅은 통화의 주요 이벤트가 발생할 때마다 외부 시스템으로 페이로드를 전송합니다. CRM 연동, 실시간 모니터링, 로그 수집, 통화 후 스크립트 저장 등에 활용합니다.
이 섹션은 v2를 기준으로 설명합니다. 새 연동은 v2로 구현하세요. v2는 통화 종료 이벤트와 분석 완료 이벤트를 분리합니다.

이벤트 유형

이벤트시점설명
call_started통화 시작통화가 연결된 직후 발생합니다.
mid_call통화 진행 중플로우 노드 전환(flow_transition)이나 개별 발화(call_message)가 발생할 때마다 전송됩니다.
call_ended통화 종료통화가 끝난 뒤 기본 통화 정보와 스크립트를 전송합니다.
call_analyzed분석 완료비용, 요약, 감정 분석, 통화 정보 추출 결과가 준비되면 전송합니다.

최상위 페이로드 구조

모든 이벤트는 공통으로 event 필드를 가집니다. v2는 webhook_version을 함께 보내고, 모든 이벤트를 call 객체 안에 담아 전송합니다.
{
  "event": "call_started | mid_call | call_ended | call_analyzed",
  "webhook_version": "v2",
  "call": {}
}
v1은 기존 수신 서버를 유지해야 하는 경우를 위한 형식입니다. call_started, call_endedcall 객체를 사용하고, mid_callmid_call 객체를 사용합니다.
{
  "event": "call_started | call_ended | mid_call",
  "call": {},
  "mid_call": {}
}

v2 페이로드 예시

아래 예시는 새 연동에서 구현해야 하는 v2 기준 페이로드입니다. call_ended는 통화 종료 데이터와 스크립트를 전송합니다. 비용과 분석 결과는 call_analyzed로 전송됩니다.

call_started

{
  "event": "call_started",
  "webhook_version": "v2",
  "call": {
    "call_id": "6b0f1f08-1c2b-4f0e-9c3a-0c1d9e6f5a82",
    "agent": {
      "agent_id": "a1f4c8d2-3e5b-4a7c-9d8e-2b1f6c4a9d3e",
      "agent_version": "v3"
    },
    "call_type": "inbound",
    "from_number": "01012345678",
    "to_number": "07012345678",
    "dynamic_variables": {
      "customer_name": "김철수"
    },
    "metadata": {
      "campaign": "봄_프로모션"
    },
    "start_at": 1775980200000,
    "opt_out_sensitive_data_storage": false
  }
}

mid_call

{
  "event": "mid_call",
  "webhook_version": "v2",
  "call": {
    "call_id": "6b0f1f08-1c2b-4f0e-9c3a-0c1d9e6f5a82",
    "agent": {
      "agent_id": "a1f4c8d2-3e5b-4a7c-9d8e-2b1f6c4a9d3e",
      "agent_version": "v3"
    },
    "occurred_at": 1775980380000,
    "event_type": "call_message",
    "event_data": {
      "role": "user",
      "content": "주문 번호는 ORD-2026-0042입니다."
    }
  }
}

call_ended

{
  "event": "call_ended",
  "webhook_version": "v2",
  "call": {
    "call_id": "6b0f1f08-1c2b-4f0e-9c3a-0c1d9e6f5a82",
    "agent": {
      "agent_id": "a1f4c8d2-3e5b-4a7c-9d8e-2b1f6c4a9d3e",
      "agent_version": "v3"
    },
    "call_type": "inbound",
    "from_number": "01012345678",
    "to_number": "07012345678",
    "dynamic_variables": {
      "customer_name": "김철수"
    },
    "metadata": {
      "campaign": "봄_프로모션"
    },
    "call_status": "ended",
    "disconnection_reason": "agent_hangup",
    "start_at": 1775980200000,
    "end_at": 1775980542000,
    "transcript": [
      { "role": "agent", "content": "안녕하세요, 무엇을 도와드릴까요?" },
      { "role": "user", "content": "주문 상태를 확인하고 싶습니다." }
    ],
    "recording_url": "https://www.tryvox.co/api/store/download/...",
    "opt_out_sensitive_data_storage": false
  }
}

call_analyzed

{
  "event": "call_analyzed",
  "webhook_version": "v2",
  "call": {
    "call_id": "6b0f1f08-1c2b-4f0e-9c3a-0c1d9e6f5a82",
    "agent": {
      "agent_id": "a1f4c8d2-3e5b-4a7c-9d8e-2b1f6c4a9d3e",
      "agent_version": "v3"
    },
    "call_type": "inbound",
    "from_number": "01012345678",
    "to_number": "07012345678",
    "dynamic_variables": {
      "customer_name": "김철수"
    },
    "metadata": {
      "campaign": "봄_프로모션"
    },
    "call_status": "ended",
    "disconnection_reason": "agent_hangup",
    "start_at": 1775980200000,
    "end_at": 1775980542000,
    "transcript": [
      { "role": "agent", "content": "안녕하세요, 무엇을 도와드릴까요?" },
      { "role": "user", "content": "주문 상태를 확인하고 싶습니다." }
    ],
    "recording_url": "https://www.tryvox.co/api/store/download/...",
    "call_cost": {
      "total_cost": 120
    },
    "call_analysis": {
      "summary": "고객이 주문 상태를 문의했고, 상담원이 배송 예정일을 안내했습니다.",
      "user_sentiment": "positive",
      "custom_analysis_data": [
        { "name": "inquiry_type", "value": "배송 상태 문의" },
        { "name": "resolved", "value": true }
      ]
    },
    "opt_out_sensitive_data_storage": false
  }
}
시간 필드는 모두 UNIX 타임스탬프 밀리초 단위입니다. v2에는 duration_ms가 없으므로 end_at - start_at으로 계산하세요. agent.agent_version은 특정 배포 버전이면 v3처럼 표시되고, 현재 설정으로 실행된 통화면 current입니다.
v1 예시는 기존 수신 서버와의 호환을 위해 제공합니다. 새 연동에서는 위의 v2 페이로드를 기준으로 구현하세요.

v1 call_started 페이로드

{
  "event": "call_started",
  "call": {
    "agent_id": "a1f4c8d2-3e5b-4a7c-9d8e-2b1f6c4a9d3e",
    "call_id": "6b0f1f08-1c2b-4f0e-9c3a-0c1d9e6f5a82",
    "call_type": "inbound",
    "call_from": "01012345678",
    "call_to": "07012345678",
    "dynamic_variables": {
      "customer_name": "김철수"
    },
    "metadata": {
      "campaign": "봄_프로모션"
    },
    "start_timestamp": 1775980200000,
    "opt_out_sensitive_data_storage": false
  }
}

v1 call_ended 페이로드

{
  "event": "call_ended",
  "call": {
    "agent_id": "a1f4c8d2-3e5b-4a7c-9d8e-2b1f6c4a9d3e",
    "call_id": "6b0f1f08-1c2b-4f0e-9c3a-0c1d9e6f5a82",
    "call_type": "inbound",
    "call_from": "01012345678",
    "call_to": "07012345678",
    "dynamic_variables": {
      "customer_name": "김철수"
    },
    "metadata": {
      "campaign": "봄_프로모션"
    },
    "start_timestamp": 1775980200000,
    "end_timestamp": 1775980542000,
    "duration_ms": 342000,
    "disconnection_reason": "agent_hangup",
    "recording_url": "https://www.tryvox.co/api/store/download/...",
    "transcript": [
      { "role": "agent", "content": "안녕하세요, 무엇을 도와드릴까요?" },
      { "role": "user", "content": "주문 상태를 확인하고 싶습니다." }
    ],
    "call_cost": {
      "total_credits_used": 120,
      "duration_seconds": 342
    },
    "call_analysis": {
      "summary": "고객이 주문 ORD-2026-0042의 배송 상태를 문의했고, 3월 25일 도착 예정임을 안내했습니다.",
      "user_sentiment": "positive",
      "custom_analysis_data": [
        { "name": "inquiry_type", "value": "배송 상태 문의" },
        { "name": "resolved", "value": true }
      ]
    },
    "opt_out_sensitive_data_storage": false
  }
}
시간 단위: start_timestamp, end_timestamp는 UNIX 타임스탬프(밀리초)이고, duration_ms밀리초입니다. ISO 8601 문자열이 아니라는 점에 유의하세요. call_cost.duration_seconds만 과금 편의를 위해 초 단위로 제공됩니다.
v1에서는 통화 정보 추출에서 정의한 필드가 call.call_analysis.custom_analysis_data 배열에 포함됩니다. v2에서는 같은 데이터가 call_analyzed 이벤트에 포함됩니다.

v1 mid_call 페이로드

mid_call은 통화가 진행되는 동안 발생하는 세부 이벤트를 스트림처럼 전달합니다. event_type에 따라 event_data 구조가 달라집니다.플로우 노드 전환 (flow_transition):
{
  "event": "mid_call",
  "mid_call": {
    "agent_id": "a1f4c8d2-3e5b-4a7c-9d8e-2b1f6c4a9d3e",
    "call_id": "6b0f1f08-1c2b-4f0e-9c3a-0c1d9e6f5a82",
    "timestamp": 1775980380000,
    "event_type": "flow_transition",
    "event_data": {
      "from_node_id": "node_1",
      "to_node_id": "node_2",
      "from_node_name": "인사",
      "to_node_name": "주문 조회"
    }
  }
}
개별 발화 (call_message):
{
  "event": "mid_call",
  "mid_call": {
    "agent_id": "a1f4c8d2-3e5b-4a7c-9d8e-2b1f6c4a9d3e",
    "call_id": "6b0f1f08-1c2b-4f0e-9c3a-0c1d9e6f5a82",
    "timestamp": 1775980380000,
    "event_type": "call_message",
    "event_data": {
      "role": "user",
      "content": "주문 번호는 ORD-2026-0042입니다."
    }
  }
}

종료 사유 (disconnection_reason)

call_ended 페이로드의 disconnection_reason에 쓰이는 값 목록과 의미는 통화종료사유에서 확인하세요. 대시보드 필터·API 응답과 동일한 값을 사용합니다.

관련 문서


웹훅, webhook, 인바운드 웹훅, 통화 데이터 웹훅, call_started, call_ended, call_analyzed, mid_call, 페이로드, payload, webhook v2