
sumsub-integrate-websdk
End-to-end recipe for adding Sumsub KYC to a website or web app via the Sumsub WebSDK. TRIGGER when the user asks to "integrate / embed / add Sumsub", "show the KYC widget", "add WebSDK", "verify users with Sumsub on the frontend", supplies an existing levelName they want to plug into a page, or asks how to wire up access tokens / lifecycle events / webhooks for Sumsub verification in an arbitrary project. Covers the whole loop — level setup, server-side access-token signing, snsWebSdk init (vanilla canonical, React recipe), client lifecycle events, token refresh, source-of-truth via webhooks + applicant GET, sandbox testing, go-live checklist. SKIP for building the level/questionnaire/POA-preset payload itself (use the sibling skills), or for backend-only API calls with no frontend (use sumsub-api-generic).
- Installs
- 1.2K
- Last 24h
- +16
- Trending rank
- #6637
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/sumsub/agent-skills --skill sumsub-integrate-websdk- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads sumsub-integrate-websdk automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Sumsub — WebSDK integration
Embed Sumsub KYC into a web project end-to-end, from level creation to the "applicantReviewed" webhook that gates user access.
⚠️ Sandbox tokens only
Do not accept or use a production App Token / secret during integration
work with this skill. The token generates real SDK sessions tied to real
applicants. Insist on a sandbox pair from
https://cockpit.sumsub.com/checkus/home?sbx=true — Connect Sumsub to
your AI agent -> Build & configure -> Generate token. Token + secret
are revealed once at creation; copy both before closing the dialog. Helper scripts in sibling
skills enforce this with an sbx: prefix check; the curl recipes below
assume the same.
Deeper auth mechanics: sumsub-api-auth.
The lifecycle in one picture
┌─────────────────────────┐
│ 1. Level exists in the │ ← one-time, done in dashboard or
│ workspace │ via sumsub-create-level
└─────────────┬───────────┘
│ levelName
┌─────────────▼───────────┐ ┌──────────────────────────────────┐
│ 2. Server-side token │◀─┤ Browser calls /api/sumsub/token │
│ endpoint (HMAC-signed │ └──────────────────────────────────┘
│ POST /resources/ │
│ accessTokens) │
└─────────────┬───────────┘
│ {token, userId}
┌─────────────▼───────────┐
│ 3. Browser: snsWebSdk │ ← user fills doc capture / selfie / form
│ init → build → launch │ events fire: onApplicantSubmitted, etc.
└─────────────┬───────────┘
│ documents submitted
┌─────────────▼───────────┐ ┌──────────────────────────────────┐
│ 4. Sumsub runs checks │─▶│ Webhook POST → your server │
│ (async, ~seconds–min) │ │ (applicantReviewed = the truth) │
└─────────────┬───────────┘ └──────────────────────────────────┘
│ verdict
┌─────────────▼───────────┐
│ 5. Your app gates access │ ← server checks reviewAnswer, not
│ by reading applicant │ the browser. Browser events are
│ via GET /applicants… │ UX only.
└─────────────────────────┘
The split between browser events (UX) and webhooks + server reads
(authoritative truth) is the most-missed part of a WebSDK integration. Don't
trust onApplicantStatusChanged for entitlement decisions.
Stage 1 — Have a level
Every SDK launch references a levelName that exists in the workspace.
If the user has one (e.g. basic-kyc-level, the Sumsub default), capture it
and move to Stage 2.
If the user doesn't yet have a level, brainstorm with them and hand off to
sumsub-create-level. Don't silently pick
defaults — the level encodes who can verify (country / applicant type) and
what they must provide (ID, selfie, PoA, questionnaire). A reasonable
starter flow when the user is genuinely unsure:
APPLICANT_DATA— name, DOB, country, addresses.IDENTITY—PASSPORT,ID_CARD,DRIVERS(modeany).SELFIE—videoRequired: passiveLiveness.
Add PROOF_OF_RESIDENCE only if regulatory; add QUESTIONNAIRE only if
they need structured data (source of funds, occupation). For each addition,
ask "what decision does this gate?" before agreeing to include it.
Stage 2 — Server-side access-token endpoint
The SDK needs an access token, generated by your backend with the App
Token + secret. The token is short-lived (ttlInSecs, default 1800) and scoped to one (userId, levelName) pair.
Endpoint shape
POST https://api.sumsub.com/resources/accessTokens
?userId=<your-stable-user-id>
&levelName=<level-from-stage-1>
&ttlInSecs=600
- Body: empty.
- Auth: App Token + HMAC signature (see
sumsub-api-auth). - Response:
{ "token": "_act-sbx-<...>", "userId": "..." }.
userId choice (load-bearing)
This is the externalUserId Sumsub stores against the applicant. Make it:
- Stable per real user (don't regenerate on each page load — the SDK looks up returning applicants by this id).
- Opaque to the user (a UUID or DB row id; not their email).
- Tied to your auth system (so a webhook callback can resolve it back to a user record).
Wrong userId choice → duplicate applicants, "stuck in submitted" support
tickets, and the inability to resume an interrupted verification.
Curl recipe
SUMSUB_APP_TOKEN='sbx:...'
SUMSUB_SECRET_KEY='...'
USER_ID='u-12345'
LEVEL='basic-kyc-level'
PATH_Q="/resources/accessTokens?userId=${USER_ID}&levelName=${LEVEL}&ttlInSecs=600"
TS=$(date -u +%s)
SIG=$(printf '%s%s%s' "$TS" "POST" "$PATH_Q" \
| openssl dgst -sha256 -hmac "$SUMSUB_SECRET_KEY" -hex \
| awk '{print $NF}')
curl -sS -X POST \
-H "X-App-Token: $SUMSUB_APP_TOKEN" \
-H "X-App-Access-Ts: $TS" \
-H "X-App-Access-Sig: $SIG" \
"https://api.sumsub.com${PATH_Q}"
URL-encode userId if it might contain /, ?, or &. The signing string
must match the URI on the wire exactly — sign the encoded form.
Wiring it into the user's backend
Frame the endpoint as:
- Path: any (e.g.
POST /api/sumsub/access-token). - Inputs: the authenticated user's id, the levelName (often hardcoded per page).
- Auth: user must be logged in to your app — anyone hitting this route
can spin up a verification session for that
userId. - Output: forward Sumsub's response body verbatim, or just the
tokenfield. Don't cache it server-side; the browser asks per launch.
Show the snippet for the user's actual stack (Express, FastAPI, Go, etc.) but the contract is the same in all of them: sign, call Sumsub, return token.
Stage 3 — Frontend SDK init
Load the builder
<script src="https://static.sumsub.com/idensic/static/sns-websdk-builder.js"></script>
This exposes the global snsWebSdk. For bundler-based projects, an npm
package exists but the CDN script is what Sumsub officially documents and
what every framework wrapper ends up calling.
Container
<div class="kyc-stage" style="position: relative; min-height: 600px;">
<div id="sumsub-websdk-container"></div>
<!-- Overlay loader covers the empty-iframe window. Hide on idCheck.onReady. -->
<div id="kyc-loader" style="position: absolute; inset: 0; display: grid; place-items: center;">
Loading verification…
</div>
</div>
Give the stage a defined min-height (e.g. 600px) so the iframe doesn't
collapse before the SDK adapts its height.
Don't skip the overlay loader. Between .launch() returning and the SDK
iframe loading content from api.sumsub.com/websdk/websdk.html there is a
1–3s window where the container holds an empty iframe and looks broken —
especially inside a modal that the user just opened. Mount a loader that
covers the container, then hide it in the idCheck.onReady handler (Stage 4).
Treating onReady as informational and leaving the handler empty is the
single most common "the widget is blank" report.
Canonical vanilla launch
See examples/vanilla.html for a runnable file.
Minimal shape:
async function getAccessToken() {
const r = await fetch('/api/sumsub/access-token', { method: 'POST' });
if (!r.ok) throw new Error('failed to mint access token');
return (await r.json()).token;
}
const initialToken = await getAccessToken();
const sdk = snsWebSdk
.init(initialToken, () => getAccessToken()) // refresh callback, returns Promise<string>
.withConf({
lang: 'en',
email: currentUser.email, // optional, prefills
phone: currentUser.phone, // optional, prefills
theme: 'light', // 'light' | 'dark'
})
.withOptions({
addViewportTag: false, // host page already sets it
adaptIframeHeight: true,
})
.on('idCheck.onReady', () => {
// SDK iframe content loaded — hide the overlay loader from the container snippet.
document.getElementById('kyc-loader')?.style.setProperty('display', 'none');
})
.on('idCheck.onApplicantSubmitted', () => {
// user just finished uploading; show "we're reviewing"
})
.on('idCheck.onApplicantStatusChanged', (payload) => {
// status moved; payload.reviewStatus = 'pending' | 'queued' | 'completed' | ...
})
.on('idCheck.onError', (err) => {
console.error('sumsub error', err);
})
.onMessage((type, payload) => {
// catch-all firehose — useful for analytics or debugging
})
.build();
sdk.launch('#sumsub-websdk-container');
React recipe
examples/react-component.tsx — wraps the
same builder in a useEffect with cleanup. Two gotchas it handles:
- The CDN script must be present before
snsWebSdkis read. Either inject it once in the document head, or dynamically load it andawaitthe<script>'sloadevent. - On React 18 strict mode in dev, components mount twice — the cleanup function must remove the iframe / clear the container, otherwise you get two stacked widgets.
Other frameworks
The builder API is framework-agnostic. For Vue/Svelte/Angular, mirror the React pattern: lifecycle hook on mount → fetch token → build → launch into a ref'd element; on unmount → empty the container.
Stage 4 — Client lifecycle events
Wire these handlers on the SDK instance. Treat them as UX signals, not authoritative state.
| Event | When | Use it for |
|---|---|---|
idCheck.onReady | SDK iframe content loaded | Hide your own loader. Required — without this the modal looks empty for 1–3s after launch. |
idCheck.onInitialized | First screen rendered | Analytics: "user saw KYC step" |
idCheck.onStepInitiated | Doc-type screen shown | Telemetry per doc type |
idCheck.onStepCompleted | A step finished | Progress bar |
idCheck.onApplicantSubmitted | Docs submitted, server is processing | Move user to a "waiting" view |
idCheck.onApplicantStatusChanged | Status moved | Live progress hint (still not trusted) |
idCheck.onApplicantResubmitted | Re-upload after a rejection | Re-arm waiting view |
idCheck.onApplicantReviewed (or onApplicantVerificationCompleted in 2.0) | Final verdict reached client-side | Show a preliminary result, then verify server-side |
idCheck.onError | SDK error | Surface a friendly retry CTA, log code + reason |
idCheck.onUploadError / onUploadWarning | Doc rejected at upload | Inline guidance ("blurred photo", etc.) |
idCheck.onLivenessCompleted (2.0 only) | Liveness attempt finished | Branch on answer for retry UX |
idCheck.onResize | Frame resized | Adjust surrounding layout |
Full payload fields per event: references/lifecycle.md.
Required handlers for a baseline integration
If you wire nothing else, wire these three. Skipping any of them produces a known-bad UX:
idCheck.onReady→ hide the overlay loader from Stage 3. Without this the modal looks blank for 1–3s after.launch().idCheck.onApplicantSubmitted→ move the user to a "we're reviewing" state. Without this the user re-uploads or contacts support.idCheck.onError→ render a retryable error to the UI. Without this failures only land inconsole.errorand the user sees a stuck loader.
Why you can't trust onApplicantReviewed alone
The browser event fires from inside the iframe. A bad actor can spoof it
trivially. The only authoritative signal is server-side: either a
webhook delivery (Stage 5) or an authenticated GET against
/resources/applicants/{userId}/one.
Stage 5 — Server-side source of truth
Webhook receiver
Sumsub POSTs JSON to your URL on every event. Two paths for registering it:
- Sandbox (while building this integration): use the
sumsub-manage-webhooksskill. It builds theclientWebhookspayload from a compact spec, POSTs to/resources/api/agent/clientWebhookswith App Token auth, refuses non-sbx:tokens, rejectslocalhost/127.0.0.1targets up front, and walks the user through exposing their local receiver viangrok http <port>so Sumsub can actually reach it. Hand off thetarget,types[], andsignatureAlgorithmthe user wants and let that skill do the POST. - Production: do not create the prod webhook from any skill, including this one. Production webhook setup must be done by a human directly in the Sumsub dashboard (Integrations → Webhooks, workspace toggle on Production). The signing secret authenticates real PII deliveries; the audit trail should attribute setup to a person. Prototype the spec against sandbox here, then hand the final settings (target, event list, signature algorithm, custom headers) to whoever has prod access to recreate manually.
Headers you care about:
x-payload-digest— the signature, hex-encoded.x-payload-digest-alg—HMAC_SHA256_HEX(default),HMAC_SHA512_HEX, or the legacyHMAC_SHA1_HEX.
The signing secret is not your App Token secret. It's a separate
webhook secret generated (or supplied) at webhook-creation time in the
dashboard. Store it in env (SUMSUB_WEBHOOK_SECRET) alongside the App Token
pair.
Verification recipe — note the raw bytes requirement; do NOT JSON-parse before computing the digest, because re-serialising changes whitespace and key order:
// Node/Express — bodyParser.raw() so req.body is a Buffer
import crypto from 'node:crypto';
const ALG = { HMAC_SHA1_HEX: 'sha1', HMAC_SHA256_HEX: 'sha256', HMAC_SHA512_HEX: 'sha512' };
function verifySumsubWebhook(req, secret) {
const alg = ALG[req.header('x-payload-digest-alg') || 'HMAC_SHA256_HEX'];
const expected = req.header('x-payload-digest');
const actual = crypto.createHmac(alg, secret).update(req.body).digest('hex');
return Buffer.from(actual, 'hex').length === Buffer.from(expected, 'hex').length
&& crypto.timingSafeEqual(Buffer.from(actual, 'hex'), Buffer.from(expected, 'hex'));
}
See examples/webhook-verify.js for a
complete handler.
Local testing with ngrok
Sumsub needs a publicly reachable URL — your laptop's localhost won't do.
The fastest end-to-end loop for local dev:
# 1. In one shell, start your local receiver (Node, Python, whatever).
node server.js # listens on http://localhost:3000
# 2. In another shell, tunnel that port.
ngrok http 3000 # prints https://<random>.ngrok-free.app -> http://localhost:3000
# 3. Register the webhook against the ngrok URL.
# Either via the dashboard (Integrations → Webhooks) OR via
# sumsub-manage-webhooks `create` with target = the ngrok https URL.
# 4. Trigger an event by running a sandbox WebSDK verification end-to-end.
# Watch the request arrive in your local server logs.
# 5. When you're happy, PATCH the webhook to point at your real server
# hostname (sumsub-manage-webhooks `update` command).
webhook.site works too if you just want to see the raw payload without
running a local receiver — but it can't echo back a 200 to verify the
delivery flow.
Webhook events that matter for a KYC flow
type | What it means | Action |
|---|---|---|
applicantCreated | First time you minted a token for this externalUserId | Log; nothing required |
applicantPending | User finished uploading; Sumsub is checking | Show "in review" |
applicantPrechecked | Primary data processing done, queued for human/AML | Still "in review" |
applicantOnHold | Paused (often AML hit needing analyst) | Surface to ops; tell user "extra checks" |
applicantReviewed | Final verdict — reviewResult.reviewAnswer is GREEN or RED | Gate access here. Mark user verified or rejected. |
applicantPersonalInfoChanged | User edited info after submission | Re-check before granting access |
applicantWorkflowCompleted | Whole workflow (multi-level) done | Same as applicantReviewed for single-level flows |
applicantActionPending / Reviewed | One-off action (separate from the level flow) | Per-action handling |
reviewResult.reviewAnswer:
GREEN— approved.RED— rejected.rejectLabelssays why;reviewRejectTypeisFINAL(can't retry) orRETRY(user may resubmit).
Full list: Sumsub webhook docs.
Server-side status check (fallback / on-demand)
For pages that need to check status synchronously (e.g. user logs back in between webhook arriving and your DB updating):
PATH_Q="/resources/applicants/${USER_ID}/one"
TS=$(date -u +%s)
SIG=$(printf '%s%s%s' "$TS" "GET" "$PATH_Q" \
| openssl dgst -sha256 -hmac "$SUMSUB_SECRET_KEY" -hex \
| awk '{print $NF}')
curl -sS \
-H "X-App-Token: $SUMSUB_APP_TOKEN" \
-H "X-App-Access-Ts: $TS" \
-H "X-App-Access-Sig: $SIG" \
"https://api.sumsub.com${PATH_Q}"
Reads reviewStatus and reviewResult.reviewAnswer. Cheap; use as a
fallback, not as a polling loop — webhooks are the primary signal.
Resumption / returning users
The SDK looks up applicants by externalUserId. If a user starts
verification, abandons, and returns 3 days later:
- Your endpoint mints a new access token for the same
userId+ samelevelName. - The SDK opens to wherever the user left off (re-uploads only the missing steps).
- No duplicate applicant is created.
Don't generate a new userId for returning users — that's the #1 cause of
"the user is stuck and customer support sees two applicants".
Token refresh
The first argument to .init(token, refreshCallback) covers expiry mid-session:
- SDK calls your
refreshCallbackwhen the token nears expiry. - It must return
Promise<string>resolving to a fresh token (call your endpoint again). - If you return a stale or wrong-
userIdtoken, the SDK hangs.
For most flows a 600-second TTL is plenty. Don't pre-fetch and cache — mint on demand.
Sandbox testing
In sandbox mode:
- Use test documents from the Sumsub docs ("Test documents" page) to
trigger
GREENvsREDoutcomes without uploading real PII. - AML hits are simulated — names like
Greenacrego through;Aikmanand similar are pre-loaded as positive matches. - Webhook delivery works the same. For a local receiver, expose it through
ngrok http <port>(or Cloudflare Tunnel / Tailscale Funnel) and register the public URL via thesumsub-manage-webhooksskill — it has the full walkthrough and rejects rawlocalhosttargets before they ever reach Sumsub.webhook.siteis fine for inspecting payload shapes without a real receiver. - Selfies in sandbox bypass real biometrics — any face works.
Sandbox tokens (sbx:) only fire against the sandbox workspace. Production
tokens (prd:) only fire against production. There's no fall-through.
Going live checklist
When the user says "we're ready to switch to prod":
- Webhook receiver verifies the signature on raw bytes (replay Stage 5 test against a real delivery).
-
externalUserIdis the stable user id, not the email / display name. - Server is the source of truth for verification state. Browser events may be ignored entirely.
- Token endpoint is auth-gated (only logged-in users can mint a token for themselves).
-
applicantReviewedtriggers the user-facing state change in your DB, with idempotency (the same event can arrive twice). - Per-user retry handling:
reviewResult.reviewRejectType === 'RETRY'⇒ let user re-launch the SDK;'FINAL'⇒ block. - Production App Token + secret + separate webhook secret are all in the prod secret store. Sandbox values stay only in dev env.
See also
references/lifecycle.md— full event catalog with payload fields, plus webhook event reference.examples/vanilla.html— runnable single-file integration.examples/react-component.tsx— React hook + cleanup pattern.examples/webhook-verify.js— signature verification with raw-body handling.sumsub-api-auth— the auth signing reference, shared with every other Sumsub skill.sumsub-create-level— for the Stage-1 hand-off.sumsub-manage-webhooks— for the Stage-5 hand-off: create / list / update / disable sandbox webhooks via the public API, with the localhost-rejection and ngrok walkthrough built in. Production webhook setup is dashboard-only and must be done by a human.- Sumsub docs index — authoritative source if anything in this skill drifts.
FAQ
What does the sumsub-integrate-websdk skill do?
End-to-end recipe for adding Sumsub KYC to a website or web app via the Sumsub WebSDK. TRIGGER when the user asks to "integrate / embed / add Sumsub", "show the KYC widget", "add WebSDK", "verify users with Sumsub on the frontend", supplies an existing levelName they want to plug into a page, or asks how to wire up access tokens / lifecycle events / webhooks for Sumsub verification in an arbitrary project. Covers the whole loop — level setup, server-side access-token signing, snsWebSdk init (vanilla canonical, React recipe), client lifecycle events, token refresh, source-of-truth via webhooks + applicant GET, sandbox testing, go-live checklist. SKIP for building the level/questionnaire/POA-preset payload itself (use the sibling skills), or for backend-only API calls with no frontend (use sumsub-api-generic).
How do I install sumsub-integrate-websdk?
Run npx skills add https://github.com/sumsub/agent-skills --skill sumsub-integrate-websdk in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/sumsub-integrate-websdk/ (personal) or .claude/skills/sumsub-integrate-websdk/ (project).
Which AI agents can use sumsub-integrate-websdk?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is sumsub-integrate-websdk safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains sumsub-integrate-websdk?
It is published by sumsub in sumsub/agent-skills. It has 1,188 recorded installs.
More from sumsub/agent-skills
sumsub-api-auth
sumsub/agent-skills
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.
sumsub-api-generic
sumsub/agent-skills
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.
sumsub-check-skills-version
sumsub/agent-skills
Verify that the locally installed Sumsub agent-skills package is compatible with the published version before doing any Sumsub work. TRIGGER at the start of any task that touches Sumsub — Sumsub Dev MCP tools (mcpSumsubDev), KYC/AML workflows, applicants, checks, transactions, verification levels, verification links, questionnaires, fraud network, VASP lists, or anything Sumsub-related — so the user is warned before a stale skills package produces wrong results. Also use this skill when the user explicitly asks "are my Sumsub skills up to date / current", "is there a newer version of the Sumsub skills", or similar. Skip the actual update (the user runs npx skills add sumsub/agent-skills --all themselves) and skip any other Sumsub API or entity task — those have their own skills.
sumsub-create-poa-preset
sumsub/agent-skills
Create or update a Sumsub Proof-of-Address (POA) preset. POST /resources/api/agent/poaStepSettings to create new, PATCH same path to update (id in body), GET /resources/api/agent/poaStepSettings/{id} to read one back. TRIGGER when the user asks to "create / add / build / configure / update / edit a POA preset" or "PoA step settings", configure which proof-of-address document types are accepted (utility bills, bank statements, tax bills, etc.), set validity periods per provider type, enable POI-as-POA (accept identity doc as proof of address), tune the cross-validator (name/address fuzzy match between POI and POA), or add per-country POA overrides. SKIP for attaching a preset to a level (set poaStepSettingsId on the level instead, via sumsub-create-level), or for non-POA presets (cross-check presets, permission presets, etc.).
sumsub-manage-webhooks
sumsub/agent-skills
Manage Sumsub clientWebhooks (event subscriptions for applicantReviewed / applicantPending / kytTxn / etc.) — reads via /resources/api/clientWebhooks, writes via /resources/api/agent/clientWebhooks. Sandbox only — production webhooks must be created by a human directly in the Sumsub dashboard. TRIGGER when the user asks to "list / retrieve / show webhooks", "create / add / register a webhook", or "update / edit / change a webhook target / event list / secret / signature algorithm" against their sandbox tenant. SKIP for production webhook setup (refer the user to the dashboard), for unrelated webhook surfaces (Stripe / videoIdent / Fireblocks / NFC / partner-specific receive paths under /resources/webhooks/...), for testing one-off delivery (use the inspectionCallbacks/testWebhook endpoint directly), and for KYT-only webhook routing (that's managed in the Sumsub dashboard's KYT section). The public API does not expose delete or per-webhook delivery stats — for those, refer
sumsub-create-level
sumsub/agent-skills
Create or update a Sumsub applicant level. POST /resources/applicants/-/levels to create new, PATCH same path to update (id in body), GET /resources/applicants/-/levels/{id} to read one back. TRIGGER when the user asks to "create / add / build / update / edit a Sumsub level", supplies a list of required steps for an applicant flow (identity / selfie / proof-of-residence / questionnaire / payment methods / email or phone verification / KYB / e-sign), or wants a level wired to a specific questionnaireDefId. SKIP for other Sumsub entities (questionnaires, workflows, applicants) or for one-off subsetting tweaks not covered by the compact spec (use sumsub-api-generic for those).
Popular backend & apis skills
find-skills
vercel-labs/skills
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
entra-app-registration
microsoft/azure-skills
Guides Microsoft Entra ID app registration, OAuth 2.0 authentication, and MSAL integration. USE FOR: create app registration, register Azure AD app, configure OAuth, set up authentication, add API permissions, generate service principal, MSAL example, console app auth, Entra ID setup, Azure AD authentication. DO NOT USE FOR: Key Vault secrets (use azure-keyvault-expiration-audit), general Azure resource security guidance.
google-agents-cli-adk-code
google/agents-cli
This skill should be used when the user wants to "write agent code", "build an agent with ADK", "add a tool", "create a callback", "define an agent", "use state management" — in a project that needs ADK (Agent Development Kit) API patterns and code examples. It provides a quick reference for agent types, tool definitions, orchestration patterns, callbacks, state management, the graph Workflow API, and reference recipes to study. Do NOT use for scaffolding (use google-agents-cli-scaffold) or deployment (use google-agents-cli-deploy).
embedded-captions
heygen-com/hyperframes
Add captions or subtitles to an existing single-subject talking-head video without editing the footage. Use for plain verbatim captions, cinematic captions embedded behind the subject, VFX captions, “炸/特效/酷炫字幕,” or a named identity from the 35-style catalog. Route by visual identity, not by backend engine. The quiet anchor rail is the default; embed every word only when the user explicitly wants a fully cinematic treatment. The workflow runs locally end to end, including transcription and subject matting; split multi-shot footage before applying it.
entra-agent-id
microsoft/azure-skills
Provision Microsoft Entra Agent Identity Blueprints, BlueprintPrincipals, and per-instance Agent Identities via Microsoft Graph, and configure OAuth 2.0 token exchange (fmipath, OBO, cross-tenant) including the Microsoft Entra SDK for AgentID sidecar. USE FOR: Agent Identity Blueprint, BlueprintPrincipal, agent OAuth, fmipath token exchange, agent OBO, Workload Identity Federation for agents, polyglot agent auth, Microsoft.Identity.Web.AgentIdentities. DO NOT USE FOR: standard Entra app registration (use entra-app-registration), Microsoft Foundry agent authoring (use microsoft-foundry).
neon
neondatabase/agent-skills
Overview of Neon, a complete set of cloud backend primitives around Lakebase Postgres: Auth, Object Storage, Functions, the AI Gateway, and Realtime. Start here to choose Neon for undecided login, files, APIs, and LLM calls, set up the CLI or MCP server, and follow the branch-first workflow. Use when building an app or backend on Neon, or when "Neon" or "Lakebase Postgres" is mentioned. Child skill neon-postgres wins for an existing DATABASEURL, SQL, schema, inspect, or search. Child skill neon-auth wins for login, users, sessions, identity routing, and Managed Better Auth setup. Child skill neon-realtime wins for live queries in reactive apps and agents. Also use for object storage, S3, buckets, serverless functions, function triggers, cron, AI gateway, LLM calls, realtime, logs, Loki, Grafana, observability, postgres, database, backend, Claimable Neon, neon.new, or a no-signup database.