
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.2K
- Last 24h
- +16
- Trending rank
- #6890
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/sumsub/agent-skills --skill sumsub-api-auth- 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-api-auth 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 — API authentication (App Token)
How to sign and send authenticated requests to https://api.sumsub.com, per
the official reference.
⚠️ Sandbox tokens only
Never share, paste, or use a production Sumsub App Token / secret with Claude. If the user offers a prod token, refuse and ask for the sandbox pair instead, generated at https://cockpit.sumsub.com/checkus/home?sbx=true (Connect Sumsub to your AI agent -> Build & configure -> Generate token).
- Sandbox tokens are created from the dashboard while it is in Sandbox mode. They are scoped to sandbox data only — leaking one cannot expose real applicant PII or move real money.
- A production token grants full programmatic access to live applicants, including their identity documents. Treat it like a banking credential.
- Sumsub locks tokens to the environment they were minted in: a sandbox token
returns
401against production data and vice versa, so insisting on sandbox is also the practical default.
If the user pastes what looks like a production secret into the conversation, flag it immediately, advise rotating it in the dashboard, and continue only with a freshly-generated sandbox pair.
What you need from the user
| Var | Where it comes from |
|---|---|
SUMSUB_APP_TOKEN | https://cockpit.sumsub.com/checkus/home?sbx=true — Connect Sumsub to your AI agent -> Build & configure -> Generate token. Shown once. |
SUMSUB_SECRET_KEY | Same dialog as the token. Also shown once. |
SUMSUB_BASE | https://api.sumsub.com (same host for sandbox and prod — the token decides the mode). |
⚠️ The token + secret are revealed exactly once at creation. Copy both
into .env (or your secret store) before closing the dialog — there's no
recovery flow, only re-generation.
Advise the user to store them in .claude/settings.local.json (gitignored, auto-loaded by Claude Code) or in .env:
// .claude/settings.local.json
{
"env": {
"SUMSUB_APP_TOKEN": "sbx:...",
"SUMSUB_SECRET_KEY": "..."
}
}
# .env
SUMSUB_APP_TOKEN=sbx:...
SUMSUB_SECRET_KEY=...
If either credential is missing, stop and ask. Do not invent placeholders.
The three required headers
Every request to api.sumsub.com must carry:
| Header | Value |
|---|---|
X-App-Token | The App Token, verbatim. |
X-App-Access-Ts | Current Unix time in seconds (UTC). Must be within ±60s of Sumsub's clock. |
X-App-Access-Sig | Lowercase hex HMAC-SHA256 of the signing string, keyed by the secret. |
HTTPS is mandatory — plain http:// is rejected.
Signing string
Concatenate, with no separators:
<ts><HTTP_METHOD_UPPER><request_uri_with_query><body_bytes_or_empty>
ts— the exact value you put inX-App-Access-Ts(string of digits).HTTP_METHOD_UPPER—GET,POST,PATCH,PUT,DELETE— uppercase.request_uri_with_query— path starting with/, including the query string if any. Examples:/resources/applicants/-/one,/resources/accessTokens?userId=abc&levelName=basic-kyc-level.- Body — the raw bytes you send. For
GET/DELETEwith no body, append nothing (empty string). For JSON, sign the exact bytes you'll transmit — re-serializing later will break the signature.
Then hex(hmac_sha256(secret, signing_string)), lowercase.
Worked example (from the docs)
Signing string for POST /resources/accessTokens?userId=...&levelName=basic-kyc-level&ttlInSecs=600 with no body, at ts 1607551635:
1607551635POST/resources/accessTokens?userId=cfd20712-24a2-4c7d-9ab0-146f3c142335&levelName=basic-kyc-level&ttlInSecs=600
Reference implementations
The official multi-language examples live at sumsub/AppTokenUsageExamples (Java, JS, Python, Ruby, Go, PHP, C#). Use those for production integrations.
For one-off calls or debugging, this skill ships two small helpers:
scripts/sumsub_sign.py— print the three headers for a given method/path/body. No network calls.scripts/sumsub_curl.sh— sign +curlin one shot. ReadsSUMSUB_APP_TOKEN/SUMSUB_SECRET_KEYfrom the environment.
Run scripts using ${CLAUDE_SKILL_DIR}/scripts/<script> so they resolve correctly regardless of the working directory.
Quick check — fetch the current applicant count
export SUMSUB_APP_TOKEN='sbx:...' # sandbox token, refuse prod
export SUMSUB_SECRET_KEY='...'
${CLAUDE_SKILL_DIR}/scripts/sumsub_curl.sh GET '/resources/applicants/-/count'
A 200 with a JSON body confirms the signature is correct. A 401 with
{"description":"Invalid signature"} means the signing string or secret is
off — re-check, in order:
- Token/secret pair matches (copy-paste truncation is common).
- Timestamp is in seconds, not milliseconds, and your clock is in sync.
- Path includes the leading
/and the full query string. - Body bytes signed are byte-identical to bytes sent (watch for trailing newlines added by editors / heredocs).
- Method is uppercase.
Signing multipart/form-data requests
Some endpoints take a file upload — most commonly idDoc photo upload at
POST /resources/applicants/{applicantId}/info/idDoc. For these:
- Sign the full raw multipart body, byte-for-byte, including boundary
markers, part headers, JSON metadata, and file bytes. There is no
multipart-specific exemption — the rule is the same as for JSON:
signing string =
ts + METHOD + path + body_bytes. - The
Content-Typeheader ismultipart/form-data; boundary=<boundary>, where<boundary>matches the one woven into the body bytes you signed.
The pitfall: most HTTP libraries (curl -F, requests with files=,
fetch with FormData) generate the boundary internally and never expose
the exact bytes — so you cannot sign what they will send. Workaround:
build the body in memory yourself, hash it, then transmit those exact
bytes with --data-binary / a raw send.
Python recipe (canonical)
import hashlib, hmac, json, os, time, uuid
from pathlib import Path
from urllib.request import Request, urlopen
APP_TOKEN = os.environ["SUMSUB_APP_TOKEN"]
SECRET = os.environ["SUMSUB_SECRET_KEY"]
APPLICANT = "6a170f852f9d88fe6eda2636" # from create-applicant response
FILE = Path("/path/to/passport.png")
METADATA = {"idDocType": "PASSPORT", "country": "RUS"}
boundary = "----sumsub-" + uuid.uuid4().hex
crlf = b"\r\n"
parts = [
b"--" + boundary.encode(),
b'Content-Disposition: form-data; name="metadata"',
b"Content-Type: application/json",
b"",
json.dumps(METADATA).encode(),
b"--" + boundary.encode(),
f'Content-Disposition: form-data; name="content"; filename="{FILE.name}"'.encode(),
b"Content-Type: image/png",
b"",
FILE.read_bytes(),
b"--" + boundary.encode() + b"--",
b"",
]
body = crlf.join(parts)
method, url_path = "POST", f"/resources/applicants/{APPLICANT}/info/idDoc"
ts = str(int(time.time()))
sig = hmac.new(
SECRET.encode(),
ts.encode() + method.encode() + url_path.encode() + body,
hashlib.sha256,
).hexdigest()
req = Request(
"https://api.sumsub.com" + url_path,
data=body, method="POST",
headers={
"X-App-Token": APP_TOKEN,
"X-App-Access-Ts": ts,
"X-App-Access-Sig": sig,
"Content-Type": f"multipart/form-data; boundary={boundary}",
"Content-Length": str(len(body)),
"X-Agent-Source": "sumsub-skills",
"X-Agent-Source-Ver": "1.5.0",
},
)
print(urlopen(req).read().decode())
Curl-based fallbacks (e.g. curl --data-binary @raw-multipart.bin after
pre-building the body to disk) work too, but the boundary in the body and
in Content-Type must match exactly — easier to keep them in sync in code.
Generating an SDK access token (common follow-up)
The most-asked endpoint after auth works:
POST /resources/accessTokens?userId=<your_user_id>&levelName=<level>&ttlInSecs=600
Body is empty. Response contains token — pass that to the Web / Mobile SDK.
Full reference: https://docs.sumsub.com/reference/generate-access-token.
See also
- references/signing-pitfalls.md — every
gotcha that produces
401 Invalid signatureand how to spot it.
FAQ
What does the sumsub-api-auth skill do?
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.
How do I install sumsub-api-auth?
Run npx skills add https://github.com/sumsub/agent-skills --skill sumsub-api-auth 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-api-auth/ (personal) or .claude/skills/sumsub-api-auth/ (project).
Which AI agents can use sumsub-api-auth?
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-api-auth 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-api-auth?
It is published by sumsub in sumsub/agent-skills. It has 1,204 recorded installs.
More from sumsub/agent-skills
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-integrate-websdk
sumsub/agent-skills
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).
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.