sumsub-manage-webhooks

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Sumsub — Manage Client Webhooks

Sumsub — 管理客户端Webhook

Lists, retrieves, creates, updates, and disables/enables
ClientWebhook
event subscriptions. Reads use
/resources/api/clientWebhooks
; writes use
/resources/api/agent/clientWebhooks
.
列出、获取、创建、更新以及禁用/启用
ClientWebhook
事件订阅。读取操作使用
/resources/api/clientWebhooks
;写入操作使用
/resources/api/agent/clientWebhooks

Endpoints

端点

VerbPathPurpose
GET
/resources/api/clientWebhooks
List webhooks on the tenant. Returns
EntityResult<ClientWebhook>
(
{list: {items: [...] }}
). Capped at the oldest 50 server-side (
getOldest50
).
GET
/resources/api/clientWebhooks/{id}
Read one webhook by id. Use this to resolve a
name
from a known id, or to verify what landed after a write.
POST
/resources/api/agent/clientWebhooks
Create. Body must NOT include
id
— server assigns it. (The model layer still does an internal upsert, but the request DTO is
ClientWebhookCreateRequest
without
id
.)
PATCH
/resources/api/agent/clientWebhooks
Update an existing webhook (by
id
in body). DTO is
ClientWebhookUpdateRequest
.
Permission required:
manageClientSettings
.
There is no DELETE and no
/stats
endpoint
on the public API — use the Sumsub dashboard UI when you need to delete a webhook or view per-webhook delivery stats.
请求方法路径用途
GET
/resources/api/clientWebhooks
列出租户下的webhook。返回
EntityResult<ClientWebhook>
(格式为
{list: {items: [...] }}
)。服务器端限制最多返回最早的50条(通过
getOldest50
实现)。
GET
/resources/api/clientWebhooks/{id}
通过ID读取单个webhook。可用于根据已知ID获取对应的
name
,或验证写入操作后的结果。
POST
/resources/api/agent/clientWebhooks
创建webhook。请求体不得包含
id
——由服务器分配ID。(模型层仍会执行内部更新操作,但请求DTO为不含
id
ClientWebhookCreateRequest
。)
PATCH
/resources/api/agent/clientWebhooks
更新现有webhook(通过请求体中的
id
指定)。DTO为
ClientWebhookUpdateRequest
所需权限:
manageClientSettings
公开API不提供DELETE接口和**
/stats
端点**——如需删除webhook或查看单个webhook的投递统计,请使用Sumsub控制台UI。

Auth — App Token + secret (sandbox only)

身份验证 — App Token + 密钥(仅限沙箱环境)

This skill talks to the public Sumsub API and signs each request per the authentication reference. The full how-it-works writeup lives in the
sumsub-api-auth
skill — read it if you hit
401 Invalid signature
.
⚠️ Sandbox tokens only. Do not accept or use a production App Token here. If the user offers one, refuse and ask them to generate a sandbox pair at https://cockpit.sumsub.com/checkus/devSpace/appTokens (toggle the workspace to Sandbox first, then Create). Token + secret are shown once — copy both before closing the dialog. The helper script enforces this — it rejects tokens that don't start with
sbx:
unless
SUMSUB_ALLOW_PROD=1
is set.
VarExample
SUMSUB_APP_TOKEN
sbx:...
— sandbox App Token from the dashboard.
SUMSUB_SECRET_KEY
The paired secret shown once at token creation.
SUMSUB_BASE
Optional. Defaults to
https://api.sumsub.com
.
If the user has already supplied credentials in conversation, reuse them; otherwise ask once before running. Never echo the secret back.
本技能调用Sumsub公开API,并按照身份验证参考文档对每个请求进行签名。详细的工作原理说明位于
sumsub-api-auth
技能文档中——如果遇到
401 Invalid signature
错误,请查阅该文档。
⚠️ 仅限沙箱令牌。请勿接受或使用生产环境的App Token。如果用户提供生产环境令牌,请拒绝并要求他们在https://cockpit.sumsub.com/checkus/devSpace/appTokens生成沙箱环境的令牌密钥对(先将工作区切换为Sandbox,再点击Create)。令牌和密钥仅显示一次——请在关闭对话框前复制两者。辅助脚本会强制验证这一点——除非设置了
SUMSUB_ALLOW_PROD=1
,否则会拒绝非
sbx:
开头的令牌。
变量示例
SUMSUB_APP_TOKEN
sbx:...
— 来自控制台的沙箱环境App Token。
SUMSUB_SECRET_KEY
创建令牌时一次性显示的配对密钥。
SUMSUB_BASE
可选参数。默认值为
https://api.sumsub.com
如果用户已在对话中提供凭证,请复用;否则在执行操作前询问一次。切勿回显密钥。

Sandbox-only scope — production webhooks must be created by a human

仅限沙箱环境范围 — 生产环境webhook必须由人工创建

Because this skill only accepts sandbox App Tokens, every webhook it creates, updates, or toggles lives in the sandbox workspace. Sandbox and production are separate tenants on Sumsub's side — there is no "promote to prod" path, and re-running this skill with a production token is not the right way to set up a real webhook.
When the user is ready to wire up a production webhook:
  • Do not offer to do it from this skill, even if the user asks.
  • Do not ask for or accept a production App Token (the script will refuse it without
    SUMSUB_ALLOW_PROD=1
    , and you should not suggest that override).
  • Tell the user that the production webhook — target URL, signing secret, event subscription, custom headers — should be configured by a human directly in the Sumsub dashboard (Integrations → Webhooks, with the workspace toggle on Production). Setting up a production webhook is a security-sensitive operation (the signing secret authenticates real PII deliveries) and the audit trail should attribute it to a person.
  • The right workflow is: use this skill to prototype against sandbox, capture the final spec the user wants (event list, headers, signature algorithm), then hand that spec off as plain documentation so a human can recreate it in production.
由于本技能仅接受沙箱环境的App Token,因此通过它创建、更新或切换状态的所有webhook均位于沙箱工作区中。Sumsub的沙箱环境与生产环境是相互独立的租户——不存在“升级到生产环境”的路径,使用生产环境令牌重新运行本技能不是设置正式webhook的正确方式。
当用户准备配置生产环境webhook时:
  • 请勿通过本技能提供配置服务,即使用户提出要求。
  • 请勿请求或接受生产环境的App Token(脚本会在未设置
    SUMSUB_ALLOW_PROD=1
    的情况下拒绝该令牌,且你不应建议使用该覆盖参数)。
  • 告知用户生产环境webhook的目标URL、签名密钥、事件订阅、自定义标头等配置必须由人工直接在Sumsub控制台中完成(路径为Integrations → Webhooks,需将工作区切换为Production)。配置生产环境webhook是一项安全敏感操作(签名密钥用于验证真实PII数据的投递),审计记录需归属到具体人员。
  • 正确的流程是:使用本技能在沙箱环境中进行原型开发,记录用户所需的最终规格(事件列表、标头、签名算法),然后将该规格作为文档交付给人工,由其在生产环境中重新配置。

Subcommands

子命令

manage_webhooks.sh
is the orchestrator:
bash
manage_webhooks.sh list                       # GET all webhooks (table summary; capped at 50)
manage_webhooks.sh list --json                # raw JSON of all webhooks
manage_webhooks.sh get <webhookId>            # one webhook (filtered from the list)
manage_webhooks.sh create <spec.json>         # POST without id  (compact spec → ClientWebhook)
manage_webhooks.sh update <spec.json>         # POST with id     (spec MUST contain id)
manage_webhooks.sh disable <webhookId>        # GET → flip disabled=true → POST
manage_webhooks.sh enable  <webhookId>        # GET → flip disabled=false → POST
create
and
update
both call
build_webhook_payload.py
to expand the compact spec.
manage_webhooks.sh
是编排脚本:
bash
manage_webhooks.sh list                       # 获取所有webhook(表格摘要;最多显示50条)
manage_webhooks.sh list --json                # 所有webhook的原始JSON数据
manage_webhooks.sh get <webhookId>            # 获取单个webhook(从列表中筛选)
manage_webhooks.sh create <spec.json>         # 创建webhook(无id的POST请求,精简规格转换为ClientWebhook)
manage_webhooks.sh update <spec.json>         # 更新webhook(含id的POST请求,规格必须包含id)
manage_webhooks.sh disable <webhookId>        # 获取webhook → 设置disabled=true → 提交POST请求
manage_webhooks.sh enable  <webhookId>        # 获取webhook → 设置disabled=false → 提交POST请求
create
update
命令均会调用
build_webhook_payload.py
来扩展精简规格。

Before submitting: target must be publicly reachable

提交前注意:目标地址必须可公开访问

Sumsub delivers webhooks from its own infrastructure, so the
target
URL has to resolve and accept connections from the public internet. Common gotcha: users paste
http://localhost:3000/webhook
(or
127.0.0.1
,
0.0.0.0
,
::1
) while developing locally. Sumsub accepts the URL at creation time but every delivery will fail — and
targets
like these are rejected by the skill's payload builder up front.
If the user supplies a localhost-ish URL, don't submit it. Instead, walk them through exposing the local server through a public tunnel before creating the webhook:
  1. Suggest ngrok (the most common choice). On macOS:
    brew install ngrok/ngrok/ngrok
    . Other platforms: download from the link. First-time users need a free ngrok account to grab an auth token, then
    ngrok config add-authtoken <TOKEN>
    once.
  2. Ask which port their local webhook receiver listens on (typically 3000 / 8080 / 4000).
  3. Have them run
    ngrok http <port>
    in a separate terminal and keep it open.
  4. ngrok prints a
    Forwarding https://<random>.ngrok-free.app -> http://localhost:<port>
    line. The
    https://...ngrok-free.app
    part is the public URL.
  5. Append the receiver's webhook path (e.g.
    /webhook
    ,
    /sumsub
    ) and use the full URL as
    target
    . Then re-run the
    create
    subcommand.
Heads-up to mention: on the free ngrok plan the public URL changes every time
ngrok
restarts — the webhook will need to be re-
update
d (POST with the existing
id
and the new
target
) each session. A reserved domain (paid) or
--domain=<your-subdomain>
keeps it stable. Alternatives if the user prefers: Cloudflare Tunnel (
cloudflared tunnel
), Tailscale Funnel, localtunnel — same idea, same procedure.
Sumsub从自身基础设施投递webhook,因此
target
URL必须能从公网解析并接受连接。常见误区:用户在本地开发时粘贴
http://localhost:3000/webhook
(或
127.0.0.1
0.0.0.0
::1
)。Sumsub会在创建时接受该URL,但每次投递都会失败——且此类
target
会被本技能的负载构建器提前拒绝。
如果用户提供本地主机类URL,请勿提交。相反,请引导他们通过公共隧道暴露本地服务器后再创建webhook:
  1. 推荐使用ngrok(最常用的选择)。在macOS上:
    brew install ngrok/ngrok/ngrok
    。其他平台:从链接下载。首次使用的用户需要免费的ngrok账户获取认证令牌,然后执行
    ngrok config add-authtoken <TOKEN>
    完成配置。
  2. 询问用户本地webhook接收器监听的端口(通常为3000 / 8080 / 4000)。
  3. 让他们在单独的终端中运行
    ngrok http <port>
    并保持终端开启。
  4. ngrok会输出一行
    Forwarding https://<random>.ngrok-free.app -> http://localhost:<port>
    。其中
    https://...ngrok-free.app
    部分即为公共URL。
  5. 追加接收器的webhook路径(例如
    /webhook
    /sumsub
    ),将完整URL作为
    target
    。然后重新运行
    create
    子命令。
需要提醒用户:免费版ngrok的公共URL每次重启
ngrok
都会改变——每次会话都需要重新
update
webhook(使用现有
id
和新
target
提交POST请求)。付费版的预留域名或使用
--domain=<your-subdomain>
参数可保持URL稳定。如果用户偏好其他工具,可选择Cloudflare Tunnel(
cloudflared tunnel
)、Tailscale Funnel、localtunnel——原理相同,操作步骤一致。

Compact spec for
create
/
update

create
/
update
的精简规格

yaml
undefined
yaml
undefined

Identity (omit on create; required on update)

标识信息(创建时可省略;更新时必填)

id: 698bfc... # id from a previous list / create response
id: 698bfc... # 来自之前列表或创建响应的id

Display + addressing

显示信息与地址配置

name: "Production webhook" # required (no min length but the dashboard expects something) description: "Sends KYC events to our backend" target: "https://example.com/sumsub/webhook" # required — destination URL (or slack / email / telegram address depending on targetType) targetType: http # http | email | slack | telegram (default: http)
name: "Production webhook" # 必填(无最小长度要求,但控制台需要填写内容) description: "Sends KYC events to our backend" target: "https://example.com/sumsub/webhook" # 必填——目标URL(或根据targetType填写slack/email/telegram地址) targetType: http # http | email | slack | telegram (默认值: http)

Subscription

订阅配置

types: # required — event-type strings (see "Event types" below)
  • applicantReviewed
  • applicantPending
  • applicantOnHold
  • applicantCreated applicantType: individual # individual | company (omit to subscribe to both) sourceKeys: [] # optional — restrict to specific source keys
types: # 必填——事件类型字符串(见下方“事件类型”)
  • applicantReviewed
  • applicantPending
  • applicantOnHold
  • applicantCreated applicantType: individual # individual | company (省略则同时订阅两类) sourceKeys: [] # 可选——限制为特定source key

Auth + delivery

身份验证与投递配置

secretKey: "..." # HMAC secret used to sign payloads signatureAlgorithm: HMAC_SHA256_HEX # HMAC_SHA1_HEX | HMAC_SHA256_HEX | HMAC_SHA512_HEX (default: SHA256) headers: # optional extra HTTP headers added to each delivery
  • { key: "X-Source", value: "sumsub" }
  • { key: "Authorization", value: "Bearer ${MY_TOKEN}" } # caller substitutes before sending
secretKey: "..." # 用于签名负载的HMAC密钥 signatureAlgorithm: HMAC_SHA256_HEX # HMAC_SHA1_HEX | HMAC_SHA256_HEX | HMAC_SHA512_HEX (默认值: SHA256) headers: # 可选——添加到每次投递的额外HTTP标头
  • { key: "X-Source", value: "sumsub" }
  • { key: "Authorization", value: "Bearer ${MY_TOKEN}" } # 调用方需在发送前替换变量

Lifecycle flags

生命周期标识

disabled: false # default false; set true to pause without deleting notResendFailedWebhooks: false # default false; true = no automatic retries on delivery failure

The builder validates enums (`targetType`, `signatureAlgorithm`, `applicantType`), rejects empty `types`, and wraps `headers` so that the `key`/`value` shape matches `ClientWebhookHeader`. Unknown keys pass through (escape hatch).
disabled: false # 默认值false;设置为true可暂停webhook而不删除 notResendFailedWebhooks: false # 默认值false;true表示投递失败时不自动重试

构建器会验证枚举值(`targetType`、`signatureAlgorithm`、`applicantType`),拒绝空的`types`数组,并将`headers`包装为符合`ClientWebhookHeader`的`key`/`value`格式。未知字段会直接传递(作为兼容机制)。

Event types (
types[]
)

事件类型(
types[]

The OpenAPI keeps
types
as a free-form
string[]
. The names below cover the commonly-emitted Sumsub events. Unknown event types are silently accepted server-side and the webhook simply never fires — so typos are not caught by the API.
GroupEvent typeWhen it fires
Applicant lifecycle
applicantCreated
New applicant created
applicantPrechecked
Pre-screen complete
applicantPending
Submitted for review
applicantReviewed
Final review answer (GREEN / RED) reached
applicantOnHold
Review held / paused
applicantActivated
Applicant activated
applicantDeactivated
Applicant deactivated
applicantReset
Verification reset (retry)
applicantLevelChanged
Level reassigned
applicantTagsChanged
Tags added/removed
applicantPersonalInfoChanged
Personal info edited
applicantDeleted
Applicant deleted
applicantPersonalDataDeleted
GDPR personal-data erasure executed
Action workflow
applicantActionPending
/
applicantActionReviewed
/
applicantActionOnHold
Action-flow events
Workflow
applicantWorkflowCompleted
Workflow run finished (not
applicantWorkflowRunCompleted
)
Video ident
videoIdentStatusChanged
Live status update
videoIdentCompositionCompleted
Recording assembly finished
KYT (applicant-scoped)
applicantKytTxnApproved
/
applicantKytTxnRejected
/
applicantKytTxnReviewed
/
applicantKytTxnDeleted
/
applicantKytTxnDataChanged
/
applicantKytTxnAwaitingUser
/
applicantKytOnHold
Per-applicant transaction-monitoring events
KYT (case-scoped)
kytCaseCreated
/
kytCaseStatusChanged
/
kytCaseReviewed
KYT case-management events (note: it's
kytCaseStatusChanged
, not
kytCaseUpdated
)
AML case
amlCaseApproved
/
amlCaseRejected
/
amlCaseOnHold
AML-case disposition events
Travel Rule
travelRuleAction
Travel-rule lifecycle events
KYB
kybCompanyActivity
KYB ongoing-monitoring events
The skill forwards whatever the caller writes — no client-side validation, since Sumsub may add events faster than this list updates.
OpenAPI将
types
定义为自由格式的
string[]
。以下名称涵盖了Sumsub常用的事件类型。服务器会静默接受未知事件类型,但webhook不会触发——因此API不会捕获拼写错误。
分组事件类型触发时机
申请人生命周期
applicantCreated
创建新申请人时
applicantPrechecked
预筛选完成时
applicantPending
提交审核时
applicantReviewed
得出最终审核结果(通过/拒绝)时
applicantOnHold
审核暂停时
applicantActivated
申请人激活时
applicantDeactivated
申请人停用
applicantReset
验证重置(重试)时
applicantLevelChanged
等级重新分配时
applicantTagsChanged
添加/移除标签时
applicantPersonalInfoChanged
修改个人信息时
applicantDeleted
删除申请人时
applicantPersonalDataDeleted
执行GDPR个人数据擦除时
操作工作流
applicantActionPending
/
applicantActionReviewed
/
applicantActionOnHold
操作流事件
工作流
applicantWorkflowCompleted
工作流运行完成时(注意:不是
applicantWorkflowRunCompleted
视频身份验证
videoIdentStatusChanged
实时状态更新时
videoIdentCompositionCompleted
录制文件合成完成时
KYT(申请人范围)
applicantKytTxnApproved
/
applicantKytTxnRejected
/
applicantKytTxnReviewed
/
applicantKytTxnDeleted
/
applicantKytTxnDataChanged
/
applicantKytTxnAwaitingUser
/
applicantKytOnHold
针对申请人的交易监控事件
KYT(案例范围)
kytCaseCreated
/
kytCaseStatusChanged
/
kytCaseReviewed
KYT案例管理事件(注意:是
kytCaseStatusChanged
不是
kytCaseUpdated
AML案例
amlCaseApproved
/
amlCaseRejected
/
amlCaseOnHold
AML案例处置事件
旅行规则
travelRuleAction
旅行规则生命周期事件
KYB
kybCompanyActivity
KYB持续监控事件
本技能会直接转发调用方填写的事件类型——不进行客户端验证,因为Sumsub新增事件的速度可能快于本列表的更新速度。

Outputs

输出结果

  • list
    — table with
    id
    ,
    name
    ,
    target
    ,
    disabled
    ,
    types[]
    ,
    applicantType
    ,
    signatureAlgorithm
    ,
    createdAt
    .
  • get
    — the full single webhook JSON (with
    secretKey
    redacted in the output as a defensive measure).
  • create
    /
    update
    — the persisted
    ClientWebhook
    (with server-assigned
    id
    on create) and a one-line summary.
  • disable
    /
    enable
    — reports the new
    disabled
    value.
  • list
    — 表格形式展示
    id
    name
    target
    disabled
    types[]
    applicantType
    signatureAlgorithm
    createdAt
  • get
    — 单个webhook的完整JSON数据(输出中会自动隐藏
    secretKey
    作为安全措施)。
  • create
    /
    update
    — 持久化后的
    ClientWebhook
    (创建时包含服务器分配的
    id
    )以及一行摘要信息。
  • disable
    /
    enable
    — 报告更新后的
    disabled
    状态值。

Worked examples

示例

  • examples/basic-http.json
    — minimal webhook: HTTPS endpoint, four applicant-lifecycle events, SHA-256 signing.
  • examples/with-headers-and-restrictions.json
    — broad event set scoped to a specific
    sourceKey
    , with custom HTTP headers.
  • examples/legacy-sha1.json
    — SHA1-signed webhook, for receivers that already verify SHA1.
  • examples/update-existing.json
    — same as basic but with
    id
    set, demonstrating the update path.
  • examples/basic-http.json
    — 基础webhook示例:HTTPS端点、四个申请人生命周期事件、SHA-256签名。
  • examples/with-headers-and-restrictions.json
    — 包含广泛事件集,限定特定
    sourceKey
    ,并带有自定义HTTP标头。
  • examples/legacy-sha1.json
    — 使用SHA1签名的webhook示例,适用于已验证SHA1的接收器。
  • examples/update-existing.json
    — 与基础示例相同,但包含
    id
    ,演示更新流程。

See also

另请参阅