sumsub-create-kyt-rules
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSumsub — KYT Rules, Applicant Scoring & Risk Levels
Sumsub — KYT规则、申请人评分与风险等级
Configures the full KYT transaction monitoring stack:
- Rules — translates user intent into payloads and POSTs them one at a time. Supports creating new rules and modifying existing ones (by posting a new revision). New rules always start in testMode (
KytTxnRule) — they appear indryRun: truebut do not affect the live outcome until activated in the dashboard.dryScore - Tags & applicant scoring — creates and configures tags (named risk markers) and the assessment that maps tag weights into a composite applicant risk score.
- Risk levels — configures the score thresholds that translate a numeric risk score into a human-readable label (e.g. Low / Med / High).
Rules, tags, and risk levels form a single pipeline: a rule fires → applies tags → tags accumulate a weighted score → score maps to a risk level.
配置完整的KYT交易监控体系:
- 规则 — 将用户意图转换为负载并逐个进行POST请求。支持创建新规则和修改现有规则(通过提交新版本)。新规则默认处于测试模式(
KytTxnRule)—— 它们会出现在dryRun: true中,但在仪表板激活前不会影响实际结果。dryScore - 标签与申请人评分 — 创建并配置标签(命名风险标记),以及将标签权重映射为综合申请人风险评分的评估机制。
- 风险等级 — 配置评分阈值,将数值型风险评分转换为易读的标签(如低/中/高)。
规则、标签和风险等级构成一个完整流程:规则触发 → 应用标签 → 标签累计加权评分 → 评分映射到风险等级。
Endpoints
接口
| Method | Path | Description | Response |
|---|---|---|---|
| | List existing rules. Supports | |
| | Create a new rule or a new revision. For creation omit | 200 rule object · 400 error message |
| | List rules in a bundle by name and installation status. | |
| | Read one rule by id. Requires | rule object |
| | List all KYT tags with their assessment configuration and linked rules. | |
| | Create or update a KYT tag. Body: | 200 empty body |
| | Get current applicant assessment scoring configuration (tag weights, hierarchy, company beneficiary weights). | assessment settings object |
| | Replace applicant assessment scoring configuration. Requires | 200 updated assessment settings |
| | Get current applicant risk level thresholds. | risk level settings object |
| | Replace risk level thresholds. Body: min 2 items, each with | 200 updated risk level settings |
| | Fetch a client list by name. 404 if not found. Requires | client list object |
| | Create a client list (idempotent). Requires | client list object |
See for the full rule SumScript expression field reference and type system.
references/kyt-rule-schema.md| 方法 | 路径 | 描述 | 响应 |
|---|---|---|---|
| | 列出现有规则。支持 | |
| | 创建新规则或新版本。创建时省略 | 200规则对象 · 400错误信息 |
| | 按名称和安装状态列出规则包中的规则。 | |
| | 根据ID读取单个规则。需要 | 规则对象 |
| | 列出所有KYT标签及其评估配置和关联规则。 | |
| | 创建或更新KYT标签。请求体: | 200空响应体 |
| | 获取当前申请人评估评分配置(标签权重、层级、公司受益人权重)。 | 评估配置对象 |
| | 替换申请人评估评分配置。需要 | 200更新后的评估配置 |
| | 获取当前申请人风险等级阈值。 | 风险等级配置对象 |
| | 替换风险等级阈值。请求体至少包含2项,每一项需包含 | 200更新后的风险等级配置 |
| | 根据名称获取客户列表。不存在则返回404。需要 | 客户列表对象 |
| | 创建客户列表(幂等操作)。需要 | 客户列表对象 |
完整的规则SumScript表达式字段参考和类型系统请查看。
references/kyt-rule-schema.mdAuth — 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
skill — read it if you hit .
sumsub-api-auth401 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:
| Var | Example |
|---|---|
| |
| The paired secret shown once at token creation. |
| Optional. Defaults to |
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-auth401 Invalid signature⚠️ 仅支持沙箱令牌。 请勿接受或使用生产环境的App Token。如果用户提供生产令牌,请拒绝并要求他们在https://cockpit.sumsub.com/checkus/devSpace/appTokens生成沙箱令牌对(先将工作区切换为Sandbox,再点击Create)。令牌和密钥仅显示一次——关闭对话框前请复制两者。辅助脚本会强制执行此限制——拒绝所有不以开头的令牌。sbx:
| 变量 | 示例 |
|---|---|
| |
| 创建令牌时显示的配对密钥。 |
| 可选,默认值为 |
如果用户已在对话中提供凭据,请复用;否则在执行前询问一次。切勿回显密钥。
Tenant Entitlements
租户权限
KYT rules require the entitlement at minimum. Additional per-type requirements apply:
KYTRule | Required entitlement |
|---|---|
| |
| |
| |
| |
| |
Before creating any rules, run from the
skill directory
and verify (and any type-specific permission) is present in the array.
bash scripts/check_permissions.shsumsub-check-permissionsKYTallowedIf is not in — stop immediately. Do not build or POST any rules.
Tell the user the entitlement is missing and that they need to contact their CSM or Sumsub support to get it enabled.
KYTallowedKYT规则至少需要权限。不同类型的规则还有额外的权限要求:
KYT规则 | 所需权限 |
|---|---|
| |
| |
| |
| |
| |
创建任何规则前,请运行技能目录中的,并验证数组中是否包含(以及对应类型所需的权限)。
sumsub-check-permissionsbash scripts/check_permissions.shallowedKYT如果中没有——立即停止操作。 不要构建或POST任何规则。告知用户缺少该权限,需要联系他们的客户成功经理或Sumsub支持团队启用。
allowedKYTProcedure
操作流程
-
Fetch tenant entitlements. Runand store the
sumsub-check-permissionsarray. Verifyallowedis present; abort with an explanation if missing.KYT -
Determine mode — create or modify.
- Modify mode: the user provides a rule (immutable slug, e.g.
name) or enough context to identify one. Runfin-ben-pep-ter-list-abo-thr-WoGD, find the rule bybash ${CLAUDE_SKILL_DIR}/scripts/get_kyt_rules.shorname, and store the full current document. Show the user the existingtitle,conditionEl,score, andaction, then collect only the fields they want to change. Skip to step 2a.types - Create mode: the user describes a new rule. Run and check for a title collision — the server creates a duplicate on every POST with no deduplication. If a rule with a matching title already exists, offer to skip creation and modify the existing one instead.
bash ${CLAUDE_SKILL_DIR}/scripts/get_kyt_rules.sh
- Modify mode: the user provides a rule
-
Translate user intent to compact specs. For each rule the user wants to create, collect:
- (≤128 chars, required)
title - — one or more transaction types (see table below)
types - A plain-English description of the condition (used to generate in step 3)
conditionEl - (integer, default 0),
score(action|score|onHold|awaitUser)reject - Optional: ,
desc,tags,bundleName,priority,stopOnMatchsourceKeys
2a. Ensure client lists exist — if any rule will reference in its ,
verify each list exists before generating or validating expressions:
- HTTP 200 → list exists; proceed.
- HTTP 404 → list does not exist; create it:
The POST is idempotent — it succeeds even if the list was created in the meantime.
Do not proceed to validation or rule creation until every referenced client list is confirmed.
clientLists.<name>conditionElbash bash ${CLAUDE_SKILL_DIR}/scripts/get_kyt_client_list.sh <listName> bash bash ${CLAUDE_SKILL_DIR}/scripts/create_kyt_client_list.sh <listName> - Generate . For each rule that needs a condition:
conditionEl- Construct the SumScript boolean expression using the type definitions in
.
references/kyt-rule-schema.md - Do not guess field paths. Only use fields confirmed in the schema — verify the path from root to leaf before writing the expression.
- For default-currency amount checks use (normalized amount), not
data.info.amountInDefaultCurrency(source-currency amount) — unless the user explicitly asks for source-currency filtering.data.info.amount - Scheduled rules () do NOT use
types: ["scheduledEvent"]for their trigger — useconditionElinstead (see references/kyt-rule-schema.md).noEventTrigger - For multi-branch scoring (different score per sub-condition), use inside
addScoreIfand set the payload-levelconditionEl,score: 0(see Scoring section).action: "score"
- Construct the SumScript boolean expression using the type definitions in
3a. Validation is built into POST — the server validates syntax during the create call (step 6). No separate pre-flight step is needed. If validation fails the server returns HTTP 400 with an error message describing the problem — fix the expression and re-POST.
conditionEl-
Build payload. Assemble the JSON for each rule following these constraints:Create mode:
- Required fields only: ,
title(min 1 value).types - For rules: include
eval,conditionEl, andscorewhen relevant.action - Never send or
id— the server assigns both.name
Modify mode (new revision):- Include — the immutable slug from the existing rule.
"name": "<existing-slug>" - Include — an explicit null. This signals the server to create a new revision rather than a new rule. Do not use
"id": null(empty string) — Jackson will reject it as an invalid ObjectId and return HTTP 400."id": "" - Carry over all unchanged fields from the existing rule document. Only change the fields the user asked to modify.
- and
titleremain required.types
Both modes — always apply:- Never send server-assigned or audit fields: ,
clientId,actual, timestamps (revision,createdAt,modifiedAt), author fields.archivedAt - Never send or
scope— license-control fields managed by the server.bgCheckTargets - Create mode: never send or
dryRun; the server initialises them todisabledandtrue.false - Modify mode: carry over and
dryRunfrom the existing rule document — the server uses the sent values to preserve the rule's current activation and test-mode state across the revision.disabled - Omit empty optional containers: ,
sourceKeys: [],caseAction: {},applicantChange: {},applicantActions: {"actions": {}},varDefinitions: {"definitions": []}.varValues: {"values": {}} - Do not mix with other transaction types.
scheduledEvent
- Required fields only:
-
Show each payload to the user and ask for explicit confirmation before any POST.
-
POST each rule via. Rules are created one at a time. Check the exit code:
bash ${CLAUDE_SKILL_DIR}/scripts/post_kyt_rule.sh < payload.json- Exit 0 → HTTP 200; the response body is the created . Proceed to step 7.
KytTxnRuleView - Exit 1 → HTTP 4xx/5xx; the response body contains the error message. Surface it verbatim, fix the expression, and re-POST.
Retry cap: allow at most 10 POST attempts per rule. If the 10th attempt still fails, mark that rule as failed, record the last error message, and move on to the next rule — do not abort the entire batch. Report all failed rules in step 9. - Exit 0 → HTTP 200; the response body is the created
-
GET each created rule back via. Compare
bash ${CLAUDE_SKILL_DIR}/scripts/get_kyt_rule.sh {id}and key fields to what was sent. Report any discrepancy.conditionEl -
Build the dashboard link for each rule:
https://cockpit.sumsub.com/checkus/kyt/rulesManager/rulesList/{name}?clientId={clientId}&xSNSEnv=sbxandnamecome from the POST response body. Render as a clickable markdown link.clientId -
Report — for each rule, lead with its human-readable title:
- Title and auto-generated (the short immutable slug)
name - Status: testMode — must be activated in the dashboard to go live
- ,
types,actionscore - Dashboard link as a clickable markdown link
- Rule on its own final line
id
For rules that exhausted all 10 attempts, report them in a Failed rules section with the title and the last HTTP 400 error message.Surface 4xx errors verbatim. - Title and auto-generated
⚠️ testMode default. Every new rule starts with. It evaluates against transactions and its result appears indryRun: true, but does not affect the real score or action. To make a rule live, open it in the dashboard and set it to "Active".dryScore
-
获取租户权限。运行并存储
sumsub-check-permissions数组。验证allowed是否存在;若不存在则终止并说明原因。KYT -
确定模式——创建或修改
- 修改模式:用户提供规则的(不可变别名,如
name)或足够的上下文以通过标题识别规则。运行fin-ben-pep-ter-list-abo-thr-WoGD,通过bash ${CLAUDE_SKILL_DIR}/scripts/get_kyt_rules.sh或name找到规则并存储完整的当前文档。向用户展示现有规则的title、conditionEl、score和action,然后仅收集用户想要修改的字段。跳至步骤2a。types - 创建模式:用户描述新规则。运行并检查是否存在标题冲突——服务器每次POST都会创建重复规则,无去重机制。如果存在标题匹配的规则,建议用户跳过创建操作,改为修改现有规则。
bash ${CLAUDE_SKILL_DIR}/scripts/get_kyt_rules.sh
- 修改模式:用户提供规则的
-
将用户意图转换为简洁规格。对于每个用户想要创建的规则,收集以下信息:
- (≤128字符,必填)
title - — 一种或多种交易类型(见下表)
types - 条件的自然语言描述(用于在步骤3中生成)
conditionEl - (整数,默认值0)、
score(action|score|onHold|awaitUser)reject - 可选:、
desc、tags、bundleName、priority、stopOnMatchsourceKeys
2a. 确保客户列表存在 — 如果任何规则的中引用了,则在生成或验证表达式前确认每个列表是否存在:
- HTTP 200 → 列表存在;继续操作。
- HTTP 404 → 列表不存在;创建列表:
POST操作是幂等的——即使列表在此期间已创建,也会成功。在确认所有引用的客户列表都存在前,请勿继续验证或创建规则。
conditionElclientLists.<name>bash bash ${CLAUDE_SKILL_DIR}/scripts/get_kyt_client_list.sh <listName> bash bash ${CLAUDE_SKILL_DIR}/scripts/create_kyt_client_list.sh <listName> - 生成。对于每个需要条件的规则:
conditionEl- 使用中的类型定义构建SumScript布尔表达式。
references/kyt-rule-schema.md - 不要猜测字段路径。仅使用 schema 中确认的字段——在编写表达式前验证从根到叶子的路径。
- 对于默认货币金额检查,使用(标准化金额),而非
data.info.amountInDefaultCurrency(源货币金额)——除非用户明确要求按源货币过滤。data.info.amount - 定时规则()不使用
types: ["scheduledEvent"]作为触发器——改用conditionEl(见references/kyt-rule-schema.md)。noEventTrigger - 对于多分支评分(不同子条件对应不同评分),在中使用
conditionEl,并将负载级别的addScoreIf、score: 0(见评分部分)。action: "score"
- 使用
3a. 验证内置在POST操作中 — 服务器在创建调用(步骤6)期间验证语法。无需单独的预检步骤。如果验证失败,服务器返回HTTP 400并附带描述问题的错误信息——修复表达式后重新POST。
conditionEl-
构建负载。按照以下约束组装每个规则的JSON:创建模式:
- 仅必填字段:、
title(至少1个值)。types - 对于规则:必要时包含
eval、conditionEl和score。action - 切勿发送或
id——服务器会分配这两个值。name
修改模式(新版本):- 包含— 来自现有规则的不可变别名。
"name": "<existing-slug>" - 包含— 显式null。这向服务器发出信号,表明要创建新版本而非新规则。切勿使用
"id": null(空字符串)——Jackson会将其视为无效的ObjectId并返回HTTP 400。"id": "" - 保留现有规则文档中所有未更改的字段。仅修改用户要求更改的字段。
- 和
title仍为必填项。types
两种模式通用规则:- 切勿发送服务器分配的字段或审计字段:、
clientId、actual、时间戳(revision、createdAt、modifiedAt)、作者字段。archivedAt - 切勿发送或
scope——由服务器管理的许可证控制字段。bgCheckTargets - 创建模式: 切勿发送或
dryRun;服务器会将它们初始化为disabled和true。false - 修改模式: 保留现有规则文档中的和
dryRun——服务器使用这些值在版本更新期间保留规则当前的激活状态和测试模式状态。disabled - 省略空的可选容器:、
sourceKeys: []、caseAction: {}、applicantChange: {}、applicantActions: {"actions": {}}、varDefinitions: {"definitions": []}。varValues: {"values": {}} - 不要将与其他交易类型混合使用。
scheduledEvent
- 仅必填字段:
-
在POST前向用户展示每个负载并请求明确确认。
-
逐个POST规则,命令为。 规则逐个创建。检查退出代码:
bash ${CLAUDE_SKILL_DIR}/scripts/post_kyt_rule.sh < payload.json- 退出码0 → HTTP 200;响应体为创建的。继续步骤7。
KytTxnRuleView - 退出码1 → HTTP 4xx/5xx;响应体包含错误信息。直接展示错误信息,修复表达式后重新POST。
重试上限: 每个规则最多允许10次POST尝试。如果第10次尝试仍失败,则将该规则标记为失败,记录最后一条错误信息,然后继续处理下一个规则——不要终止整个批次。在步骤9中报告所有失败的规则。 - 退出码0 → HTTP 200;响应体为创建的
-
通过获取每个已创建的规则。 比较
bash ${CLAUDE_SKILL_DIR}/scripts/get_kyt_rule.sh {id}和关键字段与发送的内容。报告任何差异。conditionEl -
为每个规则构建仪表板链接:
https://cockpit.sumsub.com/checkus/kyt/rulesManager/rulesList/{name}?clientId={clientId}&xSNSEnv=sbx和name来自POST响应体。将其渲染为可点击的markdown链接。clientId -
报告 — 对于每个规则,以其易读的标题开头:
- 标题和自动生成的(短不可变别名)
name - 状态: 测试模式——必须在仪表板中激活才能生效
- 、
types、actionscore - 可点击的仪表板markdown链接
- 单独一行显示规则
id
对于用尽所有10次尝试的规则,在失败规则部分报告其标题和最后一条HTTP 400错误信息。直接展示4xx错误信息。 - 标题和自动生成的
⚠️ 测试模式默认设置。 每个新规则默认。它会对交易进行评估,结果显示在dryRun: true中,但不会影响实际评分或操作。要使规则生效,请在仪表板中打开它并设置为“Active”。dryScore
Compact Spec Format
简洁规格格式
Express each rule as a JSON object before generating the full payload:
jsonc
{
"title": "Hold large outgoing transfers", // required, ≤128 chars
"desc": "Holds outgoing transactions over 50 000 in default currency",
"types": ["finance"], // required
"condition": "outgoing AND amount > 50 000 default currency", // natural language → conditionEl
"score": 100, // 0 if using addScoreIf
"action": "onHold", // score | onHold | awaitUser | reject
"tags": ["HighAmount"], // optional; auto-created if new
"bundleName": "AML Compliance", // optional group
"priority": 10, // optional; higher = evaluated first
"stopOnMatch": false, // optional
"sourceKeys": ["payment-gateway-1"] // optional top-level filter
}在生成完整负载前,将每个规则表示为JSON对象:
jsonc
{
"title": "暂扣大额转出交易", // 必填,≤128字符
"desc": "暂扣默认货币金额超过50000的转出交易",
"types": ["finance"], // 必填
"condition": "转出且金额超过50000默认货币", // 自然语言 → conditionEl
"score": 100, // 使用addScoreIf时设为0
"action": "onHold", // score | onHold | awaitUser | reject
"tags": ["HighAmount"], // 可选;若为新标签则自动创建
"bundleName": "AML合规", // 可选分组
"priority": 10, // 可选;值越高越先评估
"stopOnMatch": false, // 可选
"sourceKeys": ["payment-gateway-1"] // 可选顶级过滤器
}Transaction Types
交易类型
| Type | When to use | | Notes |
|---|---|---|---|
| Payment transfers, deposits, withdrawals | Yes | Most common type |
| Travel-rule transactions | Yes | Requires |
| KYC/verification session events | Yes | |
| Login, password reset, 2FA events | Yes | Requires |
| Periodic applicant re-checks | No (use | Must be alone in |
Types may be combined in one rule except which must be the only type.
scheduledEvent| 类型 | 使用场景 | 是否需要 | 说明 |
|---|---|---|---|
| 支付转账、存款、取款 | 是 | 最常用类型 |
| 旅行规则交易 | 是 | 需要 |
| KYC/验证会话事件 | 是 | |
| 登录、密码重置、2FA事件 | 是 | 需要 |
| 定期重新检查申请人 | 否(使用 | 必须是 |
除必须单独使用外,其他类型可在一个规则中组合使用。
scheduledEventRule Actions
规则操作
| Action | Priority | Effect |
|---|---|---|
| 0 | Adds score only (default) |
| 5 | Holds the transaction for review |
| 7 | Awaits user action before proceeding |
| 10 | Rejects the transaction outright |
Across all matched rules, the strongest action wins and scores accumulate.
| 操作 | 优先级 | 效果 |
|---|---|---|
| 0 | 仅添加评分(默认) |
| 5 | 暂扣交易以待审核 |
| 7 | 等待用户操作后继续 |
| 10 | 直接拒绝交易 |
在所有匹配的规则中,最强操作胜出,评分累加。
Scoring & conditionEl
conditionEl评分与conditionEl
conditionElSimple rule (single threshold, one score): Put the score in and keep as a pure boolean.
scoreconditionEljson
{
"title": "Hold high outgoing finance",
"types": ["finance"],
"conditionEl": "data.info.direction == 'out' AND data.info.amountInDefaultCurrency > 50000",
"score": 100,
"action": "onHold"
}Multi-branch scoring (different scores per sub-condition): Use inside .
Set payload and — otherwise the payload score is double-counted.
addScoreIfconditionElscore: 0action: "score"- (eager OR): every branch is evaluated, all matching branches accumulate score. Use for independent flags.
EOR - (short-circuit): stops at the first matching branch. Use for mutually exclusive tiers (strictest first).
OR
addScoreIf(data.info.amountInDefaultCurrency > 100000, 50) EOR
addScoreIf(applicant.country IN clientLists.sanctioned_countries, 100) EOR
addScoreIf("pep" IN applicant.riskLabels.aml, 75)简单规则(单一阈值,一个评分): 将评分放在中,保持为纯布尔值。
scoreconditionEljson
{
"title": "暂扣大额转出金融交易",
"types": ["finance"],
"conditionEl": "data.info.direction == 'out' AND data.info.amountInDefaultCurrency > 50000",
"score": 100,
"action": "onHold"
}多分支评分(不同子条件对应不同评分): 在中使用。设置负载和——否则负载评分会被重复计算。
conditionEladdScoreIfscore: 0action: "score"- (主动或): 评估所有分支,所有匹配分支的评分累加。用于独立标记。
EOR - (短路或): 在第一个匹配分支处停止。用于互斥层级(最严格的在前)。
OR
addScoreIf(data.info.amountInDefaultCurrency > 100000, 50) EOR
addScoreIf(applicant.country IN clientLists.sanctioned_countries, 100) EOR
addScoreIf("pep" IN applicant.riskLabels.aml, 75)Common conditionEl
Patterns
conditionEl常见conditionEl
模式
conditionElundefinedundefinedFinance: outgoing transfer over threshold
金融:转出交易超过阈值
data.info.direction == 'out' AND data.info.amountInDefaultCurrency > 50000
data.info.direction == 'out' AND data.info.amountInDefaultCurrency > 50000
Finance: applicant in a client list
金融:申请人在客户列表中
applicant.country IN clientLists.high_risk_countries
applicant.country IN clientLists.high_risk_countries
Finance: incoming from specific payment type
金融:来自特定支付类型的转入交易
data.info.direction == 'in' AND data.info.type == 'transfer'
data.info.direction == 'in' AND data.info.type == 'transfer'
Finance: crypto transaction
金融:加密货币交易
data.info.currencyType == 'crypto'
data.info.currencyType == 'crypto'
KYC: applicant review rejected
KYC:申请人审核被拒绝
applicant.review.decision == 'rejected'
applicant.review.decision == 'rejected'
Travel Rule: counterparty VASP not found
旅行规则:未找到交易对手VASP
txn.travelRuleInfo.status == 'counterpartyVaspNotFound'
txn.travelRuleInfo.status == 'counterpartyVaspNotFound'
Aggregation: applicant sent > 3 transactions in last 24 hours
聚合:申请人在过去24小时内发送了超过3笔交易
txns.finance.byApplicant.out.lastHours(24).count() > 3
txns.finance.byApplicant.out.lastHours(24).count() > 3
Aggregation: total outgoing amount in last 30 days
聚合:过去30天的总转出金额
txns.finance.byApplicant.out.lastDays(30).sum(it.data.info.amountInDefaultCurrency) > 100000
For the full type system and all available fields, see [`references/kyt-rule-schema.md`](references/kyt-rule-schema.md).txns.finance.byApplicant.out.lastDays(30).sum(it.data.info.amountInDefaultCurrency) > 100000
完整的类型系统和所有可用字段请查看[`references/kyt-rule-schema.md`](references/kyt-rule-schema.md)。Client Lists
客户列表
Client lists are named sets of values (countries, currencies, peer IDs, etc.) referenced in as . A list must exist before a rule that references it can be validated or created.
conditionElclientLists.<listName>客户列表是命名的值集合(国家、货币、对等方ID等),在中以形式引用。在验证或创建引用该列表的规则前,列表必须已存在。
conditionElclientLists.<listName>Checking and creating a list
检查和创建列表
bash
undefinedbash
undefinedCheck if a list exists
检查列表是否存在
bash ${CLAUDE_SKILL_DIR}/scripts/get_kyt_client_list.sh high_risk_countries
bash ${CLAUDE_SKILL_DIR}/scripts/get_kyt_client_list.sh high_risk_countries
Create a list (idempotent)
创建列表(幂等操作)
bash ${CLAUDE_SKILL_DIR}/scripts/create_kyt_client_list.sh high_risk_countries
The POST creates an empty list if it doesn't exist and returns the list document either way.bash ${CLAUDE_SKILL_DIR}/scripts/create_kyt_client_list.sh high_risk_countries
POST操作会在列表不存在时创建空列表,无论哪种情况都会返回列表文档。Required permissions
所需权限
| Operation | Permission |
|---|---|
| GET (read) | |
| POST (create) | |
If the GET returns 403, is missing. If the POST returns 403, is missing. In both cases, tell the user the missing permission and stop.
seeClientListsmanageClientLists| 操作 | 权限 |
|---|---|
| GET(读取) | |
| POST(创建) | |
如果GET返回403,说明缺少权限。如果POST返回403,说明缺少权限。两种情况都要告知用户缺少的权限并停止操作。
seeClientListsmanageClientListsUsage in conditionEl
conditionEl在conditionEl
中使用
conditionElReference a list by its exact name after the prefix:
clientLists.undefined在前缀后使用列表的精确名称引用:
clientLists.undefinedCountry in a named list
国家在命名列表中
applicant.country IN clientLists.high_risk_countries
applicant.country IN clientLists.high_risk_countries
Peer wallet not in an allowlist
对等方钱包不在允许列表中
NOT (txn.counterparty.wallet IN clientLists.approved_wallets)
NOT (txn.counterparty.wallet IN clientLists.approved_wallets)
Combined
组合使用
applicant.country IN clientLists.sanctioned_countries AND data.info.amountInDefaultCurrency > 1000
List contents are managed separately in the Sumsub dashboard (KYT → Client Lists) — the API endpoints only create an empty list; adding values is a dashboard-only operation.applicant.country IN clientLists.sanctioned_countries AND data.info.amountInDefaultCurrency > 1000
列表内容在Sumsub仪表板中单独管理(KYT → 客户列表)——API端点仅创建空列表;添加值只能通过仪表板操作。Tags
标签
Tags link rule matches to applicant-level risk assessment:
- Add to a rule — the tag name auto-creates in KYT settings if new.
tags: ["TagName"] - When the rule matches, each tag accumulates the rule's score for the applicant.
- The post-scoring runner aggregates tag scores into the applicant risk profile.
applicantAssessment
标签将规则匹配与申请人级别的风险评估关联起来:
- 在规则中添加——如果是新标签,会在KYT设置中自动创建。
tags: ["TagName"] - 当规则匹配时,每个标签会为申请人累计规则的评分。
- 评分后处理程序会将标签评分聚合为申请人风险档案。
applicantAssessment
Scheduled Rules (scheduledEvent
)
scheduledEvent定时规则(scheduledEvent
)
scheduledEventScheduled rules fire without an incoming transaction. They find applicants based on trigger criteria
and generate synthetic events. See
for the full structure.
references/kyt-rule-schema.mdnoEventTriggerKey constraints:
- must be exactly
types— cannot be combined with other types.["scheduledEvent"] - Must include or
applicantChange(at least one).applicantActions - is optional (use for secondary filtering, not as the primary trigger).
conditionEl - is either
noEventTrigger.type(approved applicants at a level, N days after review) orbyLevelName(free-form applicant filter expression).byCustomExpression
Minimal scheduled rule:
json
{
"title": "Annual KYC refresh",
"types": ["scheduledEvent"],
"noEventTrigger": {
"type": "byLevelName",
"levelParams": {
"levelName": "basic-kyc-level",
"days": 365
}
},
"applicantChange": {
"type": "applicantLevel",
"applicantLevel": {
"levelName": "re-verification-level"
}
}
}定时规则无需传入交易即可触发。它们根据触发条件查找申请人并生成合成事件。完整的结构请查看。
noEventTriggerreferences/kyt-rule-schema.md关键约束:
- 必须恰好为
types——不能与其他类型组合。["scheduledEvent"] - 必须包含或
applicantChange(至少一个)。applicantActions - 可选(用于二次过滤,而非作为主要触发器)。
conditionEl - 为
noEventTrigger.type(审核通过后N天的特定级别申请人)或byLevelName(自由格式申请人过滤表达式)。byCustomExpression
最简定时规则:
json
{
"title": "年度KYC更新",
"types": ["scheduledEvent"],
"noEventTrigger": {
"type": "byLevelName",
"levelParams": {
"levelName": "basic-kyc-level",
"days": 365
}
},
"applicantChange": {
"type": "applicantLevel",
"applicantLevel": {
"levelName": "re-verification-level"
}
}
}Case Creation on Match
匹配时创建案例
To automatically create a compliance case when a rule matches, add :
caseActionjson
{
"caseAction": {
"createCase": true,
"groupByType": "byApplicant",
"blueprintId": "<case-blueprint-id>",
"priority": "high",
"deadlineHours": 24
}
}groupByTypebyRulebyApplicantblueprintId要在规则匹配时自动创建合规案例,请添加:
caseActionjson
{
"caseAction": {
"createCase": true,
"groupByType": "byApplicant",
"blueprintId": "<case-blueprint-id>",
"priority": "high",
"deadlineHours": 24
}
}groupByTypebyRulebyApplicantblueprintIdModifying an Existing Rule
修改现有规则
To update a rule, POST a new revision to the same endpoint used for creation. The server replaces the current revision atomically and increments .
revision要更新规则,请向创建规则的同一端点POST新版本。服务器会原子性地替换当前版本并递增。
revisionIdentify the rule
识别规则
The user must supply the rule's (immutable slug) or enough context to identify it by title. List all rules and find the match:
namebash
bash ${CLAUDE_SKILL_DIR}/scripts/get_kyt_rules.sh | python3 -c "
import json, sys
items = json.load(sys.stdin).get('list', {}).get('items', [])
for r in items:
if r.get('name') == 'fin-ben-pep-ter-list-abo-thr-WoGD':
print(json.dumps(r, indent=2))
"Or search by title substring:
bash
bash ${CLAUDE_SKILL_DIR}/scripts/get_kyt_rules.sh | python3 -c "
import json, sys
items = json.load(sys.stdin).get('list', {}).get('items', [])
for r in items:
if 'PEP' in r.get('title', '').upper():
print(json.dumps(r, indent=2))
"Show the matching rule's current , , , and to the user before proceeding.
conditionElscoreactiontypes用户必须提供规则的(不可变别名)或足够的上下文以通过标题识别。列出所有规则并找到匹配项:
namebash
bash ${CLAUDE_SKILL_DIR}/scripts/get_kyt_rules.sh | python3 -c "
import json, sys
items = json.load(sys.stdin).get('list', {}).get('items', [])
for r in items:
if r.get('name') == 'fin-ben-pep-ter-list-abo-thr-WoGD':
print(json.dumps(r, indent=2))
"或按标题子串搜索:
bash
bash ${CLAUDE_SKILL_DIR}/scripts/get_kyt_rules.sh | python3 -c "
import json, sys
items = json.load(sys.stdin).get('list', {}).get('items', [])
for r in items:
if 'PEP' in r.get('title', '').upper():
print(json.dumps(r, indent=2))
"在继续操作前,向用户展示匹配规则当前的、、和。
conditionElscoreactiontypesPayload shape
负载格式
Take the existing rule document, apply only the user's requested changes, then:
- Set — explicit null (signals new revision, not new rule). Never use
"id": null— it fails Jackson ObjectId deserialization with HTTP 400."" - Keep — the existing immutable slug.
"name": "<slug>" - Strip server-managed fields: ,
clientId,actual,revision,scope, timestamps, author fields.bgCheckTargets - Keep and
dryRunfrom the existing document — they preserve the rule's current activation and test-mode state across the revision.disabled
json
{
"id": null,
"name": "fin-ben-pep-ter-list-abo-thr-WoGD",
"title": "Finance — Beneficiary in PEP and terror list above threshold",
"types": ["finance"],
"conditionEl": "beneficiary.fullName IN clientLists.pep_and_terror AND data.info.amountInDefaultCurrency > 5000",
"score": 100,
"action": "onHold",
"dryRun": true,
"disabled": false
}获取现有规则文档,仅应用用户请求的更改,然后:
- 设置— 显式null(表示新版本,而非新规则)。切勿使用
"id": null——这会导致Jackson ObjectId反序列化失败并返回HTTP 400。"" - 保留— 现有不可变别名。
"name": "<slug>" - 移除服务器管理的字段:、
clientId、actual、revision、scope、时间戳、作者字段。bgCheckTargets - 保留现有文档中的和
dryRun——它们会在版本更新期间保留规则当前的激活状态和测试模式状态。disabled
json
{
"id": null,
"name": "fin-ben-pep-ter-list-abo-thr-WoGD",
"title": "金融 — 受益人在PEP和恐怖分子列表且金额超过阈值",
"types": ["finance"],
"conditionEl": "beneficiary.fullName IN clientLists.pep_and_terror AND data.info.amountInDefaultCurrency > 5000",
"score": 100,
"action": "onHold",
"dryRun": true,
"disabled": false
}Validate before posting
POST前验证
If changed, the POST validates it automatically. If the server returns HTTP 400, fix the expression and re-POST (same 10-attempt cap as create mode applies).
conditionEl如果已更改,POST操作会自动验证。如果服务器返回HTTP 400,修复表达式后重新POST(与创建模式相同,最多10次尝试)。
conditionElAfter posting
POST后
- The response contains the new (the latest revision gets a new id), old
id,namenumber, and all rule fields.revision - GET the rule back by the new to verify.
id - The dashboard link uses the old :
namehttps://cockpit.sumsub.com/checkus/kyt/rulesManager/rulesList/{name}?clientId={clientId}&xSNSEnv=sbx - Report the new number alongside the title and updated fields.
revision
- 响应包含新的(最新版本会获得新ID)、旧的
id、name编号和所有规则字段。revision - 通过新获取规则以验证。
id - 仪表板链接使用旧的:
namehttps://cockpit.sumsub.com/checkus/kyt/rulesManager/rulesList/{name}?clientId={clientId}&xSNSEnv=sbx - 在标题和更新字段旁报告新的编号。
revision
Applicant Risk Scoring
申请人风险评分
Applicant risk scoring calculates a composite risk score for each applicant based on the transaction monitoring rules that matched them. The score is built from three layers configured independently:
Rules (produce tags on match)
└─ Tags (each carries a score weight)
└─ Assessment (maps tags → weighted score)
└─ Risk Levels (score thresholds → Low / Med / High label)申请人风险评分根据匹配申请人的交易监控规则计算综合风险评分。评分由三个独立配置的层级构成:
规则(匹配时生成标签)
└─ 标签(每个标签带有评分权重)
└─ 评估(将标签映射为加权评分)
└─ 风险等级(评分阈值 → 低/中/高标签)How it works
工作原理
- Rules fire — when a TM rule matches a transaction, it applies its to the applicant.
tags - Tags accumulate — each tag carries a . Multiple rule matches sum tag scores.
scoreWeight - Assessment aggregates — the assessment config controls which tags count toward the total score (), their relative weights (
includeInTotalScore), and optional hierarchy (scoreWeight).items - Risk level assigned — the total score is compared against to produce a human-readable risk label (e.g. Low / Med / High).
riskLevelThresholds
For companies, in the assessment applies role-based weights (UBO, director, shareholder…) so the applicant's score accounts for the risk of their associated parties.
companyBeneficiarySettings- 规则触发 — 当TM规则匹配交易时,会将其应用于申请人。
tags - 标签累计 — 每个标签带有。多次规则匹配会累加标签评分。
scoreWeight - 评估聚合 — 评估配置控制哪些标签计入总评分()、它们的相对权重(
includeInTotalScore)以及可选的层级(scoreWeight)。items - 分配风险等级 — 将总评分与比较,生成易读的风险标签(如低/中/高)。
riskLevelThresholds
对于公司,评估中的应用基于角色的权重(最终受益人、董事、股东…),因此申请人的评分会考虑其关联方的风险。
companyBeneficiarySettingsConfiguring applicant scoring — step by step
配置申请人评分——分步指南
Step 1 — Create/update tags
bash
echo '{"tag": {"name": "HighValue", "styleClass": "red", "color": "#FF000080", "scorable": true, "scoreWeight": 1.0}}' \
| bash scripts/post_kyt_tag.shRead back all tags to confirm:
bash
bash scripts/get_kyt_tags.shStep 2 — Configure assessment
Map tags to weighted scores. is a client-assigned stable identifier for the entry.
idjson
{
"scores": [
{
"id": "high-value-score",
"tag": "HighValue",
"includeInTotalScore": true,
"scoreWeight": 1.0
}
],
"companyBeneficiarySettings": [
{ "beneficiaryType": "ubo", "weight": 1.0 },
{ "beneficiaryType": "director", "weight": 0.5 }
]
}Valid values: , , , , , , , , , , , , , , .
beneficiaryTypeshareholderrepresentativedirectorubocompanyOfficersecretaryfounderinvestorlegalAdvisorauthorizedSignatorytrusteetrustBeneficiarytrustSettlortrustProtectorpayerbash
undefined步骤1 — 创建/更新标签
bash
echo '{"tag": {"name": "HighValue", "styleClass": "red", "color": "#FF000080", "scorable": true, "scoreWeight": 1.0}}' \
| bash scripts/post_kyt_tag.sh读取所有标签以确认:
bash
bash scripts/get_kyt_tags.sh步骤2 — 配置评估
将标签映射为加权评分。是客户端分配的条目标识符,需保持稳定。
idjson
{
"scores": [
{
"id": "high-value-score",
"tag": "HighValue",
"includeInTotalScore": true,
"scoreWeight": 1.0
}
],
"companyBeneficiarySettings": [
{ "beneficiaryType": "ubo", "weight": 1.0 },
{ "beneficiaryType": "director", "weight": 0.5 }
]
}有效的值:、、、、、、、、、、、、、、。
beneficiaryTypeshareholderrepresentativedirectorubocompanyOfficersecretaryfounderinvestorlegalAdvisorauthorizedSignatorytrusteetrustBeneficiarytrustSettlortrustProtectorpayerbash
undefinedRead current
读取当前配置
bash scripts/get_kyt_applicant_assessment.sh
bash scripts/get_kyt_applicant_assessment.sh
Apply new config
应用新配置
echo '<payload>' | bash scripts/patch_kyt_applicant_assessment.sh
**Step 3 — Configure risk level thresholds**
```bashecho '<payload>' | bash scripts/patch_kyt_applicant_assessment.sh
**步骤3 — 配置风险等级阈值**
```bashRead current
读取当前配置
bash scripts/get_kyt_risk_level_settings.sh
bash scripts/get_kyt_risk_level_settings.sh
Apply new thresholds (min 2 required)
应用新阈值(至少需要2项)
echo '{"riskLevelThresholds": [
{"label": "Low", "rangeFrom": 0, "styleClass": "green"},
{"label": "High", "rangeFrom": 75, "styleClass": "red"}
]}' | bash scripts/patch_kyt_risk_level_settings.sh
undefinedecho '{"riskLevelThresholds": [
{"label": "低", "rangeFrom": 0, "styleClass": "green"},
{"label": "高", "rangeFrom": 75, "styleClass": "red"}
]}' | bash scripts/patch_kyt_risk_level_settings.sh
undefinedTags in rules
规则中的标签
Add to a rule's payload to connect rule matches to the assessment:
tagsjson
{
"title": "Flag high-value transfers",
"types": ["finance"],
"conditionEl": "data.info.amountInDefaultCurrency > 10000",
"score": 50,
"action": "score",
"tags": ["HighValue"]
}When this rule matches, the tag is applied to the applicant and its weight contributes to their risk score.
HighValue在规则负载中添加,将规则匹配与评估关联起来:
tagsjson
{
"title": "标记高价值转账",
"types": ["finance"],
"conditionEl": "data.info.amountInDefaultCurrency > 10000",
"score": 50,
"action": "score",
"tags": ["HighValue"]
}当此规则匹配时,标签会应用于申请人,其权重会计入申请人的风险评分。
HighValueSee Also
另请参阅
- — full field reference and SumScript type system
references/kyt-rule-schema.md - — bare-minimum working payload
examples/minimal.json - — complete finance hold rule
examples/eval-finance-hold.json - — list rules in a bundle by name and category (
scripts/get_kyt_bundle.sh|installed|available)archived - — list all KYT tags with assessment config and linked rules
scripts/get_kyt_tags.sh - — create or update a KYT tag (requires
scripts/post_kyt_tag.sh)manageKytSettings - — get applicant assessment scoring configuration
scripts/get_kyt_applicant_assessment.sh - — replace applicant assessment scoring configuration (requires
scripts/patch_kyt_applicant_assessment.sh)manageKytSettings - — get current applicant risk level thresholds
scripts/get_kyt_risk_level_settings.sh - — replace applicant risk level thresholds (min 2, requires
scripts/patch_kyt_risk_level_settings.sh)manageKytSettings - — check whether a client list exists by name
scripts/get_kyt_client_list.sh - — create a client list (idempotent)
scripts/create_kyt_client_list.sh - — submit test transactions to verify rules
sumsub-create-transaction - — check tenant entitlements
sumsub-check-permissions - — authentication reference
sumsub-api-auth
- — 完整字段参考和SumScript类型系统
references/kyt-rule-schema.md - — 最简可用负载
examples/minimal.json - — 完整的金融暂扣规则
examples/eval-finance-hold.json - — 按名称和类别(
scripts/get_kyt_bundle.sh|installed|available)列出规则包中的规则archived - — 列出所有KYT标签及其评估配置和关联规则
scripts/get_kyt_tags.sh - — 创建或更新KYT标签(需要
scripts/post_kyt_tag.sh权限)manageKytSettings - — 获取申请人评估评分配置
scripts/get_kyt_applicant_assessment.sh - — 替换申请人评估评分配置(需要
scripts/patch_kyt_applicant_assessment.sh权限)manageKytSettings - — 获取当前申请人风险等级阈值
scripts/get_kyt_risk_level_settings.sh - — 替换申请人风险等级阈值(至少2项,需要
scripts/patch_kyt_risk_level_settings.sh权限)manageKytSettings - — 根据名称检查客户列表是否存在
scripts/get_kyt_client_list.sh - — 创建客户列表(幂等操作)
scripts/create_kyt_client_list.sh - — 提交测试交易以验证规则
sumsub-create-transaction - — 检查租户权限
sumsub-check-permissions - — 认证参考文档
sumsub-api-auth