새로운 문서를 작성 중입니다.새 문서로 이동
ClawOps Docs

통화 실패 사유 (Hangup Cause)

통화가 왜 끝났는지를 나타내는 hangupCause·hangupCauseQ850·sipResponseCode·hangupSource 전체 목록. 결번(없는 번호) 자동 정제, 재시도 판단, 실패 분석에 사용합니다.

통화 실패 사유 (Hangup Cause)

status 는 통화가 어떻게 끝났는지(completed / failed / busy / no-answer ...)만 알려줍니다. 왜 그렇게 끝났는지 — 결번인지, 상대가 안 받은 건지, 망 장애인지 — 는 hangupCause 로 구분합니다.

특히 failed 는 결번·망 오류·시스템 오류를 모두 포함하는 대분류입니다. 발신 리스트를 정제하거나 재시도 여부를 판단하려면 status 가 아니라 hangupCause 를 보세요.

어디서 받나요

경로필드
통화 단건 조회hangupCause · hangupCauseQ850 · sipResponseCode · hangupSource
통화 목록 조회위와 동일 (통화마다)
Status Callback webhookHangupCause · HangupCauseQ850 · SipResponseCode · HangupSource (종료 이벤트)
{
  "callId": "CAabcdef1234567890",
  "status": "failed",
  "to": "07080588491",
  "duration": 0,
  "hangupCause": "invalid_number",
  "hangupCauseQ850": 1,
  "sipResponseCode": 404,
  "hangupSource": "carrier"
}

네 값은 같은 사건을 서로 다른 해상도로 표현합니다. 보통은 hangupCause 하나면 충분하고, hangupCauseQ850·sipResponseCode 는 통신망 원본 신호가 필요한 정밀 분석용입니다.

재시도 판단

가장 흔한 용도입니다. 이 표만 보고 분기하면 됩니다.

재시도해도 소용없음 — 번호를 목록에서 제외하세요

hangupCauseQ.850뜻
invalid_number1 · 5 · 28결번. 없는 번호이거나 형식이 잘못됐습니다
number_changed22번호가 변경됐습니다
incompatible_destination88해당 번호로는 음성 통화를 연결할 수 없습니다
recipient_blocked21수신거부 명단에 등록된 번호라 걸지 않았습니다. 벨은 울리지 않았고 요금도 발생하지 않습니다

recipient_blocked 는 통신망이 아니라 여러분이 등록한 명단 때문에 걸리지 않은 통화입니다. 재시도하면 같은 결과이고, 무엇보다 연락하지 말라고 한 상대에게 다시 거는 일이 됩니다. 명단은 수신거부 목록 조회 또는 콘솔의 수신거부 화면에서 관리하고, 해제해야 다시 발신됩니다. 발신 API 호출 자체는 422 recipient_blocked 로 즉시 거절됩니다.

재시도 가치 있음 — 일시적인 사유입니다

hangupCauseQ.850뜻
no_answer18 · 19 · 20벨은 울렸으나 받지 않음
user_busy17통화 중
recovery_on_timer_expire102응답 대기 시간 초과
temporary_failure41통신망 일시 장애
switching_congestion42교환기 혼잡
no_circuit_available34회선 부족
network_out_of_order38망 장애
destination_out_of_order27상대 단말/교환기 장애
resource_unavailable47망 자원 부족
protocol_error111통신망 프로토콜 오류

계정 한도·상태 — 번호가 아니라 계정을 확인하세요

수신 통화가 계정 설정 때문에 연결되지 못한 경우입니다. 상대 번호에는 문제가 없습니다.

hangupCauseQ.850뜻
concurrency_limit_exceeded17동시통화 한도를 넘어 받지 못했습니다. 잠시 후 재시도하거나 동시통화 채널을 올리세요
subscription_inactive21구독이 없거나 만료되어 받지 못했습니다. 재시도해도 동일합니다
inbound_quota_exceeded21월 수신 통화 한도를 다 썼습니다. 다음 청구 주기에 초기화됩니다
inbound_not_supported21현재 플랜이 수신 통화를 지원하지 않습니다
sip_trunk_inactive21SIP 트렁크 부가서비스가 없거나 만료되어 BYOC·소프트폰 번호로 받지 못했습니다

1채널로 운영 중에 두 번째 전화가 들어오면 concurrency_limit_exceeded 로 통화 기록이 남고 Status Callback webhook 이 발송됩니다. 발신번호(From)를 받아 콜백 안내 문자를 보내는 구성에 쓰실 수 있습니다.

수신 통화 차단 — 여러분의 설정이 거절했습니다

수신 통화를 받지 않고 거절하도록 여러분이 설정한 경우입니다. 실패가 아니며 요금도 청구되지 않습니다. status 는 rejected 입니다. 설정 방법은 수신 통화 차단 을 보세요.

hangupCauseQ.850뜻
caller_blocked21수신 통화 차단 목록에 있는 번호라 받지 않고 거절했습니다
caller_id_restricted_rejected21번호의 번호 표시제한 통화 거절이 켜져 있어, 번호를 숨기고 건 통화를 받지 않고 거절했습니다

recipient_blocked(발신 쪽 수신거부 명단)와 다릅니다 — 그쪽은 여러분이 거는 통화를 막습니다.

등록 단말·SIP 도착지 — 받는 쪽 설정을 확인하세요

번호 라우팅을 소프트폰(등록 단말 착신) 이나 SIP 트렁크(외부 SIP 도착지) 로 둔 번호에 걸려온 전화를 넘기지 못한 경우입니다. 등록 단말은 softphone_not_registered, SIP 도착지는 sip_endpoint_not_found 로 경로가 갈립니다.

hangupCauseQ.850뜻
softphone_not_registered1이 번호로 등록된 단말이 없어 연결하지 못했습니다. 단말의 등록 상태를 확인하세요. 등록되기를 기다렸다 넘겨 주지 않습니다
sip_endpoint_not_found1SIP 도착지가 404(또는 604)로 대상을 찾을 수 없다고 응답했습니다. 도착지 URI 와 받는 서버의 설정을 확인하세요

단말이나 도착지가 받지 않거나 통화 중·거절로 응답하면 통신망과 같은 사유(no_answer·user_busy·call_rejected 등)로 기록됩니다. 벨이 울린 뒤 30초 안에 받지 않으면 status 는 no-answer, hangupCause 는 no_answer 입니다.

ClawOps 측 오류 — 재시도하세요

hangupCausehangupSource뜻
app_errorapp통화 처리 중 오류가 발생했습니다 (VoiceML 파싱 실패 등 포함)
call_stucksystem통화가 비정상 상태로 남아 시스템이 정리했습니다

hangupSource 가 app 또는 system 이면 상대방·번호 문제가 아니라 ClawOps 측 문제입니다. 수신자 번호를 정제 대상으로 넣지 마시고 재시도해 주세요. 반복되면 통화 ID 와 함께 문의해 주시면 원인을 확인해 드립니다.

실패가 아닌 종료

hangupCauseQ.850뜻
normal_clearing16통화 후 정상 종료 (status: "completed"). 누가 먼저 끊었는지는 hangupSource 로 구분합니다
caller_canceled16상대가 받기 전에 발신 측이 끊음
call_rejected21 · 50 · 57수신자가 거절 (수신 차단 포함). 수신 통화에서는 VoiceML <Reject> 로 거절한 통화도 이 값입니다
unspecified31 · 127통신망이 사유를 주지 않음
unknown—위 어디에도 해당하지 않는 cause

사유로 조회하기

통화 목록 조회 의 hangupCause 로 필터링합니다. status 는 failed 하나에 결번·망 오류·시스템 오류가 다 섞여 있어, 사유별로 보려면 이쪽을 쓰세요.

GET /v1/accounts/{accountId}/calls?hangupCause=concurrency_limit_exceeded
GET /v1/accounts/{accountId}/calls?hangupCause=invalid_number&hangupCause=number_changed

기간·통화시간과 함께 좁힐 수도 있습니다. since/until 은 시작 시각 기준이고 until 은 미포함, minDuration/maxDuration 은 초 단위로 양끝을 포함합니다. 통화 시간이 아직 확정되지 않은 통화(진행 중 등)는 minDuration/maxDuration 을 주면 결과에서 빠집니다.

# 지난달 놓친 전화 중 0초로 끝난 것만
GET /v1/accounts/{accountId}/calls?since=2026-08-01T00:00:00Z&until=2026-09-01T00:00:00Z&minDuration=0&maxDuration=0

hangupSource — 누구 때문에 끝났나

값뜻
carrier통신망이 통화를 끊었습니다 (결번·망 장애 등)
callee수신 측이 끝냈습니다 (거절·통화중·무응답, 또는 통화 후 먼저 끊음)
caller발신 측이 끝냈습니다 (연결 전 취소, 또는 통화 후 먼저 끊음)
appClawOps 통화 처리 오류
systemClawOps 시스템이 정리하거나 종료한 통화
null종료 주체를 판정하지 못했습니다

통화 후 정상 종료(normal_clearing)에서 caller·callee 는 먼저 끊은 쪽의 역할입니다. 여러분의 앱·에이전트가 끊었다면 그 통화에서 맡은 역할로 기록됩니다.

통화 방향상대가 먼저 끊음여러분의 앱·에이전트가 먼저 끊음
착신 (inbound)callercallee
발신 (outbound)calleecaller

2026년 10월 12일부터 정상 종료 통화도 실제로 먼저 끊은 쪽을 기록합니다. 그 전에는 정상 종료 통화의 hangupSource 가 누가 끊었는지와 관계없이 항상 callee 였습니다.

sipResponseCode

통신망이 보낸 SIP 응답코드가 있을 때만 채워집니다. 없이 끝난 통화는 null 입니다.

코드흔한 의미
404없는 번호
403발신이 거부됨
408응답 없음
480일시적으로 연결할 수 없음
486통화 중
500통신망 내부 오류 — 실제 사유는 hangupCause 를 보세요

국내 통신망은 실제 사유를 500 으로 감싸 보내는 경우가 있습니다. ClawOps 는 통신망이 함께 보낸 Q.850 원인값을 읽어 hangupCause 로 교정하므로, SIP 코드보다 hangupCause 가 정확합니다.

예제 — 결번 자동 정제

발신 후 통화 결과를 조회해, 다시 걸어도 소용없는 번호를 목록에서 빼는 예제입니다.

DO_NOT_RETRY = {"invalid_number", "number_changed", "incompatible_destination"}

call = client.accounts(account_id).calls.get(call_id)

if call.status != "completed":
    cause = getattr(call, "hangup_cause", None)
    if cause in DO_NOT_RETRY:
        mark_number_invalid(call.to)          # 고객 DB 에서 제외
    elif getattr(call, "hangup_source", None) in ("app", "system"):
        enqueue_retry(call.to)                # ClawOps 측 오류 — 재시도
    else:
        enqueue_retry(call.to, delay_min=30)  # 일시적 사유 — 나중에 재시도

Status Callback 으로 실시간 처리하려면 종료 이벤트에서 같은 값을 읽으면 됩니다.

@app.route("/status", methods=["POST"])
def status_callback():
    if request.form.get("CallStatus") in ("completed", "failed", "busy", "no-answer"):
        cause = request.form.get("HangupCause")
        if cause in DO_NOT_RETRY:
            mark_number_invalid(request.form.get("To"))
    return "", 204

통화 전환(transfer)의 실패 사유

이 페이지의 hangupCause 는 발신자와 ClawOps 사이의 통화(메인 leg) 에 대한 값입니다. 에이전트나 SIP 단말이 상담원에게 넘긴 전환 leg 는 별도 필드를 씁니다 — transferHangupCauseQ850 · transferSipResponseCode · transferReasonText, 그리고 다단계 전환의 전체 이력은 transfers[] 입니다. 값을 읽는 법은 통화 전환 결과 를 보세요.

VoiceML <Dial> 은 이 transfer* 필드를 채우지 않습니다. <Dial> 결과는 action 요청의 DialCallStatus 로 받습니다 — VoiceML 참고.