关于 sumsub-create-poa-preset
这款 Sumsub Agent skill 可根据精简规格构建地址证明预设载荷,并通过 Sumsub API 创建或更新预设,面向沙盒工作区的地址文件与校验规则配置。
主要功能
- 01构建 POA 预设载荷
- 02通过 API 创建和更新预设
- 03校验国家与提供方设置
- 04读取预设以验证或查询名称
- 05返回用于关联级别的预设 ID
适用场景
- 01设置可接受的地址证明文件
- 02配置有效期和国家范围
- 03更新现有 POA 预设
- 04将预设关联到验证级别
MCP 相关
此技能通过 Sumsub API 创建、更新和读取 POA 预设,并返回预设 ID,以便将其关联到级别的居住证明文档集。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ sumsub/ agent-skills --skill sumsub-create-poa-preset安装后在 Claude Code 中输入/sumsub-create-poa-preset确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
examples/eu-bank-friendly.jsonminimal.jsonper-country-tight.jsonreferences/poa-preset-schema.mdscripts/build_poa_preset.pyget_poa_preset.shpatch_poa_preset.shpost_poa_preset.sh详细介绍
Sumsub — 创建 POA 预设
根据精简规范构建 POA 预设 JSON 负载,将其 POST 到 Sumsub API,并返回生成的预设 id,以便通过 level.requiredIdDocs.docSets[].poaStepSettingsId 将其关联到一个或多个级别。
前提条件 — 级别必须包含 PROOF_OF_RESIDENCE 步骤。 除非将 POA 预设关联到至少一个级别中的
PROOF_OF_RESIDENCE(或PROOF_OF_RESIDENCE2/3/4)docset,否则该预设不会生效。如果用户尚未创建(或描述)包含 POA 步骤的级别,请在构建预设之前说明这一点——单独创建预设毫无意义。
端点
| 方法 | 路径 | 适用情况 |
|---|---|---|
POST | /resources/api/agent/poaStepSettings | 创建新预设。请求体不得包含 id——由服务器分配。 |
PATCH | /resources/api/agent/poaStepSettings | 更新现有预设。请求体必须包含 id(作为字段,而非放在 URL 中)。 |
GET | /resources/api/agent/poaStepSettings/{id} | 读取单个预设——用于验证写入结果,以及根据已知 id 获取 name。 |
这三个端点都需要 manageClientSettings 权限。请求体格式遵循 POA 预设架构——仅包含客户端可设置的字段(clientId、createdAt、createdBy、modifiedAt、审计跟踪由服务器管理,并会在响应中返回)。
创建后,通过编辑级别进行关联:在任意 PROOF_OF_RESIDENCE doc-set 上设置 requiredIdDocs.docSets[].poaStepSettingsId = "<新 id>"。
身份验证 — App Token + 密钥(仅限沙盒)
此技能会调用 Sumsub 公共 API,并按照身份验证参考为每个请求签名。完整的工作原理说明请参阅 sumsub-api-auth 技能——如果遇到 401 Invalid signature,请阅读该说明。
⚠️ 仅限沙盒令牌。 请勿在此处接受或使用生产环境的 App Token。如果用户提供了生产令牌,请拒绝并要求他们前往 https://cockpit.sumsub.com/checkus/home?sbx=true 生成一组沙盒凭据(Connect Sumsub to your AI agent -> Build & configure -> Generate token)。 令牌和密钥只会显示一次——关闭对话框前请复制两者。辅助脚本会强制执行此限制——如果令牌不以
sbx:开头,就会拒绝使用。
| 变量 | 示例 |
|---|---|
SUMSUB_APP_TOKEN | sbx:... — 控制面板中的沙盒 App Token。 |
SUMSUB_SECRET_KEY | 创建令牌时显示一次的配对密钥。 |
SUMSUB_BASE | 可选。默认为 https://api.sumsub.com。 |
如果用户已在对话中提供凭据,请重复使用;否则,在运行前询问一次。切勿再次透露密钥。
租户权益
POA 预设创建过去一直受 POA 权益限制,但实际上,无论租户是否拥有该权益,API 通常都会接受写入请求——该权益往往是基础权益、由其他密钥覆盖,或根本不会显示在 allowedChecks 中。不要因为缺少该权益而阻止操作。
- 调用
sumsub-check-permissions并检查allowedChecks——仅供参考和诊断。 - 如果存在
POA——继续操作。 - 如果缺少
POA——仍然继续操作,并向用户显示一行说明,指出文档所述的权益未列出(这样如果 POST 最终失败,用户就知道向支持团队说明什么)。不要暂停等待确认——如果租户确实不具备相应权限,Sumsub 会自行拒绝写入;与预先中止相比,届时返回的 4xx 错误会提供更多信息。 - 如果 POST 返回的 4xx 提到了权益——原样展示错误正文,并建议联系 CSM / Sumsub 支持团队。
操作步骤
-
获取租户权益信息——参见上文。
-
将用户意图转换为精简规格(如下)。大多数用户会用“接受哪些材料”(银行对账单、水电费账单)和“有效期多长”(有效月数)来描述预设——将其映射到
providers键、subTypes和validMonths。 -
验证:名称不能为空;
includedCountries和excludedCountries不能同时设置;每个 provider 键都必须是PoaCompanyContactType;每个subTypes条目都必须是PoaSubType;每个国家代码都必须是大写的 ISO-3166-1 alpha-3 代码;crossValidator.fuzzyThreshold必须在[0, 1]范围内。 -
生成负载:通过
${CLAUDE_SKILL_DIR}/scripts/build_poa_preset.py(从标准输入读取精简规格 → 向标准输出输出完整负载)。 -
创建或更新:
- 新建预设——通过
${CLAUDE_SKILL_DIR}/scripts/post_poa_preset.sh发送 POST 请求。负载中不得包含id。 - 更新现有预设——先通过
${CLAUDE_SKILL_DIR}/scripts/get_poa_preset.sh获取当前状态,让用户查看差异,然后通过${CLAUDE_SKILL_DIR}/scripts/patch_poa_preset.sh发送 PATCH 请求。负载必须包含预设的id。
- 新建预设——通过
-
**构建控制面板链接。**从响应正文读取
id和clientId,并按以下格式生成:https://cockpit.sumsub.com/checkus/sdkIntegrations/globalSettings/userVerification/proofOfAddress/<id>?clientId=<clientId>&sbx=truesbx=true查询参数用于指向 Sandbox 工作区;这是所有技能共享的标准沙盒链接参数。 -
报告——先给出便于阅读的名称;仅在最后提供
id,作为下一次 API 调用所需的值:- 名称和国家范围(包含/排除),以及每个国家覆盖规则所针对的国家。
- 简要说明接受的材料(涵盖的 provider 类型、默认有效期)。
- 控制面板链接,以可点击的 Markdown 链接形式呈现。
- 最后一行:
Preset ID for level wiring: <id>。
精简规格格式(通过标准输入传入 JSON 或 YAML)
name: "Standard POA (6 months)"
desc: "Default Proof of Address rules with 6-month validity"
# Country scope — choose AT MOST ONE
# includedCountries: [GBR, DEU, FRA] # allow-list
excludedCountries: [PRK, IRN] # block-list
# Global defaults
settings:
acceptMultiplePages: true
acceptDocScreenshot: true
requireCountryMatch: false # require POI country == POA country
useIssueDateForExpiry: false # use only issueDate (ignore expiry) for "fresh enough" check
validMonths: 6 # shortcut: applied to every provider that omits its own validMonths
addressTypes: [dwelling, poBox] # allowed PoA address types
acceptableLanguages: [en, de, fr]
# Document providers and the doc sub-types each may produce
# Keys (PoaCompanyContactType): bank | utilityProvider | governmentOrganization | mobileOperator | other
providers:
bank:
validMonths: 6
acceptUnconventional: true # accept non-mainstream banks (with allowedOrgNames below)
subTypes: [bankStatement, bankLetter, other]
allowedOrgs: # only used when acceptUnconventional=true
names: ["Some Local Co-op Bank"]
websites: ["coopbank.example"]
forbiddenDocumentNames: []
forbiddenOrgNames: []
forbiddenOrgWebsites: []
utilityProvider:
subTypes: [telecom, utilityBill, other]
governmentOrganization:
subTypes: [statement, voterRegistration, taxBill, other]
mobileOperator: {} # accept defaults
other:
subTypes: [lease, other, universityLetter]
# Accept identity document as proof of address
poiAsPoa:
enabled: true # acceptPoiAsPoa
sameDoc: true # acceptSamePoiAsPoa (same doc for POI + POA)
validMonths: 3
allowedTypes: [PASSPORT, ID_CARD, RESIDENCE_PERMIT, DRIVERS]
# Name/address comparison between POI and POA
crossValidator:
nameMode: weakContainment # strict | weakContainment | def | ai | fuzzy | containment | fuzzyContainment
addressMode: fuzzy # strict | fuzzy
fuzzyThreshold: 0.75
ignoreMiddleName: false
ignoreFixedInfo: false
# Per-country overrides — same shape as `settings`. Only the keys you set are overridden;
# others fall through to the global `settings`.
byCountry:
BRA:
validMonths: 3 # tighter validity for Brazil
providers:
bank:
validMonths: 3
Provider 类型值(providers.<key>)
bank、utilityProvider、governmentOrganization、mobileOperator、other。
子类型(providers.<key>.subTypes[])
statement、voterRegistration、taxBill、telecom、utilityBill、bankStatement、bankLetter、lease、universityLetter、employmentLetter、other。
地址类型(addressTypes[])
dwelling、poBox、poBoxSpecialCountries。
POI-as-POA allowedTypes[]
标准 IdDocType 值:PASSPORT、ID_CARD、RESIDENCE_PERMIT、DRIVERS(其他类型较少见)。
姓名比对模式(crossValidator.nameMode)
strict、weakContainment、def、ai、fuzzy、containment、fuzzyContainment。
地址比对模式(crossValidator.addressMode)
strict、fuzzy。
输出
成功时,先给出便于阅读的信息:
name、国家范围,以及每个国家覆盖规则所针对的国家列表。- 简要说明(涵盖的 provider 类型、默认有效期)。
- 控制面板链接:
https://cockpit.sumsub.com/checkus/sdkIntegrations/globalSettings/userVerification/proofOfAddress/<id>?clientId=<clientId>&sbx=true。以可点击的 Markdown 链接形式呈现。id和clientId均取自 POST 响应正文;sbx=true用于指向 Sandbox 工作区。 - 最后单独一行:
Preset ID (for level wiring / future PATCH): <id>。
失败时:提供 HTTP 状态码及 Sumsub 的 description/errorName。遇到无效枚举值或不可能的组合时,构建器会提前拒绝,并给出明确提示。
面向用户的消息中使用名称,而非 ID
这适用于所有关于预设的消息——POST 前摘要、流程中的状态更新、交接语句——不只是最终报告:
- 在文字中通过
name指代预设(“POA — 60 days”),不要使用其id。 id只能出现在专门的最终行(Preset ID for level wiring: <id>)中——这是唯一适合直接显示原始 ID 的地方,因为用户需要将其复制到某个级别的poaPresetId中。- 如果调用方是将此预设串接到
PROOF_OF_RESIDENCE步骤中的级别技能,级别技能也应在其 POST 前摘要中通过名称指代此预设——请参阅sumsub-create-level。
交接给 sumsub-create-level
返回的 id 是传入级别的 PROOF_OF_RESIDENCE 文档集所需的值。级别技能将其作为易用的 poaPresetId 快捷属性公开(或使用规范属性 poaStepSettingsId):
{
"type": "PROOF_OF_RESIDENCE",
"docTypes": ["UTILITY_BILL", "BANK_STATEMENT"],
"poaPresetId": "<id from this skill>"
}
请参阅 sumsub-create-level/examples/with-presets.json。
完整示例
examples/minimal.json— 最简预设:银行/公共事业/政府文件均采用 6 个月默认有效期,关闭 POI-as-POA。examples/eu-bank-friendly.json— 仅适用于 EU 的预设,银行对账单有效期较宽松,允许将 POI-as-POA 用于 3 个月。examples/per-country-tight.json— 全局默认设置加上更严格的 Brazil 覆盖设置。
另请参阅
- references/poa-preset-schema.md — 完整的
PoaStepSettings架构、所有枚举及注意事项。