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

By sumsub · 845 installs

npx skills add sumsub/agent-skills --skill sumsub-create-level

Source repository · Upstream listing

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 ](references/level schema.md). 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](https://docs.sumsub.com/reference/authentication). The full how it works writeup lives in the [ sumsub api auth ](../sumsub api auth/SKILL.md) 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 0. Fetch tenant entitlements. Invoke the sumsub check permissions skill and parse the JSON result. Store the allowedChecks map (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. 1. 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 id and skip the POST — the server creates a duplicate on every POST with no name deduplication. 2. 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. 3. Validate — confirm every type is a real IdDocSetType , every QUESTIONNAIRE step has a questionnaireDefId that points to an existing questionnaire, every PROOF OF RESIDENCE step has a poaPresetId / poaStepSettingsId (the server rejects the level if it's missing — run sumsub create poa preset first if no preset exists), every COMPANY step has at least one named sub step. Use the allowedChecks keys from step 0 to reject any entitlement gated feature not present in it. 4. Generate payload — run ${CLAUDE SKILL DIR}/scripts/build level.py with the spec on stdin → full payload on stdout. 5. Show the resolved payload to the user and ask for explicit confirmation before the first POST. 6. 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.sh so 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. 7. GET the level back via ${CLAUDE SKILL DIR}/scripts/get level.sh and compare to what was sent — several fields land differently from what was sent (see gotchas in [references/level schema.md](references/level schema.md)). Report any discrepancy to the user. 8. Build the dashboard link. Read id , applicantType , and clientId from the response body and format: The <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. 9. 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 ](../sumsub check permissions/SKILL.md) (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. Exception — POA. The POA / ADVANCED POA TYPE DETECTION keys are often absent from allowedChecks even on tenants where the API actually accepts PROOF OF RESIDENCE levels (the entitlement seems to be baseline or covered by other keys; the documented mapping is stale on some tenants). When only POA is missing, proceed with a one line warning to the user so they have context if support is later needed. Do NOT pause for explicit confirmation — Sumsub itself will reject the write if the tenant truly lacks the right, and that 4xx will be more informative than a pre emptive halt. Surface any entitlement related error verbatim if it comes back. Safety Creating a level is a write to a shared workspace. Always: Show the resolved payload to the user before the first POST (step 4 above). After each successful POST, GET the entity back and compare to what was sent — silent overrides are common. Do not re POST a dependency (PoA preset, questionnaire) if it already succeeded mid session — reuse the returned id . Do not delete or modify levels you didn't create in this session unless the user explicitly names them. Names, not ids, in user facing messages This applies to every message you send the user about this level — not just the final report: Pre POST summary: when you list which questionnaire and which POA preset will be attached, refer to each by name / title (e.g. "POA preset «POA — 60 days»", "questionnaire «Applicant basics»"). Do not paste the raw id (" 6a16bfd4ded0fe13aa48165d ") into prose — the user can't read it and it does not let them judge whether you picked the right entity. Final report: still ends with Level ID (for SDK access tokens / future PATCH): <id on its own line — that line is the one place a raw id is correct, because the user needs to copy it for the next API call. Diagnostic messages: when a 4xx response references a dependency id (POA preset not found, etc.), translate it to the name before showing the user. If you don't yet know an entity's name (e.g. user supplied only an id from outside this session), GET the entity first and surface its name; do not fall back to the id. Compact spec format Accepts JSON or YAML on stdin. The builder fills in sensible defaults for each doc set type (see [references/level schema.md](references/level schema.md)). New levels must be WebSDK 2.0 ( websdkNext: true ). On create , the builder sets websdkNext: true automatically — you don't need it in the spec; just never set websdkNext: false (that ships a deprecated WebSDK 1.0 level). On update of an existing level (spec has an id ), the builder leaves websdkNext untouched and you should too: upgrading a live level's SDK is a heavy client side migration, so never flip it as a side effect of an unrelated PATCH — change it only if the user explicitly asks. Supported docSets[].type values APPLICANT DATA , EMAIL VERIFICATION , PHONE VERIFICATION , IDENTITY , IDENTITY2 / 3 / 4 , SELFIE , SELFIE2 , PROOF OF RESIDENCE , PROOF OF RESIDENCE2 , PROOF OF PAYMENT , PAYMENT METHODS , INVESTABILITY , COMPANY , COMPANY DATA , COMPANY DOCUMENTS , COMPANY BENEFICIARIES , ACCREDITED INVESTOR , E SIGN , QUESTIONNAIRE / 2 / 3 / 4 , E KYC , OTHER DOCS , TR RECIPIENT INFORMATION , DEVICE CHECK . Per type compact shortcuts type Shortcut keys Builder expands to IDENTITY docTypes ; videoRequired ( disabled / docapture ); captureMode & uploaderMode (sent only when docapture); nfcVerificationSettings: {mode} flat fields on the docSet — only what you set. See [Dashboard ↔ API mapping]( dashboard api mapping for identity step) below. SELFIE videoRequired (default passiveLiveness ; full set: disabled / enabled / photoRequired / passiveLiveness / staticLiveness ), docTypes (default ["SELFIE"] ); selfieProcessingSettings: {skipLivenessCheck, skipFaceMatchCheck} (used with payment method verification — see below) bare docSet with videoRequired [+ selfieProcessingSettings ] PROOF OF RESIDENCE docTypes (default ["UTILITY BILL"] ); poaPresetId (or poaStepSettingsId ) to attach a POA preset by id docSet + poaStepSettingsId QUESTIONNAIRE questionnaireDefId (or questionnaireId alias) — required bare docSet APPLICANT DATA fields — array of strings or {na