KAT Cloud로그인

웹훅 등록·수정·테스트: /webhook/{id}/test로 연결 점검하기

KAT Cloud 웹훅은 POST /webhook으로 등록하고 PATCH로 URL을 바꾸며 DELETE로 지웁니다. /webhook/{id}/test 결과의 success, statusCode, responseTime, error로 연결 문제를 찾는 법을 정리했습니다.

가이드KAT Cloud 팀9분 읽기
웹훅 등록·수정·테스트: /webhook/{id}/test로 연결 점검하기

KAT Cloud 웹훅은 POST /webhook으로 이벤트 타입과 https 수신 URL을 등록하고, PATCH /webhook/{webhookId}로 URL을 바꾸고, DELETE /webhook/{webhookId}로 삭제합니다. 등록한 웹훅이 실제로 내 서버에 닿는지는 POST /webhook/{webhookId}/test로 테스트 페이로드를 보내 확인하며, 응답의 success, statusCode, responseTime, error 네 값으로 문제 위치를 좁힐 수 있습니다.

KAT Cloud 웹훅 API 한눈에 보기

KAT Cloud(캣클라우드)는 이벤트가 생기면 등록된 URL로 HTTP POST 요청을 보냅니다. 웹훅 설정을 다루는 엔드포인트는 다섯 개입니다.

메서드경로하는 일
GET/webhook등록된 웹훅 목록 조회
POST/webhook웹훅 등록(eventType, url 필수)
PATCH/webhook/{webhookId}웹훅 URL 수정(url 필수)
DELETE/webhook/{webhookId}웹훅 삭제
POST/webhook/{webhookId}/test등록된 웹훅으로 테스트 페이로드 전송
웹훅 목록을 확인하고, 등록하고, 테스트로 연결을 점검한 뒤, 필요하면 URL을 수정하거나 삭제하는 웹훅 관리 순서도
등록 직후와 URL을 바꾼 직후에는 꼭 테스트를 보냅니다.

등록할 수 있는 이벤트 타입은 MESSAGE_RECEIVED(고객 문자 수신), SEND_RESULT(문자 발송 결과), CALL_RECEIVED(전화 착신 알림), CALL_COMPLETED(통화 종료 후 분석 결과) 네 가지입니다. API 문서가 권장하는 처리 기준은 타임아웃 10초, HTTP 2xx 응답 시 성공 처리, 비동기 처리 후 즉시 응답입니다. 웹훅 API는 비즈니스 기능 API이므로 비즈니스 요금제 그룹 또는 별도 허용된 그룹에서 쓸 수 있습니다.

등록 전에 수신 서버 준비하기

웹훅 URL은 https여야 합니다. 등록과 테스트를 하기 전에 그 주소에서 POST 요청을 받아 2xx로 응답하는 서버가 먼저 떠 있어야 합니다. 아래는 받은 내용을 로그로만 남기는 가장 작은 Express 수신 서버입니다.

JavaScript
const express = require('express');
const app = express();
app.use(express.json());

app.post('/webhooks/katcloud', (req, res) => {
  // 먼저 2xx로 응답하고, 실제 처리는 그 뒤에 합니다.
  res.status(200).send('OK');
  const { eventType, data } = req.body || {};
  console.log(new Date().toISOString(), eventType, JSON.stringify(data));
});

app.listen(3000, () => console.log('listening on 3000'));

로컬 개발 중이라면 터널링 도구로 로컬 포트를 https 주소로 잠시 노출해 테스트할 수 있습니다. 이때 노출된 주소는 누구나 호출할 수 있으므로 테스트가 끝나면 터널을 닫고, 등록한 웹훅도 운영 URL로 바꾸거나 삭제합니다.

테스트 페이로드의 구체적인 본문 형식은 API 문서에 따로 적혀 있지 않습니다. 그래서 수신 서버는 모르는 eventType이나 비어 있는 data가 와도 에러를 내지 말고 2xx로 응답하도록 만들어 두는 것이 안전합니다. 실제 이벤트 페이로드는 { "eventType": ..., "timestamp": ..., "data": { ... } } 구조입니다.

웹훅 조회와 등록: GET·POST /webhook

등록 전에 목록부터 확인합니다. 배포 스크립트가 실행될 때마다 POST /webhook을 호출하면 같은 설정이 여러 개 쌓일 수 있습니다.

Shell
curl -X GET "https://studio-gateway.zerocall.kr/webhook" \
  -H "x-api-key: $KAT_API_KEY"

curl -X POST "https://studio-gateway.zerocall.kr/webhook" \
  -H "x-api-key: $KAT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"eventType": "CALL_COMPLETED", "url": "https://api.example.com/webhooks/katcloud"}'

목록과 등록 응답의 각 항목에는 id, eventType, url, createdAt, updatedAt이 들어 있습니다. 아래 Python 스크립트는 이벤트마다 웹훅이 하나만 있도록 맞춘 뒤 바로 테스트까지 보냅니다. 같은 이벤트 타입에 다른 URL이 이미 있으면 새로 만들지 않고 URL만 수정합니다. 이벤트 타입 하나에 웹훅을 여러 개 둘 수 있는지는 문서에 명시돼 있지 않으므로, 이렇게 하나로 관리하는 쪽이 예측하기 쉽습니다.

Python
import os
import requests

BASE_URL = "https://studio-gateway.zerocall.kr"
session = requests.Session()
session.headers.update({
    "x-api-key": os.environ["KAT_API_KEY"],
    "Content-Type": "application/json",
})


def call(method, path, **kwargs):
    resp = session.request(method, BASE_URL + path, timeout=15, **kwargs)
    if not resp.ok:
        raise RuntimeError(f"{method} {path} -> {resp.status_code} {resp.text}")
    if not resp.content:
        return None
    body = resp.json()
    return body["result"] if isinstance(body, dict) and "result" in body else body


def ensure_webhook(event_type, url):
    same_type = [h for h in call("GET", "/webhook") if h["eventType"] == event_type]
    for hook in same_type:
        if hook["url"] == url:
            return hook  # 이미 원하는 대로 등록돼 있음
    if same_type:
        hook = same_type[0]
        call("PATCH", f"/webhook/{hook['id']}", json={"url": url})
        return {**hook, "url": url}
    return call("POST", "/webhook", json={"eventType": event_type, "url": url})


RECEIVER = "https://api.example.com/webhooks/katcloud"
for event in ["MESSAGE_RECEIVED", "SEND_RESULT", "CALL_RECEIVED", "CALL_COMPLETED"]:
    hook = ensure_webhook(event, RECEIVER)
    t = call("POST", f"/webhook/{hook['id']}/test")
    print(f"{event:17} id={hook['id']} success={t['success']} "
          f"status={t['statusCode']} {t['responseTime']}ms error={t['error']}")

연결 테스트: POST /webhook/{webhookId}/test 결과 읽기

POST /webhook/{webhookId}/test는 등록된 웹훅 URL로 테스트 페이로드를 보내고, 그 결과를 응답으로 돌려줍니다.

Shell
curl -X POST "https://studio-gateway.zerocall.kr/webhook/1/test" \
  -H "x-api-key: $KAT_API_KEY"
JSON
{
  "success": true,
  "statusCode": 200,
  "responseTime": 150,
  "error": null
}
내 스크립트가 KAT Cloud에 웹훅 테스트를 요청하면 KAT Cloud가 수신 서버로 테스트 페이로드를 보내고, 수신 서버의 응답 결과를 success와 statusCode로 돌려주는 순서
테스트 결과는 수신 서버가 KAT Cloud에 돌려준 응답을 그대로 요약합니다.

success는 테스트 성공 여부, statusCode는 수신 서버가 돌려준 HTTP 상태 코드, responseTime은 응답 시간(ms), error는 실패 시 에러 메시지입니다. 결과별로 의심할 지점은 다음과 같습니다.

테스트 결과의심할 원인확인할 것
success: true, 2xx정상실제 이벤트로 한 번 더 확인
statusCode 404·405경로 또는 메서드 불일치등록 URL의 경로, POST 라우트 존재 여부
statusCode 401·403내 서버의 인증 미들웨어가 막음웹훅 경로를 인증 예외로 두었는지
statusCode 413·400본문 파싱·크기 제한JSON 파서 설정, 본문 크기 제한
statusCode 5xx수신 핸들러 내부 에러서버 로그의 예외, 모르는 eventType 처리
error 메시지 있음연결 단계 실패DNS, TLS 인증서, 방화벽, 서버 기동 여부
responseTime이 길다응답 전에 무거운 처리즉시 2xx 응답 후 비동기 처리로 변경

특히 responseTime은 꾸준히 기록해 두면 좋습니다. 권장 타임아웃이 10초이므로 응답 시간이 수 초대로 올라가면, 응답 전에 DB 쓰기나 외부 API 호출을 하고 있지 않은지 살펴봅니다.

URL 수정과 삭제: PATCH·DELETE /webhook/{webhookId}

PATCH /webhook/{webhookId}는 웹훅 URL만 바꿉니다. 요청 본문은 새 https URL 하나입니다.

Shell
curl -X PATCH "https://studio-gateway.zerocall.kr/webhook/1" \
  -H "x-api-key: $KAT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://api-v2.example.com/webhooks/katcloud"}'

curl -X DELETE "https://studio-gateway.zerocall.kr/webhook/1" \
  -H "x-api-key: $KAT_API_KEY"

수정 가능한 필드는 url뿐이므로 이벤트 타입을 바꾸려면 기존 웹훅을 삭제하고 새로 등록합니다. 수정과 삭제의 응답 본문은 문서에 따로 적혀 있지 않으니, HTTP 2xx 여부로 성공을 판단하고 GET /webhook으로 결과를 다시 확인합니다.

수신 서버를 옮길 때는 아래 순서를 따르면 이벤트를 덜 놓칩니다.

  1. 1새 서버를 먼저 배포하고 기존 서버도 그대로 둡니다.
  2. 2PATCH로 URL을 새 주소로 바꿉니다.
  3. 3POST /webhook/{webhookId}/test로 새 주소의 응답을 확인합니다.
  4. 4실제 이벤트가 새 서버로 들어오는 것을 로그로 확인한 뒤 기존 서버를 내립니다.

실제 이벤트로 점검하고 놓친 이벤트 메우기

테스트가 성공해도 실제 이벤트 처리까지 검증된 것은 아닙니다. 등록이 끝나면 내 번호로 문자를 보내 MESSAGE_RECEIVED를, 전화를 걸어 CALL_RECEIVED와 CALL_COMPLETED를 직접 받아 봅니다. 수신 로그에는 eventType, 식별자(통화는 data.callHistoryId, 문자는 data.chatId), 받은 시각, 처리 결과를 남겨 두면 나중에 추적하기 쉽습니다.

수신 서버를 큐와 멱등 처리까지 갖춘 구조로 만드는 방법은 폴링 대신 웹훅: 통화 이벤트를 안정적으로 받는 서버 설계에서 다룹니다. 언어별 구현은 Node.js(Express) 웹훅 수신 서버와 Python(FastAPI) 웹훅 수신 서버 글을 참고하세요. 이벤트별 페이로드 필드는 API 문서의 웹훅 이벤트에, 설정 API 원문은 웹훅 항목에 있습니다.

자주 묻는 질문

웹훅 테스트가 실패하면 무엇부터 확인하나요?

KAT Cloud 웹훅 테스트가 실패하면 먼저 응답의 error와 statusCode를 봅니다. error에 메시지가 있으면 DNS·TLS 인증서·방화벽 같은 연결 문제를, statusCode가 4xx·5xx면 수신 서버의 경로·인증 설정·핸들러 에러를 확인합니다.

등록한 웹훅의 이벤트 타입을 바꿀 수 있나요?

KAT Cloud의 PATCH /webhook/{webhookId}는 url만 수정할 수 있습니다. 이벤트 타입을 바꾸려면 기존 웹훅을 DELETE /webhook/{webhookId}로 삭제하고 원하는 eventType으로 다시 등록합니다.

웹훅 URL에 http 주소를 써도 되나요?

KAT Cloud 웹훅 등록과 수정의 url은 https 주소여야 합니다. 로컬에서 개발할 때는 터널링 도구로 https 주소를 잠시 만들어 테스트하고, 운영에서는 유효한 인증서를 갖춘 서버 주소를 등록합니다.

테스트가 성공하면 실제 이벤트도 문제없이 받나요?

웹훅 테스트 성공은 KAT Cloud가 등록 URL에 닿고 수신 서버가 2xx로 응답했다는 뜻입니다. 실제 이벤트는 테스트와 본문이 다를 수 있으므로, 문자 수신과 통화를 직접 발생시켜 이벤트별 처리 로직까지 확인해야 합니다.

  • #웹훅
  • #Webhook 테스트
  • #디버깅
  • #KAT Cloud API

Get started

만든 AI에게 전화번호를 주세요.

070 번호 발급, SIP 직접 연결, 음성 AI 모델 연결, 문자·웹훅까지 API 하나로. 월 10,000원부터.