sumsub/agent-skills

sumsub-manage-webhooks

Manage Sumsub clientWebhooks (event subscriptions for applicantReviewed / applicantPending / kytTxn / etc.) — reads via /resources/api/clientWebhooks, writes via /resources/api/agent/clientWebhooks.

ソースを見る

使い方

  1. インストールコマンドをコピーし、自分の環境へ導入する前にソースを確認します。
  2. 必要なツール、認証情報、対応環境を原文で確認します。
  3. 入力と成果物を指定し、出力を資料と照合します。
npx skills add https://github.com/sumsub/agent-skills --skill sumsub-manage-webhooks

開始前の確認

  • 導入にはモデル契約、API枠、ファイルへのアクセス許可は含まれません。
  • スター数や導入数は活動の指標であり、独立した品質・安全性試験ではありません。
リポジトリの原文

見出し、例、コード、表、リンク、参照画像を含む原文を表示しています。

Sumsub — Manage Client Webhooks

Lists, retrieves, creates, and updates ClientWebhook event subscriptions. Reads use /resources/api/clientWebhooks; writes use /resources/api/agent/clientWebhooks.

Endpoints

VerbPathPurpose
GET/resources/api/clientWebhooksList 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/clientWebhooksCreate. 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/clientWebhooksUpdate 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.

Auth — App Token + secret (sandbox only)

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/home?sbx=true> (Connect Sumsub to your AI agent -> Build & configure -> Generate token). 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_TOKENsbx:... — sandbox App Token from the dashboard.
SUMSUB_SECRET_KEYThe paired secret shown once at token creation.
SUMSUB_BASEOptional. 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.

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

Because this skill only accepts sandbox App Tokens, every webhook it creates or updates 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.

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)

create and update both call build_webhook_payload.py to expand the compact spec.

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-updated (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.

Compact spec for create / update

yaml
# Identity (omit on create; required on update)
id: 698bfc...                  # id from a previous list / create response

# 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)

# 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

# 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

# Lifecycle flags
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).

Event 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 lifecycleapplicantCreatedNew applicant created
applicantPrecheckedPre-screen complete
applicantPendingSubmitted for review
applicantReviewedFinal review answer (GREEN / RED) reached
applicantOnHoldReview held / paused
applicantActivatedApplicant activated
applicantDeactivatedApplicant deactivated
applicantResetVerification reset (retry)
applicantLevelChangedLevel reassigned
applicantTagsChangedTags added/removed
applicantPersonalInfoChangedPersonal info edited
applicantDeletedApplicant deleted
applicantPersonalDataDeletedGDPR personal-data erasure executed
Action workflowapplicantActionPending / applicantActionReviewed / applicantActionOnHoldAction-flow events
WorkflowapplicantWorkflowCompletedWorkflow run finished (not applicantWorkflowRunCompleted)
Video identvideoIdentStatusChangedLive status update
videoIdentCompositionCompletedRecording assembly finished
KYT (applicant-scoped)applicantKytTxnApproved / applicantKytTxnRejected / applicantKytTxnReviewed / applicantKytTxnDeleted / applicantKytTxnDataChanged / applicantKytTxnAwaitingUser / applicantKytOnHoldPer-applicant transaction-monitoring events
KYT (case-scoped)kytCaseCreated / kytCaseStatusChanged / kytCaseReviewedKYT case-management events (note: it's kytCaseStatusChanged, not kytCaseUpdated)
AML caseamlCaseApproved / amlCaseRejected / amlCaseOnHoldAML-case disposition events
Travel RuletravelRuleActionTravel-rule lifecycle events
KYBkybCompanyActivityKYB ongoing-monitoring events

The skill forwards whatever the caller writes — no client-side validation, since Sumsub may add events faster than this list updates.

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.

Worked examples

See also

タスクに関連する項目

同じリポジトリから

関連する Skills

すべての Skills
sumsub
コミュニティ

sumsub-integrate-travel-rule

End-to-end recipe for integrating Sumsub Travel Rule — deciding which of the three exchange flows applies, identifying the counterparty VASP, submitting the transfer, reading the exchange status, finalising or cancelling it, answering requests other VASPs send you, handling the unhosted-wallet path when no VASP is attributed, and finding existing transactions (deduplication before after-settlement exchanges). TRIGGER when the user asks to "integrate / add / implement Travel Rule", "send Travel R

導入数
1
GitHub Stars
7
更新日
10月2日
sumsub
コミュニティ

sumsub-manage-wallet-address-book

Register the crypto wallet addresses an organisation controls, so Sumsub can resolve address ownership without a human. Bulk-imports addresses into the Wallet Address Book via POST /resources/kyt/walletAddress/import, and registers a single address against a specific applicant via POST /resources/api/applicants/{applicantId}/payments. TRIGGER when the user asks to "upload / import / register our wallet addresses", "add addresses to the Wallet Address Book", "register a user's crypto wallet as a

導入数
1
GitHub Stars
7
更新日
10月2日
sumsub
コミュニティ

sumsub-analyze-regulation

Analyze a regulation document (PDF or text) and produce a Sumsub configuration plan — mapping regulatory requirements to Sumsub entities (levels, questionnaires, PoA presets, TM rules, workflows, AML resolution rules). TRIGGER when the user provides a regulation PDF, legal act, or compliance requirement document and wants to know what to configure in Sumsub. Acts as the entry point before invoking sumsub-create-level, sumsub-create-questionnaire, sumsub-create-poa-preset, sumsub-create-workflow,

導入数
2
GitHub Stars
7
更新日
10月2日
sumsub
コミュニティ

sumsub-api-auth

Authenticate to the Sumsub API with an App Token + secret key (HMAC-SHA256 request signing). TRIGGER when the user asks to "call / sign / authenticate Sumsub API requests", debugs 401 Unauthorized / signature errors against api.sumsub.com, or needs a working request example with X-App-Token / X-App-Access-Sig / X-App-Access-Ts headers. SKIP only when a more specific skill in this repo (questionnaire/level/workflow/POA-preset/generic) already covers the user's actual task — those skills sign requ

導入数
2
GitHub Stars
7
更新日
10月2日