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` /

By sumsub · 854 installs

npx skills add sumsub/agent-skills --skill sumsub-api-auth

Source repository · Upstream listing

Sumsub — API authentication (App Token) How to sign and send authenticated requests to https://api.sumsub.com , per the [official reference](https://docs.sumsub.com/reference/authentication). ⚠️ 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 401 against 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 : 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 — the exact value you put in X 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 / DELETE with 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 : Reference implementations The official multi language examples live at [sumsub/AppTokenUsageExamples](https://github.com/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 ](scripts/sumsub sign.py) — print the three headers for a given method/path/body. No network calls. [ scripts/sumsub curl.sh ](scripts/sumsub curl.sh) — sign + curl in one shot. Reads SUMSUB APP TOKEN / SUMSUB SECRET KEY from 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 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: 1. Token/secret pair matches (copy paste truncation is common). 2. Timestamp is in seconds , not milliseconds, and your clock is in sync. 3. Path includes the leading / and the full query string. 4. Body bytes signed are byte identical to bytes sent (watch for trailing newlines added by editors / heredocs). 5. 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 Type header is multipart/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) 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: 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](references/signing pitfalls.md) — every gotcha that produces 401 Invalid signature and how to spot it.