Skip to main content

Tencent Palm Mobile H5 SDK Reference

Audience: front-end / H5 engineers on the integrating side

This document helps you integrate palm capture in the browser (including mobile WebViews). The user token required by the SDK is issued by your backend via CreateSdkUserToken.

Changelog​

VersionRelease DateChanges
v1.4.02026-10-09Recognition (1:N) adapted to backend v1.4: customHeaders.AppId is required in recognition mode; the search_rgb_palm body carries that AppId and the palm image / video are encrypted with it. token may be an empty string (the gateway allows anonymous search_rgb_palm keyed by AppId; no Authorization header is sent when empty); when provided it must belong to the same app as AppId. userId is optional. Registration / verification still require token
v1.3.02026-09-14Logging aligned with the new palmreport contract: final-state trace (success / cancel / failure) is always reported; enableLogReport only controls encrypted on-site image / video diagnostic replicas. Diagnostic media presigning migrated to create_tmp_obj (with AppId in the request body). Desktop browsers with landscape windows no longer cancel acquisition as orientation change
v1.2.02026-08-18RecognitionData.sessionId; CheckAppQuality on recognition / verification; removed Params.baseUrl (API host fixed by SDK Host deployment)
v1.1.02026-08-16PalmX Web SDK surface: Params / Result / enableManager / enableImageOnly; VerificationData.sessionId; manager direction constraints; get_palm 10021 → empty palms
v1.0.02026-07-20Initial PalmX line

Upgrading from v1.3? See "Upgrading from v1.3 to v1.4" at the end.

Introduction​

The Tencent Palm Mobile Manager Web SDK is the Web platform implementation of PalmX palm biometrics. It supports registration, verification (1:1), and recognition (1:N). Capture and inference run in the browser via iframe + WebAssembly. The SDK is deployed on a dedicated SDK Host domain; host pages integrate with a single <script src> tag or the npm package.

Core Modules​

The SDK consists of two core modules: Management Module and Acquisition Module.

Management Module​

Palm management UI (enableManager = true, default):

  • Palm state — Query left/right registration via get_palm; support deleting registered palms
  • Business flow — Registration, Recognition (1:N), Verification (1:1)
  • UI interaction — Guidance, results, errors, and retry
  • Result handling — Shows acquisition results inside the SDK; most business errors stay in-SDK for retry
  • Result callback — Calls back to the host mainly on critical errors (invalid params, token invalid, gateway auth failure, user not found) or user exit

The PalmX management module does not create users inside the SDK (no userName / phoneNo params). Users must already exist on PalmXAI Platform; tokens are issued via CreateSdkUserToken. The app id is not a standalone param; it is always passed via customHeaders.AppId (required for recognition (1:N)).

Acquisition Module​

Palm print acquisition (entered directly when enableManager = false; also used internally by the management module):

  • Camera — navigator.mediaDevices.getUserMedia live preview
  • AI — Detection, quality, liveness (WebAssembly)
  • Guidance — Open-palm / fist prompts
  • Upload — AES-128-GCM encrypted images; liveness video is recorded and uploaded by default. Client capture failure → ErrLivenessVideoCaptureFailed (10105); server rejection → ErrLivenessVideoFailed (10102); upload / network failure → ErrNetwork (10500)
  • Image-only — enableImageOnly = true skips video upload and cloud register / search / compare, returning encrypted ImageData
  • Log reporting — The final-state trace (success / cancel / failure) of every session is always reported to the palmreport log channel for statistics and troubleshooting; enableLogReport = true additionally uploads encrypted on-site image / video diagnostic replicas (see Params.enableLogReport)
  • Orientation — Rotating a touch mobile device to landscape invalidates the current acquisition (treated as 10002 user cancel); desktop browser window orientation does not affect acquisition

Features​

  • Multiple modes — Registration, Verification (1:1), Recognition (1:N)
  • Optimized AI — Detection & alignment, liveness, quality, and action recognition via WebAssembly
  • Modular UI — Pre-built UI for manager and acquisition
  • Origin isolation — Capture UI and wasm run in an iframe on an independent origin; postMessage with strict origin checks
  • Secure by design — Palm data encrypted before upload; tokens must be server-issued — never hard-code platform secrets in the browser

Glossary / Core Concepts​

  • [Palm] Single-Factor Feature Set — Palm print only. Browser cameras cannot capture palm vein; this SDK collects palm print only.
  • [Palm + PalmVein] Dual-Factor Feature Set — Palm print + palm vein for professional-device enrollment. This Web SDK does not collect palm vein.

SDK Host​

The SDK is deployed by the service provider on a dedicated domain (SDK Host). Host pages include the loader via <script src>. The capture iframe, wasm, and camera UI are served by the SDK Host — the host page does not need to know their internals.

  • https://open.intl.palm.tencent.com/palm/x/jssdk/loader/palm-mobile-manager.js — entry for <script src>
  • https://open.intl.palm.tencent.com/palm/x/jssdk/embed/ — capture iframe page (loader infers this from its own <script src>)

Important: The SDK Host MUST be on a different origin from your host page so that MessageEvent.origin checks meaningfully secure cross-window communication. Loader and embed live on the same SDK Host.

Workflow​

1. Obtain User Token​

Your backend requests a short-lived token bound to the end-user UserId from Tencent PalmXAI Platform (CreateSdkUserToken), then delivers it to the client.

Recognition (1:N) does not target a specific user and needs no token: pass empty token and userId, put AppId in customHeaders (required), and the SDK recognizes anonymously within that app. Registration and verification (1:1) still require a token.

Production tokens must come from your own backend — never put the platform api_key in front-end code.

2. Start the SDK​

SDK ModuleDescription
ManagementenableManager = true (default). Shows manager UI, then acquisition; most results handled in-SDK
AcquisitionenableManager = false. Direct camera capture; host dispatches the full Result

For registration / verification, call PalmMobileManager.start with token and userId; for recognition (1:N), only AppId in customHeaders is needed (see "Recognition (1:N) Example").

3. Automated Flow​

The Management Module queries palm state, shows guidance / result pages, runs acquisition by mode, and prompts retry in-SDK.

The Acquisition Module returns the full Result (including success data) via Promise / callback when done.

4. Receive Callback​

Only one session at a time; concurrent calls are rejected immediately with ErrSdkRuntime (10007).

  • Management: host mainly receives user exit (10002) and critical passthrough codes (see Callback Result Codes). Success business payloads usually stay in the SDK result UI.
  • Acquisition: host must handle the complete result-code set.

Runtime Requirements​

ItemRequirement
ProtocolHTTPS (localhost excepted). getUserMedia requires a secure context.
Browser● Desktop: Chrome / Edge ≥ 88, Firefox ≥ 90, Safari ≥ 14
● Mobile: iOS Safari ≥ 14, Android Chrome ≥ 88
● Required: MediaDevices.getUserMedia, postMessage, ES2020, WebAssembly
iframe permissionsSDK sets allow="camera; microphone" on the iframe. Nested host iframes must allow camera at each level.
Node (npm only)Node.js ≥ 18

Integration Steps​

Prerequisites​

  1. SDK Host URL — https://open.intl.palm.tencent.com, assets under /palm/x/jssdk/.
  2. HTTPS — both SDK Host and host page (except localhost).
  3. User & Token (registration / verification) — end user provisioned on the platform; backend issues token via CreateSdkUserToken.
  4. App ID (recognition (1:N)) — your app id (AppId) on PalmXAI Platform, passed via customHeaders.AppId.
  5. Privacy consent — the SDK does not show a privacy agreement or record user consent. Obtain explicit user consent on your page before calling PalmMobileManager.start.

<script> Integration​

  1. Include the Loader

    <!-- Loader on the SDK Host -->
    <script src="https://open.intl.palm.tencent.com/palm/x/jssdk/loader/palm-mobile-manager.js"></script>

    The UMD build exposes under window.PalmMobileManager: the PalmMobileManager class, plus Mode / PalmDirection / ResultCode.

  2. Minimal example

    <script>
    const { PalmMobileManager, Mode } = window.PalmMobileManager;

    const params = {
    token: USER_TOKEN,
    userId: USER_ID,
    // mode: Mode.Registration, // default registration
    // mode: 'verification', // verification: userId is 1:1 compare target
    // mode: 'recognition', // recognition (1:N): customHeaders.AppId required
    // palmDirection: 'palm_direction_unspecified',
    // enableManager: true, // false = direct acquisition
    // enableImageOnly: false,
    // enableLogReport: false, // true = upload encrypted diagnostic replicas
    // customHeaders: { AppId: APP_ID }, // app id: required for recognition, diagnostics otherwise
    };

    PalmMobileManager.start(params, (r) => {
    console.log('[PalmMobileManager]', r);
    }).then((result) => {
    console.log('final:', result);
    });
    </script>

    Zero config: the loader uses its own <script src> origin as the embed site. As long as loader and embed share the SDK Host, the host page needs no extra setup.

npm​

pnpm add palm-mobile-manager
import { PalmMobileManager, Mode, PalmDirection } from 'palm-mobile-manager';

const result = await PalmMobileManager.start({
token: USER_TOKEN,
userId: USER_ID,
// mode: Mode.Verification,
// palmDirection: PalmDirection.Left,
// enableManager: false,
});

console.log(result);

Recognition (1:N) Example​

Recognition does not target a specific user: pass empty token and userId; AppId must be provided in customHeaders, otherwise the call returns ErrInvalidParams (10001) immediately. Use enableManager = false so the host page receives the full RecognitionData.

import { PalmMobileManager, Mode, ResultCode } from 'palm-mobile-manager';

const result = await PalmMobileManager.start({
token: '', // may be empty: gateway allows anonymous access by AppId; no Authorization header
userId: '', // 1:N is not user-specific (the TS type requires the field; pass an empty string)
mode: Mode.Recognition,
customHeaders: { AppId: APP_ID }, // required: written into the search_rgb_palm body and used as the image / video encryption factor
enableManager: false,
});

if (result.code === ResultCode.Success) {
// Matched user's userId / score / sessionId.
// Hand sessionId to your server to verify the result; do not trust userId alone.
console.log(result.data);
}

If a token is also passed, it must belong to the same app as AppId; otherwise the backend returns 2060205 (mapped to 10012).

Local Integration Testing​

Point the host page's <script src> at the SDK Host. The host page may run on http://localhost; the camera is opened by the SDK Host HTTPS iframe:

<script src="https://open.intl.palm.tencent.com/palm/x/jssdk/loader/palm-mobile-manager.js"></script>

Test tokens can be issued by your test backend via CreateSdkUserToken, or see "Quick Start for Testing Environments" below.

API Reference​

PalmMobileManager.start(params, callback?)​

Starts one management / acquisition session and returns Promise<Result>. callback and Promise receive the same Result. Only one session at a time; concurrent calls return ErrSdkRuntime (10007).

PositionalTypeRequiredDescription
paramsParams✅See below
callback(result: Result) => voidOptional; Promise still resolves with the same result

PalmMobileManager.back()​

Sends a back command to the active embed (same semantics as the in-UI back control). No-op if no session.

PalmMobileManager.version​

Static string, the SDK version, currently 1.4.0 (same as the product-line version in this document).

Params​

Startup validates non-empty fields (token / userId for registration / verification; customHeaders.AppId for recognition); failure returns code=10001. Prefer the userId format below; otherwise the backend may map to 10018.

Required Fields by Mode​

ParameterRegistrationVerification (1:1)Recognition (1:N)
token✅✅may be empty
userId✅ user to enroll✅ compare targetmay be empty
customHeaders.AppIdoptionaloptional✅

Identity Parameters​

ParameterTypeDescription
tokenstringUser identity token (issued by backend CreateSdkUserToken). May be an empty string in recognition mode (anonymous 1:N keyed by customHeaders.AppId).
userIdstringUnique user id.
• registration: user to enroll
• verification: 1:1 compare target (CompareUserId)
• recognition: optional (1:N is not user-specific)
Recommended format: 1–64 chars, [A-Za-z0-9_-] only, no whitespace.

Optional Parameters​

ParameterTypeDefaultDescription
modeModeRegistration ('registration')• Mode.Registration ('registration')
• Mode.Verification ('verification')
• Mode.Recognition ('recognition')
palmDirectionPalmDirectionUnspecified• PalmDirection.Unspecified ('palm_direction_unspecified')
• PalmDirection.Left ('left')
• PalmDirection.Right ('right')
enableManagerbooleantruetrue = management module; false = acquisition only.
enableImageOnlybooleanfalseWhen true, return encrypted ImageData only — no video upload, no register / search / compare.
enableLogReportbooleanfalseWhen true, additionally upload AES-128-GCM encrypted on-site image / video diagnostic replicas (presigned via create_tmp_obj, uploaded directly to object storage) for troubleshooting. The final-state trace log is not gated by this switch and is always reported (statistics baseline).
customHeadersRecord<string, string>{}Extra HTTP headers. AppId (case-insensitive key) is the app id:
• required for recognition; when token is provided it must match the app that issued it — the SDK writes it into the search_rgb_palm body and uses it as the image / video encryption factor; otherwise the backend returns 2060205 (mapped to 10012)
• other modes use it for diagnostic replica upload (create_tmp_obj)
Note: customHeaders are attached as-is to every SDK request. Do not pass Authorization: it overrides the Bearer <token> the SDK builds from token. The Web SDK has no baseUrl; requests always go to the SDK Host gateway, authenticated by token.

Difference vs. native SDKs (H5 characteristic): The Web SDK does not expose baseUrl. The API endpoint is decided by the embed / SDK Host at deployment time: same-origin relative /palm/* via Ingress / reverse proxy by default; when the page host is app.*, the SDK rewrites to matching open.*. The host page cannot override it. To connect to a different backend environment, use the corresponding SDK Host.

vs older PalmX docs: no userName / phoneNo / targetUserId; appId is passed via customHeaders.AppId, same as native. Verification target is userId.

Result​

interface Result {
code: number;
message: string;
data?: RegistrationData | RecognitionData | VerificationData | ImageData;
traceId?: string;
}
PropertyTypeDescription
codenumberResult code (see below).
messagestringDebug message.
dataResultData | undefinedSuccess payload; shape depends on mode / enableImageOnly.
traceIdstring | undefinedRequest trace id (may be present on failure).

ResultData​

interface RegistrationData {
userId: string;
/** Temporary registration-result lookup credential (RegisterRgbPalmRsp.SessionId, ~2h TTL) */
sessionId?: string;
/** Palm direction enrolled in this session */
palmDirection?: PalmDirection;
}

interface RecognitionData {
userId: string;
score: number;
palmDirection?: PalmDirection;
/** Temporary search-result lookup credential (SearchRgbPalmRsp.SessionId, ~2h TTL) */
sessionId?: string;
}

interface VerificationData {
isMatch: boolean;
score: number;
palmDirection?: PalmDirection;
/** Temporary compare-result lookup credential (CompareRgbPalmRsp.SessionId, ~2h TTL) */
sessionId?: string;
}

interface ImageData {
/** Serialized acquisition JSON (image fields AES-128-GCM encrypted) */
payload: string;
}

Hand sessionId to your server and verify the result via GetSessionResult.

Callback Result Codes (Management Module)​

With enableManager = true, the host mainly receives:

CodeScenarioSuggested action
10002User exit (e.g. back from manager root)Treat as cancel
10001Invalid parametersValidate required fields / mode (e.g. customHeaders.AppId missing in recognition)
10012Token invalid or expired; in recognition, token and AppId belong to different appsRe-issue token / check AppId
10021User does not exist (passthrough)Check user / re-login
10401Gateway auth failureCheck gateway JWT / contact technical support

Token / gateway auth failures during the manager stage (before acquisition starts) exit immediately with a callback; during acquisition, the management module first shows the failure result page and calls back after the user exits (same result code). Successful business payloads stay in the manager result UI by default; use enableManager = false if the host needs the full success data.

Complete Result Code Reference​

Acquisition module (enableManager = false) does not swallow codes — the host must dispatch the full set:

Expand all result codes
Common​
CodeEnumNotes
0SuccessSuccess
10000ErrUnknownUnknown error
10001ErrInvalidParamsInvalid parameters, e.g. customHeaders.AppId missing in recognition (manager callbacks)
10002ErrUserCancelledUser cancelled (manager callbacks)
10003ErrCameraPermissionDeniedCamera permission denied
10004ErrCameraInitFailedCamera init failed
10005ErrCameraPreviewUnsupportedUnsupported preview size
10006ErrSdkInitFailedSDK / wasm init failed
10007ErrSdkRuntimeRuntime error (incl. concurrent session)
10008ErrAcquisitionTimeoutAcquisition timeout (30s)
10012ErrUserTokenInvalidToken invalid/expired (callback / may exit immediately)
10016ErrLicenseValidationFailedLicense validation failed
10018ErrUserIdInvalidInvalid user id format
10020ErrAppDisabledApp disabled
10021ErrUserNotExistUser not found (manager callbacks; manager get_palm treats as empty palms)
Registration​
CodeEnumNotes
10100ErrLivenessFailedLiveness failed
10101ErrQualityFailedQuality failed
10102ErrLivenessVideoFailedLiveness video rejected by server
10103ErrAlreadyBindPalm already registered
10104ErrHighSimilarityHigh similarity with existing user
10105ErrLivenessVideoCaptureFailedClient could not record liveness video (browser / insecure context / recorder lost)
Recognition​
CodeEnumNotes
10200ErrUserNotRecognizedUser not recognized
Verification​
CodeEnumNotes
10200ErrUserNotRecognizedNo palm feature of the target user found in the compare library (shared with recognition)
10300ErrTargetUserNotFoundTarget user not found
10301ErrTargetUserUnregisteredTarget has no registered palm
10302ErrTargetUserPalmDirectionUnregisteredTarget missing current palm direction
Network​
CodeEnumNotes
10401ErrUnauthorizedGateway unauthorized (callback / may exit immediately)
10500ErrNetworkNetwork error (incl. unmapped backend codes)

Architecture​

Host Page
└─ PalmMobileManager.start(params, callback?)
└─ <iframe src="https://open.intl.palm.tencent.com/palm/x/jssdk/embed/" allow="camera; microphone">
└─ Manager View → Acquisition View
└─ getUserMedia + wasm + Tencent PalmXAI Platform
←── postMessage { ns:'palm-mobile-manager', v:1, msg:{ type:'result', payload } } ──
  • Loader ↔ Embed enforce bidirectional origin checks.
  • Cloud APIs (when not enableImageOnly): register_rgb_palm / search_rgb_palm / compare_rgb_palm; recognition and verification requests send CheckAppQuality: true.
  • Log channel: the final-state trace (success / cancel / failure) is always reported to /palm/openai/palm/palmreport/logs (OTLP, report_source=3, device_sn is a browser-persistent random id). With enableLogReport = true, encrypted on-site image / video diagnostic replicas are additionally presigned via /palm/openai/palm/palmreport/create_tmp_obj (AppId in the request body) and uploaded directly to object storage. The SDK awaits the log queue before returning the result — destroying the iframe does not truncate the final trace.
Full sequence diagram

Security Warning​

Production Environment Security Requirements​

Never hard-code platform account secrets in production browser code.

All calls that need platform secrets (e.g. CreateSdkUserToken) must run on your server. The browser only receives a short-lived token.

Verifying Recognition (1:N) Results​

The AppId passed for recognition (1:N) is an app identifier, not a secret, and may live in the front end. After anonymous recognition the userId in the browser callback can be tampered with, so hand the sessionId returned on a successful recognition (~2h TTL) to your server to verify the result — do not trust the userId in the browser callback alone.

Session Uniqueness​

Only one Web SDK session at a time. Concurrent PalmMobileManager.start() calls are rejected with ErrSdkRuntime (10007).

Quick Start for Testing Environments​

For local / internal / isolated demo only. In production, tokens must be issued dynamically by your backend.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
<title>Palm H5 Test</title>
</head>
<body>
<button id="startBtn">Start</button>
<pre id="result"></pre>

<script src="https://open.intl.palm.tencent.com/palm/x/jssdk/loader/palm-mobile-manager.js"></script>
<script>
// [TEST ONLY] do not embed production tokens in pages
const USER_TOKEN = 'sut_xxx'; // required for registration / verification; may be empty for recognition
const USER_ID = 'YourUserId'; // required for registration / verification; may be empty for recognition
const APP_ID = 'YourAppId'; // required for recognition (1:N)
const MODE = 'registration'; // 'registration' | 'verification' | 'recognition'

const { PalmMobileManager } = window.PalmMobileManager;
const resultEl = document.getElementById('result');

document.getElementById('startBtn').addEventListener('click', async () => {
try {
const result = await PalmMobileManager.start({
token: USER_TOKEN,
userId: USER_ID,
mode: MODE,
customHeaders: { AppId: APP_ID },
enableManager: false, // easier to observe full Result in tests
});
resultEl.textContent = JSON.stringify(result, null, 2);
} catch (err) {
resultEl.textContent = `Error: ${err?.code ?? ''} ${err?.message ?? err}`;
}
});
</script>
</body>
</html>

Upgrading from v1.3 to v1.4​

v1.4 changes are concentrated in recognition (1:N). Integrations that only use registration and verification (1:1) can upgrade without code changes.

#ChangeImpactCode change needed
1Recognition (1:N) requires customHeaders.AppIdBreaking: returns 10001 immediately if missing✅ Required if you use recognition
2Recognition palm images and video are encrypted with AppIdHandled inside the SDK; backend decrypts by the AppId in the body❌ As long as the correct AppId is passed
3Recognition no longer needs token; userId is optionalOptional: no need to issue tokens for recognitionRecommended
4RegistrationData adds sessionId and palmDirectionNew fields, backward compatible❌ Use as needed
5PalmMobileManager.version changes from 0.0.1 to 1.4.0Only affects version-based logicDepends
6Token failure during acquisition shows the failure result first, then calls backCallback arrives slightly later in the management module❌

Recognition call diff:

const result = await PalmMobileManager.start({
- token: userToken, // v1.3: recognition also required a token
- userId: 'placeholder', // v1.3: must be non-empty
+ token: '', // v1.4: may be empty for recognition
+ userId: '',
mode: Mode.Recognition,
+ customHeaders: { AppId: APP_ID }, // v1.4: required for recognition
enableManager: false,
});

Upgrade checklist:

  • Reference the v1.4.0 loader or npm package
  • Every mode = recognition call passes customHeaders.AppId
  • AppId matches the current environment (test / production)
  • (Optional) Remove logic that issues a token or fills a placeholder userId for recognition
  • Verify recognition results on your server with sessionId
  • Update any logic that checks version === '0.0.1'
  • Regression-test registration, verification, and recognition

FAQ:

SymptomLikely causeFix
Recognition returns 10001 right after startcustomHeaders.AppId missing or emptyPass AppId
Recognition returns 10012AppId does not exist in this environment (e.g. a test ID used in production); or a token was passed but is invalid or belongs to another appCheck AppId and environment; you may omit the token for recognition
Recognition keeps returning 10200 (not recognized)AppId belongs to a different app whose library does not contain the user's palmUse the same AppId as during registration
Registration / verification returns 10001These modes still require non-empty token and userIdPass them as before

Next Steps & Support​

  • Server APIs: token issuance, palm query / deletion, and recognition result verification — see the KYC Open API Integration Guide
  • Native app integration: Android / iOS / Flutter — see Mobile (App) SDK
  • Support: contact your technical support representative