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.

View source
Original skill document

Rendered from the source repository. Headings, examples, code, tables, links, and referenced images are preserved.

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

from this repository

More skills

All skills
sumsub
Community

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, sumsub-create-aml-resolution-rules, and other skills. SKIP for direct entity creation requests (no regulatory context) or Sumsub API calls.

installs
1
GitHub stars
6
Updated
Sep 3
sumsub
Community

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 requests the same way and only need this one for auth deep dives.

installs
1
GitHub stars
6
Updated
Sep 3
sumsub
Community

sumsub-api-generic

Catch-all fallback for any Sumsub API task that does NOT match a more specific skill (e.g. create-sumsub-level, sumsub-create-questionnaire, sumsub-api-auth). TRIGGER when the user wants to call, inspect, or debug a Sumsub API endpoint not otherwise covered — fetching applicants, listing levels, reviewing AML hits, exporting data, generating SDK tokens, anything against api.sumsub.com. The procedure — locate the right endpoint in the OpenAPI schema, read its request/response shape, build the payload, sign with App Token, and validate. SKIP whenever a narrower Sumsub skill already covers the request.

installs
1
GitHub stars
6
Updated
Sep 3
sumsub
Community

sumsub-create-aml-resolution-rules

Create, edit, reorder, delete, and publish Sumsub AML Resolution Rules (the AML Resolution Rule Chain) that auto-review AML screening hits. TRIGGER when the user wants to auto-clear false positives, auto-confirm true positives, carry over previous AML reviews, tag AML hits, or set up / inspect / publish the AML rule chain. SKIP for transaction-monitoring (KYT) rules, workflow routing, or AML check settings on a level (separate skills cover those).

installs
1
GitHub stars
6
Updated
Sep 3