Sumsub Create Level
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).
- Skill ID
- sumsub/agent-skills/sumsub-create-level
- Publisher
- sumsub
- Repository
- agent-skills
- Installs
- 0
- Files
- 13
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
sumsub/agent-skills/sumsub-create-levelInstalls these files- SKILL.md
- examples/full-kyc.json
- examples/identity-live-capture.json
- examples/identity-selfie.json
- examples/kyb-company.json
- examples/payment-methods.json
- examples/questionnaire-only.json
- examples/with-presets.json
- references/level-schema.md
- scripts/build_level.py
- scripts/get_level.sh
- scripts/patch_level.sh
- scripts/post_level.sh
What this skill tells the agent
Sumsub — Create Level
Builds an ApplicantLevel JSON payload from a compact spec, POSTs (or PATCHes) it to the Sumsub API, and reports the resulting name / id.
Endpoints
| Method | Path | When |
|---|---|---|
POST | /resources/applicants/-/levels | Create a new level. Body must NOT include id or key — server assigns them. |
PATCH | /resources/applicants/-/levels | Update an existing level (by id in body). |
GET | /resources/applicants/-/levels/{id} | Read one level. Use this to verify what landed (tenant gates may silently drop fields) or to resolve name from a known id. |
GET | /resources/applicants/-/levels | List all levels (use to reuse existing levels before creating duplicates). |
Body: `ApplicantLevel`. Returns the persisted level with id, createdAt, audit trails.
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 — creating a level is a workspace-visible write. If the user offers a prod token, 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:.| Var | Example |
|---|---|
SUMSUB_APP_TOKEN | sbx:... — sandbox App Token from the dashboard. |
SUMSUB_SECRET_KEY | The paired secret shown once at token creation. |
SUMSUB_BASE | Optional. 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.
Procedure
- Fetch tenant entitlements. Invoke the
sumsub-check-permissionsskill and parse the JSON result. Store theallowedChecksmap (its keys are the enabled entitlements); use it for all feature-gate checks in step 2 and the entitlements section below. Do this before anything else. - Check existing entities. Before building anything, list existing levels, POA presets, and questionnaires (GET the respective list endpoints). If a matching entity already exists, offer to reuse its
idand skip the POST — the server creates a duplicate on every POST with no name deduplication. - Translate the user's request to the compact spec below — name, applicant type, and a list of doc-set steps in the order they should appear in the WebSDK flow.
- Validate — confirm every
typeis a realIdDocSetType, everyQUESTIONNAIREstep has aquestionnaireDefIdthat points to an existing questionnaire, everyPROOF_OF_RESIDENCE*step has apoaPresetId/poaStepSettingsId(the server rejects the level if it's missing — runsumsub-create-poa-presetfirst if no preset exists), everyCOMPANYstep has at least one named sub-step. Use theallowedCheckskeys from step 0 to reject any entitlement-gated feature not present in it. - Generate payload — run
${CLAUDE_SKILL_DIR}/scripts/build_level.pywith the spec on stdin → full payload on stdout. - Show the resolved payload to the user and ask for explicit confirmation before the first POST.
- Create vs. update:
- New level — POST via
${CLAUDE_SKILL_DIR}/scripts/post_level.sh. Returns response body + HTTP status. - Update existing — GET the current state via
${CLAUDE_SKILL_DIR}/scripts/get_level.shso the user sees the diff, then PATCH via${CLAUDE_SKILL_DIR}/scripts/patch_level.sh. The spec passed to `build_level.py` must include `id: <level-id>` — the builder preserves it into the payload, and PATCH refuses bodies without it. PATCH replaces `requiredIdDocs.docSets` as a single array — every docSet you send must carry the full intended state, since fields omitted from a docSet are wiped on the server. Copy preserved values from the GET response into your PATCH spec.
- GET the level back via
${CLAUDE_SKILL_DIR}/scripts/get_level.shand compare to what was sent — several fields land differently from what was sent (see gotchas in references/level-schema.md). Report any discrepancy to the user. - Build the dashboard link. Read
id,applicantType, andclientIdfrom the response body and format:
https://cockpit.sumsub.com/checkus/sdkIntegrations/levels/<applicantType>Level/<id>?clientId=<clientId>&sbx=trueThe <applicantType>Level segment is literally individualLevel for applicantType: individual (confirmed) and companyLevel for applicantType: company (assumed by analogy — surface as the best guess and flag if it 404s). The sbx=true query param targets the Sandbox workspace — it is the canonical sandbox link param shared across all skills.
- Report — lead with the human-readable name:
name,applicantType, ordered list of docSets created.- Dashboard link as a clickable markdown link.
- Final line:
Level ID (for SDK access tokens / future PATCH): <id>.
Surface 4xx errors verbatim — they usually point to a missing questionnaireDefId or an unknown enum value.
Tenant entitlements
Many level settings are gated behind tenant entitlements (allowedChecks). Before enabling a feature, check that the required BackgroundCheckTarget is present as a key in the allowedChecks map returned by `sumsub-check-permissions` (fetched in step 0).
DocSet type → required permission (OR — any one suffices):
| DocSet type | Required (any one of) | |||
|---|---|---|---|---|
QUESTIONNAIRE / QUESTIONNAIRE2-4 | QUESTIONNAIRE | |||
COMPANY / COMPANY_DATA | COMPANY \ | KYB_FULL \ | KYB_AUTO_AML_AND_REGISTRY \ | KYB_AUTO_AML_ONLY |
SOLANA_ATTESTATION / LINEA_ATTESTATION | PAYMENT_METHOD_CRYPTO | |||
PAYMENT_METHODS | PAYMENT_SOURCE \ | PAYMENT_METHOD \ | PAYMENT_METHOD_CRYPTO \ | KYT_UNHOSTED_WALLET_VERIFICATION |
INVESTABILITY | PROOF_OF_FUNDS | |||
PROOF_OF_RESIDENCE / PROOF_OF_RESIDENCE2 | POA \ | ADVANCED_POA_TYPE_DETECTION (often missing from allowedChecks even when the API actually allows it — proceed with a one-line warning; see below) | ||
E_KYC | E_KYC_TARGET | |||
E_SIGN | E_SIGN_TARGET | |||
TR_RECIPIENT_INFORMATION | TRAVEL_RULE | |||
DEVICE_CHECK | DEVICE_INTELLIGENCE |
Types not in this table (IDENTITY, SELFIE, APPLICANT_DATA, EMAIL_VERIFICATION, PHONE_VERIFICATION, etc.) are available to all tenants — no entitlement required.
AML / watchlist screening → `WATCHLISTS`. This isn't a docSet — it's level-wide behavior. When WATCHLISTS is in allowedChecks, AML/PEP/sanctions screening runs on by default on every level (turn it off per-level with disableWatchlists: true). When WATCHLISTS is absent, screening is off tenant-wide and no level setting enables it — treat a policy that needs AML screening as blocked on the missing entitlement (contact CSM), same as the docSet gates above.
If a requested feature requires an entitlement the tenant doesn't have — stop immediately. Do not build or POST the level. Tell the user which entitlement is missing, that the feature is unavailable on their account, and that they need to contact their CSM or Sumsub support to get it enabled. Resume only after the user confirms the entitlement has been added or explicitly decides to drop the feature.
More from sumsub
Use this skill in a project
Open any RiverX project, search the Skills panel for sumsub/agent-skills/sumsub-create-level, and install it in one click.
