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.

Skill file

Preview skill file
---
name: sumsub-api-generic
description: 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.
allowed-tools: Read, Write, Bash, Grep
---

# Sumsub — generic API fallback

A skill of last resort. The Sumsub API has ~130 endpoints. The
[OpenAPI 3.0.1 schema](https://api.sumsub.com/openapi.json)
is the source of truth — read it before guessing.

## When to invoke

The user is asking for *something* against `api.sumsub.com` but none of the
specific skills apply. Examples:

- "Get the latest review status for applicant X"
- "List all questionnaires in this workspace"
- "Generate an SDK access token for user Y at level Z"
- "Mark applicant W as approved"
- "Pull the AML hits attached to this applicant"
- "What endpoint do I call to add a tag?"

If the ask clearly matches one of:

- `sumsub-api-auth` — authentication mechanics, signing debug, 401 triage.
- `sumsub-create-questionnaire` — building a `QuestionnaireDefinition`.
- `create-sumsub-level` — building an `ApplicantLevel` end-to-end.

…use that instead. This skill exists for everything else.

## Auth

Same App-Token-+-secret flow as the rest of the repo. **Sandbox tokens only.**
See [`sumsub-api-auth`](../sumsub-api-auth/SKILL.md) for the deep dive and
signing pitfalls. Helper script `${CLAUDE_SKILL_DIR}/scripts/sumsub_curl.sh` (mirror of the auth
skill's) refuses any token that doesn't start with `sbx:`.

If the user has not supplied `SUMSUB_APP_TOKEN` + `SUMSUB_SECRET_KEY`, stop
and ask. Refuse production credentials on sight.

## Hard rule: no shotgun debugging

**Never guess endpoint paths.** Do not try `/resources/kyt/vasps`, then `/resources/kyt/travelRule/vasps`, then `/resources/vasps`, … The schema has ~1800 paths — guessing is always slower and noisier than searching. If `find_endpoint.py` returns no matches, try a different keyword or check the schema directly. The only valid reason to type a path is because the schema told you it exists.

## Procedure


### 0. The schema is auto-fetched

The helper scripts below pull the OpenAPI schema from
<https://api.sumsub.com/openapi.json> on first use and cache
it for 24 hours at `~/.cache/sumsub/openapi.json` (or `$XDG_CACHE_HOME/sumsub/`).
Stale caches refresh transparently on the next invocation. **No App Token or
secret is required for the schema fetch itself** — only for the endpoints
you'll call later.

Force a refresh with `SUMSUB_SCHEMA_REFRESH=1` or by running
`${CLAUDE_SKILL_DIR}/scripts/refresh_schema.py`.

Override knobs:

- `SUMSUB_OPENAPI=/abs/path.json` — skip cache + network, use a local file.
- `SUMSUB_OPENAPI_URL=https://…` — pull from a different host (e.g. a private
  mirror).

The schema is ~750 KB / ~120 paths — if you want you can read it as whole, but you can use
the helpers grep/parse it for you. Do not try to
fabricate endpoint shapes from memory, or invent paths. 

### 1. Search the schema — always

Before anything else, run:

```bash
${CLAUDE_SKILL_DIR}/scripts/find_endpoint.py <keyword>
```

Examples:

```bash
${CLAUDE_SKILL_DIR}/scripts/find_endpoint.py vasp
${CLAUDE_SKILL_DIR}/scripts/find_endpoint.py applicants tags
${CLAUDE_SKILL_DIR}/scripts/find_endpoint.py accessTokens
```

This is the **only** correct way to find an endpoint. Do not proceed to step 2 until you have a match from the schema.

### 2. Pick the right match

Output: `METHOD path  — summary  (operationId)`. Pick the best match from the list `find_endpoint.py` returned. Show the candidate list to the user before committing if any ambiguity remains.

### 3. Inspect the operation in full

Dump request params, body schema, and response shape:

```bash
${CLAUDE_SKILL_DIR}/scripts/show_endpoint.py GET /resources/applicants/{applicantId}/one
```

Read the schema; do not guess. Note in particular:

- **Path params** — substitute before signing.
- **Query params** — must be in the request URI you sign.
- **Required fields** in the request body.
- **Auth requirements** — virtually all endpoints use `app-token` auth;
  flag if you see something different.

### 4. Build the payload

For writes, draft the JSON body and **show it to the user before sending**.
Spell out what each field means and any assumed defaults. Ask for confirmation
on anything irreversible (status changes, deletions, blacklisting).

### 5. Sign and send

```bash
${CLAUDE_SKILL_DIR}/scripts/sumsub_curl.sh GET  /resources/applicants/{applicantId}/one
${CLAUDE_SKILL_DIR}/scripts/sumsub_curl.sh POST /resources/applicants/{applicantId}/tags tags.json
```

The wrapper signs `ts + METHOD + path?query + body` with HMAC-SHA256 and
sends it to `https://api.sumsub.com`. Final line of output is `HTTP <code>`.

### 6. Validate

For state-changing calls, fetch the entity back and verify the change
actually landed. Sumsub occasionally accepts a field at the API edge and
then silently drops it (tenant entitlement gates). Report any mismatch.

For reads, surface the relevant fields to the user — don't just dump the
whole response. Most Sumsub responses are big.

## Common pitfalls

- **Path-parameter expansion in the signature.** You must sign the *resolved*
  path (`/resources/applicants/abc123/one`), not the template
  (`/resources/applicants/{applicantId}/one`). The helper script signs
  whatever string you pass — so resolve first.
- **Query-string encoding.** `+` vs `%20`, ordering, repeated keys — the
  signing string must match the wire exactly. Build the URL once and reuse.
- **GET/DELETE with an accidental body.** Some HTTP clients add `Content-Length: 0`
  or an empty body; the helper does not, but if you switch to another client,
  watch for it — empty body means *append nothing* to the signing string.
- **Pagination.** Many list endpoints use cursor or offset paging — check
  the schema. Don't claim "no results" from a single page.

## See also

- [`sumsub-api-auth`](../sumsub-api-auth/SKILL.md) — full auth reference and
  `401 Invalid signature` triage.
- [Sumsub API reference](https://docs.sumsub.com/reference) — human-readable
  docs that often lag the schema; cross-check.

Source

Creator's repository · sumsubstance/agent-skills

View on GitHub

Security

Security checks in progress
Results will appear here once audits complete
Checked by 3 independent security firms
Does it try to trick the AI?Not yet checkedPending · Gen Agent Trust Hub
Does it sneak in hidden code?Not yet checkedPending · Socket
Does it have known bugs?Not yet checkedPending · Snyk