Outbound 웹훅 관리
PAT로 Outbound 웹훅(ZeroTalk → 내 서버)을 직접 등록·관리하는 엔드포인트입니다. 대시보드 없이 BFF에서 웹훅을 프로비저닝하고 상태를 모니터링할 수 있습니다.
- Outbound 웹훅 (이 페이지) — ZeroTalk가 내 서버로 이벤트를 보냅니다. 페이로드·서명·전달 규약은 웹훅 문서를 참고하세요.
- Inbound 웹훅 설정(
inbound-webhook-configs) — 외부 메신저 공급자(kakao·naver 등)가 ZeroTalk로 메시지를 전달하는 수신 설정입니다. 조회 전용이며 엔드포인트 카탈로그에 있습니다.
Base: /api/public/v1/outbound-webhooks · 인증: Authorization: Bearer ztpat_… · Scope: 조회는 webhooks:read, 변경은 webhooks:write.
엔드포인트 요약
| Method · Path | Scope | 용도 |
|---|---|---|
GET /outbound-webhooks | webhooks:read | 목록 (시크릿 미반환) |
POST /outbound-webhooks | webhooks:write | 생성 (평문 secret 1회 반환) |
GET /outbound-webhooks/{id} | webhooks:read | 단건 조회 (status·failure_count·last_delivered_at) |
PATCH /outbound-webhooks/{id} | webhooks:write | name·url·event_filters 수정 (부분) |
DELETE /outbound-webhooks/{id} | webhooks:write | 삭제 |
POST /outbound-webhooks/{id}/regenerate-secret | webhooks:write | 시크릿 회전 (평문 1회 반환) |
POST /outbound-webhooks/{id}/toggle | webhooks:write | 활성/비활성 전환 (재활성 시 error에서 failure_count 리셋) |
GET /outbound-webhooks/{id}/delivery-logs | webhooks:read | 최근 전달 시도 |
서명 secret은 생성과 시크릿 회전 응답에서만 평문으로 반환됩니다. 목록·단건 조회는 시크릿을 절대 반환하지 않습니다. 받은 즉시 서버에 저장하세요.
URL 제약
- HTTPS만 허용됩니다
- 사설·예약 IP 대역은 차단됩니다 (등록 시점 + 전달 시점 양쪽에서 SSRF·DNS rebinding 검증)
자세한 차단 규칙은 웹훅 설정과 동일합니다.
목록 조회
GET /outbound-webhooks
- Scope:
webhooks:read
curl "https://api.talk.zeroworks.ai/api/public/v1/outbound-webhooks" \
-H "Authorization: Bearer ztpat_..."
응답
{
"success": true,
"data": [
{
"id": "wh-1a2b-...",
"name": "My BFF webhook",
"url": "https://bff.example.com/zerotalk/webhook",
"event_filters": ["message.created", "channel.assigned"],
"status": "active",
"failure_count": 0,
"last_delivered_at": "2026-06-02T01:23:45Z",
"created_at": "2026-06-01T00:00:00Z",
"updated_at": "2026-06-02T01:23:45Z"
}
]
}
last_delivered_at은 전달 이력이 없으면, error_message는 직전 전달이 성공했으면(또는 이력이 없으면) null이 아니라 키가 생략됩니다. secret은 읽기 경로에서 항상 생략됩니다(생성·회전 응답에서만 1회 노출).
생성
POST /outbound-webhooks
- Scope:
webhooks:write - Body
| 필드 | 타입 | 설명 |
|---|---|---|
name | string | 웹훅 이름 (필수, 1–255자) |
url | string | 수신 HTTPS URL (필수, 최대 2048자) |
event_filters | string[] · 선택 | 구독할 이벤트 목록. 비우면 전체 구독 |
curl -X POST "https://api.talk.zeroworks.ai/api/public/v1/outbound-webhooks" \
-H "Authorization: Bearer ztpat_..." \
-H "Content-Type: application/json" \
-d '{
"name": "My BFF webhook",
"url": "https://bff.example.com/zerotalk/webhook",
"event_filters": ["message.created", "channel.assigned"]
}'
응답 — 201. secret은 이 응답에서만 평문으로 반환됩니다.
{
"success": true,
"data": {
"id": "wh-1a2b-...",
"name": "My BFF webhook",
"url": "https://bff.example.com/zerotalk/webhook",
"event_filters": ["message.created", "channel.assigned"],
"status": "active",
"secret": "9f8e7d...64자hex",
"failure_count": 0,
"created_at": "2026-06-01T00:00:00Z",
"updated_at": "2026-06-01T00:00:00Z"
}
}
단건 조회
GET /outbound-webhooks/{id}
- Scope:
webhooks:read - 모니터링에 쓰는
status·failure_count·last_delivered_at을 포함하며, 직전 전달이 실패했을 때만error_message가 추가됩니다 (시크릿 제외).
{
"success": true,
"data": {
"id": "wh-1a2b-...",
"name": "My BFF webhook",
"url": "https://bff.example.com/zerotalk/webhook",
"event_filters": ["message.created", "channel.assigned"],
"status": "active",
"failure_count": 0,
"last_delivered_at": "2026-06-02T01:23:45Z",
"created_at": "2026-06-01T00:00:00Z",
"updated_at": "2026-06-02T01:23:45Z"
}
}
수정
PATCH /outbound-webhooks/{id} — name·url·event_filters를 부분 수정합니다 (보낸 필드만 변경).
- Scope:
webhooks:write
curl -X PATCH "https://api.talk.zeroworks.ai/api/public/v1/outbound-webhooks/wh-1a2b-..." \
-H "Authorization: Bearer ztpat_..." \
-H "Content-Type: application/json" \
-d '{ "name": "Renamed webhook", "event_filters": ["message.created"] }'
event_filters를 생략하면 구독은 그대로 유지됩니다.[](빈 배열)을 보내면 모든 필터가 초기화되어 전체 이벤트 구독으로 바뀝니다(생성 시 빈 필터와 동일). 이벤트 수신을 멈추려면 빈 필터를 보내지 말고 활성/비활성 전환으로 웹훅을 비활성화하세요.
삭제
DELETE /outbound-webhooks/{id}
- Scope:
webhooks:write - 응답:
204 No Content
시크릿 회전
POST /outbound-webhooks/{id}/regenerate-secret — 서명 시크릿을 회전합니다.
- Scope:
webhooks:write - 새 시크릿은 응답에서만 평문으로 반환됩니다. 서버 측 grace 기간이 없으므로, 회전 직후 짧은 시간 동안 옛 시크릿으로 서명된 요청이 도착할 수 있습니다 (서명 검증 참고).
{ "success": true, "data": { "id": "wh-1a2b-...", "secret": "a1b2c3...64자hex" } }
활성/비활성 전환
POST /outbound-webhooks/{id}/toggle — 웹훅을 활성/비활성으로 전환합니다.
- Scope:
webhooks:write - 웹훅이 연속 실패로
status=error가 되어 자동 비활성화된 경우, toggle로 재활성화하면failure_count가 리셋되고 다시active가 됩니다 (자동 비활성화 규칙은 전달 참고). - 재활성화하면 비활성 기간에 보류된 미전달분이 이벤트 접수 시점부터 24시간 윈도우 내에서 전달됩니다.
{ "success": true, "data": { "id": "wh-1a2b-...", "status": "active", "failure_count": 0 } }
전달 로그
GET /outbound-webhooks/{id}/delivery-logs — 최근 전달 시도(성공 여부·HTTP 상태·에러·소요 시간)를 조회합니다.
- Scope:
webhooks:read - 쿼리:
limit(기본 50·최대 100),offset(기본 0) — offset 기반 페이징. 응답은data.items/data.total/data.has_more.
{
"success": true,
"data": {
"items": [
{
"id": 1,
"webhook_id": "wh-1a2b-...",
"event_type": "message.created",
"success": true,
"http_status": 200,
"duration_ms": 142,
"created_at": "2026-06-02T01:23:45Z"
}
],
"total": 1,
"has_more": false
}
}
success(불리언)는 각 항목에 항상 포함되는 성공 여부 판별 필드입니다. http_status·error_message는 값이 없으면 null이 아니라 키가 생략됩니다 — 성공한 시도(success: true)는 error_message가 빠지고, HTTP 응답을 받지 못한 시도는 http_status가 빠집니다.
참고
- 페이로드·서명·재시도·멱등 등 수신 측 처리 규약은 웹훅 문서를 참고하세요.
- 콘솔 전체 흐름(웹훅 자가 등록 → 수신 → 렌더 → 답장)은 상담 콘솔 임베드 가이드에 있습니다.