ThunderPhone 2.0을 출시했습니다.셀프서비스로, 분당 2¢부터.출시 소식 보기

Webhooks

이벤트 카탈로그

ThunderPhone이 발생시키는 모든 웹훅 이벤트 유형입니다.

모든 웹훅 본문에는 이 페이지의 이벤트 유형 중 하나를 값으로 갖는 type 필드가 있습니다. 엔드포인트를 구독할 때 events 배열에는 원하는 이벤트 유형을 포함해야 합니다(모든 이벤트를 구독하려면 비워 둘 수 있음. 단, 명시적으로 이름을 지정한 엔드포인트에만 전달되는 턴별 이벤트 telephony.turn / web.turn은 제외).

이 이벤트는 두 가지 전달 방식으로 제공됩니다:

  • 엔드포인트 전송은 항상 재시도를 사용하는 비차단 알림입니다. 모든 2xx로 응답하십시오. 엔벌로프에는 중복 제거에 사용할 event_id가 포함됩니다.
  • 차단 교환은 레거시 단일 URL 웹훅에서만 실행됩니다. 여기에는 telephony.incoming / web.incoming 구성 요청(웹훅 모드 번호: 재시도 1회를 포함해 13초, 웹훅 모드 위젯 키: 10초)과 웹훅 모드 도구 디스패치가 포함됩니다. 응답이 진행 중인 통화를 구성합니다.

아래 예제 페이로드는 전송 순서의 엔드포인트 엔벌로프를 보여 줍니다(키는 알파벳순으로 정렬됨: data, event_id, type). 레거시 전달은 event_id 없이 동일한 data를 포함합니다.

통화 이벤트

telephony.incoming

수신 통화가 전화번호 중 하나에 도달하면 전송됩니다. 엔드포인트 전송은 에이전트 구성 여부나 웹훅 구성 여부와 관계없이 모든 수신 통화에 대해 전송 후 응답을 기다리지 않는 알림입니다. 에이전트가 할당되지 않은 번호는 레거시 웹훅에서 추가로 블로킹 구성 요청을 받습니다. 전체 요청/응답 스키마는 telephony.incoming / web.incoming을 참조하세요.

{
  "data": {
    "call_id": 987654321,
    "from_number": "+14155550199",
    "to_number": "+15551234567"
  },
  "event_id": "3f6b2ad0-1c9e-4a57-9f2b-8f6f0f9d2f11",
  "type": "telephony.incoming"
}
필드유형설명
agent_idinteger | null에이전트가 할당된 경우 통화를 처리한 에이전트
agent_namestring | null에이전트가 할당된 경우 통화를 처리한 에이전트

telephony.complete

수신 또는 발신 전화 통화가 종료되면 전송됩니다. 블로킹되지 않습니다. 대화 내용, 사용 가능한 경우 녹음 URL 및 청구 요약을 포함합니다. 페이로드 스키마는 telephony.complete / web.complete를 참조하세요.

필드유형설명
agent_idinteger | null에이전트가 할당된 경우 통화를 처리한 에이전트
agent_namestring | null에이전트가 할당된 경우 통화를 처리한 에이전트

telephony.tool

전화 통화가 함수 도구를 호출한 후 전송됩니다. 블로킹되지 않는 감사 알림입니다. 이 이벤트가 전송될 때 도구는 이미 실행된 상태입니다. 자체 함수 도구와 기본 제공 send_sms 도구에 적용되며, 다른 기본 제공 도구, 지식 기반 도구, 앱 연결 도구 또는 MCP 도구에는 적용되지 않습니다. send_sms의 경우 arguments.to 및 arguments.body는 모두 [REDACTED]입니다. 완료 대화 내용에서도 해당 값은 마스킹됩니다. 응답의 message_id를 사용하여 조직 범위 SMS 리소스에서 콘텐츠와 수신자를 조회하세요.

{
  "data": {
    "arguments": { "date": "2026-04-21" },
    "call_id": 987654321,
    "from_number": "+14155550199",
    "response": {
      "response": { "available_slots": ["9:00 AM", "2:00 PM"] },
      "status": 200
    },
    "to_number": "+15551234567",
    "tool_name": "search_appointments"
  },
  "event_id": "1f0a7c3e-52d4-4a0e-8f4b-b1a6a1c0d9e2",
  "type": "telephony.tool"
}

response는 실행 결과입니다. 성공 시 {"status": <http status>, "response": <your endpoint's JSON>}이고, 실패 시 {"status": <status>, "error": "<message>"}입니다.

필드유형설명
agent_idinteger | null에이전트가 할당된 경우 통화를 처리한 에이전트
agent_namestring | null에이전트가 할당된 경우 통화를 처리한 에이전트

telephony.turn

전화 통화가 진행 중인 동안 발화가 포함된 각 턴이 발생할 때마다 전송됩니다. 에이전트의 음성 완료 응답과 발신자의 전사된 턴이 포함됩니다. GET /v1/calls/{call_id}/transcript를 폴링하는 대신 일반 웹훅을 통해 실시간 대화를 추적할 수 있습니다. 블로킹되지 않습니다.

{
  "data": {
    "call_id": 987654321,
    "entry_type": "completion",
    "from_number": "+14155550199",
    "position": 7,
    "role": "assistant",
    "start_ms": 15200,
    "text": "How many employees does your company have?",
    "to_number": "+15551234567"
  },
  "event_id": "8d3f5a2c-7b1e-4c9a-b6d0-2e4f6a8c0d1e",
  "type": "telephony.turn"
}
필드유형설명
agent_idinteger | null에이전트가 할당된 경우 통화를 처리한 에이전트
agent_namestring | null에이전트가 할당된 경우 통화를 처리한 에이전트
positioninteger통화 기록 내 턴의 인덱스이며, 순서 지정을 위한 안정적인 식별자
rolestringassistant(에이전트 발화) 또는 user(발신자 발화)
textstring전송 시점에 알려진 턴의 대화 내용 텍스트
entry_typestring기본 기록 항목 유형: completion(에이전트) 또는 user_turn / span(발신자)
start_ms, end_msinteger통화 시작 이후의 밀리초 단위 오디오 오프셋이며, 전송 시점에 재생 타이밍을 이미 알고 있는 경우에만 제공

web.incoming

웹 위젯 세션 또는 빌더 마이크 테스트 통화가 시작될 때 전송되는 telephony.incoming의 웹 채널 버전입니다. 엔드포인트 전송은 모든 웹 세션에 대해 전송 후 응답을 기다리지 않습니다. mode="webhook"의 공개 키는 레거시 웹훅에서 추가로 블로킹 구성 요청을 받습니다. 해당 블로킹 요청은 형태가 다르며(origin_domain, publishable_key_prefix, 전화번호 없음), telephony.incoming / web.incoming을 참조하세요.

{
  "data": {
    "call_id": 987654322,
    "from_number": "web",
    "origin_domain": "https://example.com",
    "publishable_key_prefix": "pk_live_a1b2",
    "to_number": "+15551234567"
  },
  "event_id": "9a2b4c6d-8e0f-4a1b-9c2d-3e4f5a6b7c8d",
  "type": "web.incoming"
}

from_number는 항상 리터럴 "web"입니다. 웹훅 모드 위젯 세션의 경우 to_number는 비어 있습니다(세션의 에이전트 번호는 구성 후 할당됨). 빌더 마이크 테스트 통화의 경우 origin_domain 및 publishable_key_prefix가 비어 있습니다.

필드유형설명
agent_idinteger | null에이전트가 할당된 경우 통화를 처리한 에이전트
agent_namestring | null에이전트가 할당된 경우 통화를 처리한 에이전트

web.complete

웹 위젯 통화(direction: "web")와 빌더 마이크 테스트 통화(direction: "test")를 처리하는 telephony.complete의 웹 채널 버전입니다. 블로킹되지 않습니다. telephony.complete와 동일한 페이로드 형태이며 origin_domain이 추가되고 from_number는 "web"으로 설정됩니다.

필드유형설명
agent_idinteger | null에이전트가 할당된 경우 통화를 처리한 에이전트
agent_namestring | null에이전트가 할당된 경우 통화를 처리한 에이전트

web.tool

telephony.tool의 웹 채널 버전입니다. data에는 from_number / to_number 대신 origin_domain이 포함됩니다.

필드유형설명
agent_idinteger | null에이전트가 할당된 경우 통화를 처리한 에이전트
agent_namestring | null에이전트가 할당된 경우 통화를 처리한 에이전트

web.turn

웹 위젯 통화와 빌더 마이크 테스트 통화를 처리하는 telephony.turn의 웹 채널 버전입니다. from_number / to_number 대신 origin_domain을 포함하는 동일한 페이로드 형태를 사용합니다. telephony.turn과 마찬가지로 명시적 구독이 필요하며, 비어 있는 events 배열을 통해서는 전송되지 않습니다.

필드유형설명
agent_idinteger | null에이전트가 할당된 경우 통화를 처리한 에이전트
agent_namestring | null에이전트가 할당된 경우 통화를 처리한 에이전트

call.transfer_completed

통화당 한 번 전송되며, 통화 전환의 최종 결과를 포함합니다. 결과는 콜드 전환이거나, 에이전트가 빠진 후 웜 전환으로 남는 사람 간 브리지입니다. 차단 없이 처리되며 엔드포인트로만 전송됩니다(레거시 단일 URL 웹훅으로는 전송되지 않음). 통화의 telephony.complete 이후에 도착합니다. 통신사가 통화를 인계받거나 전환에 실패한 후, 또는 ThunderPhone이 통화를 브리지한 경우 브리지가 종료된 후 도착합니다.

{
  "data": {
    "agent_id": 12,
    "agent_name": "Front desk",
    "bridge_kind": "cold_fallback",
    "bridge_seconds": 255,
    "bridge_total_cents": 5,
    "call_id": 987654321,
    "destination": "+15555550102",
    "sip_status": 403,
    "transfer_outcome": "bridged"
  },
  "event_id": "5b0f6c1e-9d2a-5e7b-8c4d-1a2b3c4d5e6f",
  "type": "call.transfer_completed"
}
필드유형설명
call_idinteger전환된 통화입니다
agent_idinteger | null할당된 경우 통화를 처리한 에이전트입니다
agent_namestring | null할당된 경우 통화를 처리한 에이전트입니다
transfer_outcomestringrefer_accepted: 통신사가 통화를 인계받았습니다. bridged: 통신사가 콜드 전환을 거부했거나 웜 전환의 에이전트가 빠졌기 때문에 ThunderPhone이 발신자와 착신 번호를 직접 연결한 상태입니다. bridge_unanswered: 통신사가 콜드 전환을 거부했고 착신 번호가 ThunderPhone의 자체 발신에 응답하지 않았습니다. failed: 전환이 완료되지 않았고 통화가 종료되었습니다
destinationstring | null통화가 전환된 번호입니다
sip_statusinteger | null통신사가 콜드 전환을 거부했을 때의 SIP 상태입니다. 403(예: 통화 전환을 지원하지 않는 Twilio 트렁크), 405 또는 501입니다. 통신사가 거부하지 않은 경우 null입니다
bridge_kindstring | nullbridged에만 해당: cold_fallback(ThunderPhone이 연결한 거부된 콜드 전환) 또는 warm(에이전트가 떠난 후 웜 전환에 남은 두 사람)입니다
bridge_secondsinteger | nullbridged에만 해당: ThunderPhone이 청구한 브리지 시간(초)입니다
bridge_total_centsinteger | nullbridged에만 해당: 무료 통화 크레딧 적용 후 브리지 비용(USD 센트)입니다. 통화의 billing_total_cents와 별도로 청구됩니다

동일한 값은 통화 객체에도 transfer_outcome, transfer_destination, transfer_sip_status, transfer_bridge_kind, transfer_bridge_seconds, transfer_bridge_total_cents로 제공됩니다. event_id는 통화의 모든 전송에서 동일하므로, 반복 보고가 두 번째 이벤트를 생성하지 않습니다.


SMS 이벤트

SMS 이벤트는 조직의 연결된 Twilio 또는 Telnyx 계정을 통해 전송된 메시지를 설명합니다. 메시지 본문은 생략되고 to는 마스킹됩니다. 콘텐츠 또는 수신자가 필요한 경우 GET /v1/sms/{message_id}에서 조직 범위 메시지를 조회합니다.

sms.sent

고객의 통신사가 발신 SMS 요청을 수락하면 전송됩니다. 이는 단말기 수신 확인이 아닙니다.

{
  "data": {
    "accepted_at": "2026-09-19T15:42:10.113Z",
    "agent_id": 12,
    "call_id": 987654321,
    "created_at": "2026-09-19T15:42:09.901Z",
    "direction": "outbound",
    "error_code": null,
    "error_message": null,
    "from_number": "+15551234567",
    "id": "313a3117-827b-46e9-a01a-ac1493838724",
    "provider": "twilio",
    "provider_id": "SM0123456789abcdef0123456789abcdef",
    "segment_count": 1,
    "source": "agent_tool",
    "status": "accepted",
    "to": "[REDACTED]"
  },
  "event_id": "0ae347b4-1716-45bb-9a0e-b52373586e37",
  "type": "sms.sent"
}

sms.failed

통신사가 영구적으로 거부한 후, 일시적 오류에 대한 재시도가 모두 소진된 후 또는 결과를 최종적으로 알 수 없는 경우 전송됩니다. error_code는 안정적인 ThunderPhone 코드이며, error_message는 가능한 경우 고객이 취해야 할 조치를 설명합니다. status: "unknown"은 통신사가 SMS를 수락했을 수 있음을 의미합니다. ThunderPhone은 자동으로 재전송하지 않으므로 통신사 로그에서 조정합니다.

sms.received

수신 SMS 지원을 위해 예약되어 있습니다. 현재 릴리스에서는 sms.received 이벤트가 발생하지 않습니다. 수신 통신사 웹훅 구성 및 서명 검증은 별도로 제공될 예정입니다.


음성 이벤트

사용자 지정 음성 생성은 비동기적으로 처리됩니다. 이러한 비차단 이벤트를 사용하면 클론 세부 정보 엔드포인트를 폴링하는 대신 최종 결과에 대응할 수 있습니다.

voice.ready 및 voice.failed는 events: []가 설정된 조직 전체 엔드포인트로만 전달됩니다. 명시적 이벤트 필터로 선택할 수 없습니다.

voice.ready

사용자 지정 음성 처리가 완료되어 에이전트에 할당할 수 있게 되면 전송됩니다.

{
  "data": {
    "voice": {
      "created_at": "2026-07-30T14:12:08.317Z",
      "display_name": "Support voice",
      "failure_reason": "",
      "gender": "female",
      "id": "cv_2f6f90b0e9a34ee8b39be7d1",
      "language": "en",
      "name": "custom:cv_2f6f90b0e9a34ee8b39be7d1",
      "status": "ready",
      "updated_at": "2026-07-30T14:13:31.605Z"
    }
  },
  "event_id": "2d5f0a61-e9b5-4a3c-b684-29d7d9e4b214",
  "type": "voice.ready"
}

voice.failed

사용자 지정 음성 처리가 영구적 실패 상태에 도달하면 전송됩니다.

{
  "data": {
    "reason": "audio sample could not be processed",
    "voice": {
      "created_at": "2026-07-30T14:12:08.317Z",
      "display_name": "Support voice",
      "failure_reason": "audio sample could not be processed",
      "gender": "female",
      "id": "cv_2f6f90b0e9a34ee8b39be7d1",
      "language": "en",
      "name": "custom:cv_2f6f90b0e9a34ee8b39be7d1",
      "status": "failed",
      "updated_at": "2026-07-30T14:13:31.605Z"
    }
  },
  "event_id": "3493e985-1a75-4f77-a10a-e74af440cd31",
  "type": "voice.failed"
}
필드유형설명
voice.idstring사용자 지정 음성 공개 ID
voice.namestringcustom:<public_id> 형식의 에이전트 음성 값
voice.display_namestring조직에 표시되는 음성 이름
voice.languagestring클론의 단일 언어 코드
voice.genderstringmale, female 또는 빈 문자열
voice.statusstringvoice.ready의 경우 ready, voice.failed의 경우 failed
voice.failure_reasonstring성공 시 비어 있음, 실패 시 처리 실패 세부 정보
voice.created_at, voice.updated_attimestampISO 8601 타임스탬프
reasonstring실패 세부 정보이며 voice.failed에만 존재

품질 이벤트

call.graded

통화의 AI 평가 실행이 완료될 때마다 전송됩니다. 차단하지 않습니다.

{
  "data": {
    "call_id": 987654321,
    "grade": {
      "call_outcome": "success",
      "created_at": "2026-04-20T18:25:11.002Z",
      "detected_issues": [],
      "graded_at": "2026-04-20T18:25:11.002Z",
      "grader_model": "heuristic-v1",
      "id": 5512,
      "score": 92,
      "status": "completed",
      "summary": "Caller asked about their policy and got a full answer…"
    },
    "report": null
  },
  "event_id": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
  "type": "call.graded"
}
필드유형설명
agent_idinteger | null할당된 경우 통화를 처리한 에이전트
agent_namestring | null할당된 경우 통화를 처리한 에이전트
grade.idinteger평가 ID
grade.scoreinteger | null0–100
grade.call_outcomestringsuccess, failure, unknown 또는 no_conversation
grade.summarystring한 문단 요약
grade.detected_issuesarray평가기가 발견한 이슈 문자열
grade.statusstring항상 completed — 완료된 실행에서만 발생합니다
grade.grader_modelstring결과를 생성한 평가기(예: heuristic-v1)
grade.graded_at, grade.created_attimestamp
reportobject | null고객 대상 통화 보고서: 결과 레이블, 주의 필요 플래그 및 사유, 발신자, 한 줄 요약, 발신자 경험. 초기 휴리스틱 평가에서는 null이거나 필드가 자리표시자인 pending 보고서입니다. 전체 평가 이벤트에는 완료된 보고서가 포함됩니다

call.data_extracted

POST /v1/calls/{call_id}/extract를 통한 수동 재실행 또는 telephony.complete / web.complete 이후의 지연 재시도를 포함하여, 구조화된 데이터 추출이 성공적으로 완료될 때마다 전송됩니다. 차단하지 않습니다.

차단 추출 모드에서는 완료 이벤트가 일반적으로 75초의 추출 예산보다 오래 기다리지 않습니다. 추출 워커 프로세스가 손실되면 프로덕션 완료 처리 작업은 5분마다 다른 추출 시도를 시작하기 전에 blocking_deadline_at이 지난 완료를 해제합니다. 이후 성공한 결과는 이 이벤트로 별도로 전송됩니다.

{
  "data": {
    "call_id": 987654321,
    "agent_id": 12,
    "agent_name": "Acme intake",
    "extracted_data": {
      "status": "completed",
      "fields": {
        "customer_name": "Alex Morgan",
        "appointment_date": "2026-04-23"
      },
      "evidence": {
        "customer_name": {
          "quote": "My name is Alex Morgan",
          "speaker_role": "caller",
          "turn_index": 4
        },
        "appointment_date": {
          "quote": "April 23 works for me",
          "speaker_role": "caller",
          "turn_index": 7
        }
      },
      "verification": "verified",
      "field_reasons": {},
      "schema_version": "92850758e231a3c95a..."
    },
    "extracted_at": "2026-04-20T18:25:11.002Z",
    "model": "<model id>",
    "summary": "Alex Morgan called to book a follow-up visit and confirmed Thursday, April 23."
  },
  "event_id": "4d79ef1d-c2b1-4ed6-85b8-8326bd2895ef",
  "type": "call.data_extracted"
}
필드유형설명
agent_idinteger | null에이전트가 배정된 경우 통화를 처리한 에이전트
agent_namestring | null에이전트가 배정된 경우 통화를 처리한 에이전트
summarystring | null에이전트에서 통화 요약 생성을 켠 경우의 완료된 통화 요약입니다. 따라서 늦은 추출 이벤트도 완료 시간 제한을 놓친 요약을 제공합니다. 그 외의 경우에는 null입니다. 요약은 있지만 추출 필드가 없는 에이전트는 이 이벤트를 절대 발생시키지 않습니다. 늦은 요약은 GET /v1/calls/{call_id}에서 읽으십시오.
extracted_data.statusstring이 이벤트에서는 항상 completed입니다.
extracted_data.fieldsobject구성된 추출 필드 키를 기준으로 하는 값입니다. 사용할 수 없는 값은 null입니다.
extracted_data.evidenceobject추출 필드를 기준으로 하는 증거입니다. null이 아닌 값에는 정확히 구조적으로 검증된 인용문(최대 1,000자), speaker_role(caller 또는 agent), turn_index가 포함됩니다. 모델이 반환한 더 긴 인용문은 잘리지 않고 거부되며, 해당 필드가 null이면 증거도 null입니다.
extracted_data.verificationstring독립적인 증거 검증 단계가 모든 후보 필드에 대해 정확히 하나의 유효한 판정을 반환한 경우에만 verified입니다. unavailable은 검증 단계가 실패했거나, 시간 초과되었거나, 예산이 부족했거나, 잘못된 형식 또는 부분 출력을 반환했음을 의미합니다. 전체 검증 단계를 사용할 수 없는 경우에도 고객 검토를 위해 구조적 근거가 있는 값을 유지합니다. 부분 출력의 경우 유효한 판정이 적용되며, 정확히 하나의 유효한 판정이 없는 각 후보는 null 처리됩니다.
extracted_data.field_reasonsobject구조적 근거 검증 또는 독립 검증기에 의해 null 처리된 필드를 기준으로 하는 사유입니다.
extracted_data.schema_versionstring이 추출에 사용된 정확한 필드 스키마의 해시입니다.
extracted_attimestampISO 8601 완료 시간입니다.
modelstring추출에 사용된 모델입니다.

campaign.completed

캠페인의 일정이 종료되었거나 모든 연락처가 최종 상태에 도달하여 캠페인이 running에서 completed로 전환될 때 한 번 전송됩니다. 실행기 재시도는 다른 이벤트를 전송하지 않습니다. 이 조직 수준 수명 주기 이벤트는 에이전트 범위 엔드포인트가 아닌 조직 범위 엔드포인트에만 전달됩니다. 차단하지 않습니다.

{
  "data": {
    "campaign_id": "3f6b2c9e-2a0d-4c63-b6d6-a708dc98f403",
    "name": "May win-back",
    "agent_id": 12,
    "status": "completed",
    "started_at": "2026-04-20T17:00:00Z",
    "completed_at": "2026-04-20T18:25:11Z",
    "counts": {
      "contacts_total": 150,
      "completed": 121,
      "failed": 11,
      "no_answer": 18,
      "remaining": 0
    }
  },
  "event_id": "8d8f52ce-6b46-423f-9dde-cea0b91ec135",
  "type": "campaign.completed"
}

네 가지 결과 수는 서로 겹치지 않으며 합계는 contacts_total과 같습니다. completed에는 성공한 연락처가 포함됩니다. no_answer에는 최종 결과가 응답 없음인 최종 실패 또는 소진 상태의 연락처가 포함됩니다. failed에는 그 외 모든 최종 실패 또는 소진 상태의 연락처가 포함됩니다. remaining에는 대기 중, 예약됨 또는 현재 통화 중인 연락처가 포함됩니다. 가장 최근 시도가 응답 없음이었더라도 재시도를 기다리는 연락처는 remaining입니다. 한 번만 생성되는 완료 스냅샷 전에 진행 중인 통화가 조정됩니다. started_at은 구성된 캠페인 시작 시간이며, 시작 시간이 구성되지 않은 경우 캠페인 생성 시간입니다.

issue.reported

이슈 보고서가 생성될 때 전송됩니다. 즉, 대시보드에서 사용자가 제출한 경우(source: "user") 또는 통화 평가가 자동으로 생성한 경우 (source: "system")입니다. 차단하지 않습니다.

{
  "data": {
    "call_id": 987654321,
    "issue_report": {
      "created_at": "2026-04-20T18:25:11.002Z",
      "description": "Five-second silence before responding to the main question.",
      "id": 4321,
      "severity": "warning",
      "source": "system",
      "status": "open",
      "title": "Agent paused too long"
    }
  },
  "event_id": "5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b",
  "type": "issue.reported"
}
필드유형설명
agent_idinteger | null배정된 경우 통화를 처리한 에이전트
agent_namestring | null배정된 경우 통화를 처리한 에이전트
issue_report.severitystringcritical, warning 또는 info
issue_report.statusstringopen 또는 resolved
issue_report.sourcestringuser(대시보드에서 제출) 또는 system(평가로 생성)

issue.escalated

이슈 패턴이 직원 검토를 위해 ThunderPhone으로 전송될 때 전송됩니다. ThunderPhone에 보고 후 또는 Fix with AI가 고객 측 해결을 확인하지 못해 이슈를 자동으로 라우팅하는 경우에 발생합니다. 이 이벤트는 조직 전체 엔드포인트만 수신합니다.

{
  "data": {
    "automatic": false,
    "cluster_id": "7ac2844c-2df0-4fa8-a560-7378da649e19",
    "escalation_id": "ec99f52b-c8c0-41dd-a4f2-dd8a07b10894",
    "status": "open"
  },
  "event_id": "d8f8f420-7a42-45ba-bcf1-b747f9bbecda",
  "type": "issue.escalated"
}
필드유형설명
automaticboolean자동 에스컬레이션은 true, 수동 에스컬레이션은 false
cluster_idUUID에스컬레이션된 이슈 패턴
escalation_idUUID에스컬레이션 기록
statusstring이벤트 전송 시 open

이것은 근거 묶음이 아니라 알림입니다. cluster_id를 사용하여 이슈 패턴과 연결하십시오. ThunderPhone에 보고를 참조하십시오.


테스트 통화 이벤트

test-call.completed

test-call 실행이 통화가 시작되지 않아 실패한 실행을 포함하여 completed 또는 failed의 최종 상태에 도달하면 전송됩니다. 차단하지 않습니다. 일괄 CI 실행을 채팅/알림 시스템에 연결하는 데 유용합니다.

{
  "data": {
    "test_call_run": {
      "call_id": 987654321,
      "completed_at": "2026-04-20T18:25:04.822Z",
      "error_message": "",
      "id": 7110,
      "status": "completed",
      "target_id": 12,
      "target_type": "agent"
    }
  },
  "event_id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
  "type": "test-call.completed"
}
필드유형설명
agent_idinteger | null할당된 경우 통화를 처리한 에이전트
agent_namestring | null할당된 경우 통화를 처리한 에이전트
test_call_run.target_typestringagent 또는 phone_number
test_call_run.target_idintegertarget_type과 일치하는, 실행 대상 에이전트 ID 또는 전화번호 ID
test_call_run.statusstringcompleted 또는 failed
test_call_run.call_idinteger | null통화가 시작되기 전에 실행이 실패한 경우 null
test_call_run.error_messagestring성공 시 비어 있음

알림 이벤트

alert.triggered

개발자 웹훅으로 전달 채널이 활성화된 알림 규칙이 임계값을 넘으면 전송됩니다. 차단하지 않습니다. 규칙은 한 번 발생한 후 쿨다운을 준수하므로, 지속적인 위반은 쿨다운 기간당 하나의 이벤트를 생성합니다.

{
  "data": {
    "comparator": "lt",
    "event_id": "b8e6a1d4-2c3f-4a5b-9c8d-7e6f5a4b3c2d",
    "fired_at": "2026-04-20T18:00:00+00:00",
    "metric": "success_rate",
    "metric_value": 71.4,
    "rule_id": "d2c3b4a5-6f7e-4d8c-9b0a-1c2d3e4f5a6b",
    "rule_name": "Success rate below 80%",
    "threshold": 80.0,
    "window_hours": 24
  },
  "event_id": "4d5e6f7a-8b9c-4d0e-9f1a-2b3c4d5e6f7a",
  "type": "alert.triggered"
}
필드유형설명
event_id (data 내)UUID알림 발생 ID — 엔벨로프의 전달 event_id와 다릅니다
rule_id, rule_nameUUID, string발생한 규칙
metricstringsuccess_rate, failure_rate, avg_score, call_volume 또는 suite_regression
comparatorstringlt, lte, gt 또는 gte
metric_valuenumber규칙이 발생했을 때 평가 기간 내 메트릭 값
thresholdnumber구성된 임계값
window_hoursinteger후행 평가 기간
fired_attimestamp

규칙, 메트릭, 쿨다운 및 이메일 / Slack 채널을 만드는 방법은 알림 가이드를 참조하세요.


마이그레이션 이벤트

migration.call.complete

POST /v1/migrations/{id}/calls를 통해 발신한 통화가 어느 플랫폼에서 처리되었는지와 관계없이 종료되면 전송됩니다. 비차단 방식입니다. 통화가 종료된 후 최대 약 5분 내에 도착합니다. data에는 telephony.complete의 모든 필드와 migration 블록이 포함됩니다. ThunderPhone에서 발신한 통화는 동일한 call_id와 함께 평소와 같이 telephony.complete도 전송합니다. 다른 플랫폼의 통화가 2시간 후에도 종료되지 않았거나, 마이그레이션이 먼저 완료되었거나 키를 잃은 경우에는 status: "unknown" 및 트랜스크립트 없이 전송됩니다.

{
  "data": {
    "agent_id": 42,
    "agent_name": "Front desk",
    "billable_minutes": null,
    "billing_total_cents": null,
    "call_id": null,
    "direction": "outbound",
    "duration_seconds": 94,
    "end_reason": "user_hangup",
    "end_time": "2026-10-06T17:01:34+00:00",
    "extracted_data": null,
    "from_number": "+15551234567",
    "migration": {
      "arm": "vendor",
      "id": "5f0c2a9e-7b1d-4c3e-8a6f-2d9e1b4c7a30",
      "metadata": {
        "lead_id": "8812"
      },
      "routing_id": "9b2f8c1e-4d3a-4f6b-8e2d-1a7c5b9e0f34",
      "vendor": "retell",
      "vendor_call_id": "call_6a1f0e",
      "vendor_cost_usd": "0.1240"
    },
    "product": "",
    "recording_mode": "vendor",
    "recording_url": "https://…",
    "start_time": "2026-10-06T17:00:00+00:00",
    "status": "completed",
    "summary": "The callee booked a table for two on Thursday.",
    "thunderphone_retained_call_content": true,
    "to_number": "+14155552671",
    "transcripts": [
      {
        "content": "Hi Ada, this is Rosa's calling about your booking.",
        "role": "agent"
      },
      {
        "content": "Yes, Thursday works.",
        "role": "user"
      }
    ],
    "transfer_number": null,
    "unresolved_variables": [],
    "variables": {
      "first_name": "Ada"
    },
    "voice": ""
  },
  "event_id": "7c1e2f3a-4b5c-4d6e-8f7a-9b0c1d2e3f4a",
  "type": "migration.call.complete"
}
필드유형설명
migration.idUUID마이그레이션
migration.routing_idUUID통화를 발신할 때 반환된 라우팅된 통화
migration.armstringours(ThunderPhone에서 발신) 또는 vendor(다른 플랫폼에서 발신)
migration.vendorstringretell, vapi, elevenlabs 또는 bland
migration.vendor_call_idstring | null다른 플랫폼의 통화 ID이며, ours의 경우 null
migration.metadataobject통화 발신 시 전송한 metadata
migration.vendor_cost_usdstring | null다른 플랫폼이 제공한 경우 해당 플랫폼에서 보고한 통화 비용
call_idinteger | nullThunderPhone 통화 ID이며, vendor의 경우 null
statusstringvendor의 경우: 수신자가 통화한 경우 completed, 통화하지 않은 경우 failed, 위에서 설명한 경우 unknown입니다. ours의 경우: telephony.complete와 동일합니다.

vendor 통화의 경우 ThunderPhone에는 청구 또는 추출 데이터가 없습니다. billable_minutes, billing_total_cents, extracted_data는 null이며, product와 voice는 비어 있고, recording_mode는 vendor입니다. recording_url은 다른 플랫폼에서 제공한 경우 해당 플랫폼의 링크입니다.

migration.rollback

마이그레이션의 점진적 전환이 자동으로 모든 통화를 다른 플랫폼으로 되돌릴 때 전송됩니다. 다음 경우에 발생합니다. 15분 내 ThunderPhone 연결에 3번 실패한 경우, ThunderPhone으로 전송된 통화 2건이 에이전트가 응답하기 전에 종료된 경우, 또는 ThunderPhone의 작업 결과율이 다른 플랫폼보다 구성된 격차를 초과하여 낮아진 경우입니다. 롤백당 한 번 전송되며 차단하지 않습니다. 이후 ThunderPhone의 통화 비중은 0%가 되고, 누군가 에이전트의 마이그레이션 탭에서 재개할 때까지 마이그레이션이 일시 중지됩니다. 페이로드에는 전화번호, 대화 기록 또는 통화 ID가 포함되지 않습니다.

{
  "data": {
    "agent_id": 42,
    "agent_name": "Front desk",
    "dropped": 0,
    "migration_id": "5f0c2a9e-7b1d-4c3e-8a6f-2d9e1b4c7a30",
    "ours": {
      "graded": 20,
      "success_rate": 0.8
    },
    "ours_failed": 3,
    "ours_percent": 0,
    "previous_percent": 25,
    "reason": "ours_failed_burst",
    "rolled_back_at": "2026-10-10T12:05:00+00:00",
    "step": 1,
    "theirs": {
      "graded": 20,
      "success_rate": 0.8
    },
    "vendor": "retell"
  },
  "event_id": "3d1f6b2a-8c4e-5a7b-9d0e-2f1a3b4c5d6e",
  "type": "migration.rollback"
}
필드유형설명
migration_idUUID마이그레이션
vendor문자열retell, vapi, elevenlabs 또는 bland
reason문자열ours_failed_burst(15분 내 연결 실패 3건), dropped_calls(30분 내 에이전트가 응답하기 전에 종료된 통화 2건) 또는 rate_gap(각 측에서 최소 rollback_min_calls건의 평가된 통화를 기준으로 한 작업 결과율 격차)
previous_percent정수롤백 전 ThunderPhone의 통화 비중
ours_percent정수항상 0
step정수 | null적용 중이던 일정 단계(0부터 시작)
ours / theirs객체 | null현재 단계의 평가된 통화와 성공률입니다. 단계의 통화 수가 너무 적으면 theirs는 최근 30일 기준일 수 있습니다. 통화가 없으면 null입니다.
ours_failed정수최근 15분 동안 집계된 연결 실패 수
dropped정수최근 30분 동안 중단으로 집계된 통화 수
rolled_back_at타임스탬프

관련 항목