SDKs
Server SDK for Risk Intelligence
The @myazahq/trust-sdk server package is in development and is not yet
available on the public npm registry. For an integration you can run now, use
the Risk Intelligence HTTP quickstart with a
secret key on your backend. It covers customer registration and a transaction
decision. For an explicit check, use the On-Demand Wallet Screening API.
The unreleased server SDK source includes toden.riskIntelligence.walletScreenings.create(),
retrieve() and list(), plus saved PDF downloads. Its legacy transaction-reference
methods screen a counterparty address at the Wallet Screening rate, not the
transaction hash. The SDK will forward requests to Toden; risk scoring and
rules run on the server.
Client SDKs for identity verification
Toden provides drop-in client SDKs that render the full verification UI (ID selection, document scan, and active liveness) and call the verification API for you. They are thin UI layers: they capture the user’s data and media, upload it, and create the verification. The SDK uses a publishable (pk_) key, safe to ship in client code. Results arrive asynchronously on your backend via webhooks, or fetch the full result with a secret (sk_) key from your backend (the publishable key can only poll minimal status).
All three SDKs share the same core flow and call the same endpoints. The SDK detects the environment automatically from the API key prefix and resolves the base URL itself: pk_test_* → sandbox, pk_live_* → production. There is no environment option. Some newer capabilities are web SDK only for now; see Feature availability.
Configure with a workflow first
There are two ways to tell an SDK what to run, and they are not equal:
-
Mount a workflow (the recommended path). Build the flow in the dashboard as a workflow, covering countries and ID types, capture steps, add-ons (contact OTP, proof of address, NFC, questionnaire), branding, copy, and server-side decisioning, then mount it by id:
The SDK resolves the whole configuration from the server on mount. Changing the flow is a re-publish, not a redeploy, and on mobile not an app-store release. Every published workflow can also be shared as a hosted link with zero integration at all.
-
Configure via props (secondary). Spell the flow out in code (
country,idTypes, step toggles,appearance, copy). Fine for a quick experiment or a single fixed flow, but every change means shipping code, and the add-on steps are far easier composed in the builder.
When both are present, the workflow’s configuration wins over any overlapping props. Runtime data (userId, userData, metadata, and your callbacks) always stays in code: a workflow is a shared template and cannot carry per-user values. Everything below that describes a prop also exists as a builder setting on the workflow; treat the props as the code-side equivalents.
Platform guides
Each SDK has its own integration guide. Pick your platform:
- Web SDK (React):
<MyazaKYC />button + modal flow for React (≥ 18). - React Native SDK: on-device native liveness; needs a custom dev build (not Expo Go).
- Flutter SDK:
MyazaKYC.show()modal sheet for Flutter / Dart.
The rest of this page covers what’s shared across all three: supported countries, branding, consent/success copy, handling results, errors, and resilience.
The React Native SDK ships native code (on-device liveness via Apple Vision + Google ML Kit), so it needs a custom dev/native build. It does not run in Expo Go. See the React Native SDK guide.
Feature availability
All three SDKs are at full feature parity: the core flow (document capture, selfie, active liveness, consent/success copy, branding, callbacks) and every capability on top of it:
The NFC chip read is an on-device capability: browsers can’t talk to a passport chip, so the web SDK renders the chip screen only for the dashboard builder preview, while the native SDKs read chips for real. The read is best-effort by design: a phone without NFC, or a chip that won’t read, continues the flow (see ID types). Hosted workflow links remain the zero-integration option on any platform.
Supported countries & ID types
Mounting a workflow? Pick the countries and ID types in the builder, with nothing to pass in code. For prop-configured mounts, pass a subset via idTypes to limit what the user can pick, or omit it to offer everything enabled for your organisation in that country. Only types valid for the selected country are accepted.
All three SDKs use the same kebab-case idTypes keys (Flutter takes them as plain strings; there is no enum):
See ID types for the document requirements (capture vs. number-only, scan sides) of each.
The five countries above are the government-database-backed markets. All three SDKs additionally verify any ISO country via document capture (Global Documents): pass any two-letter country code, and the ID types your organisation is granted for it are offered automatically (grants are enforced server-side).
Branding & theming
In a workflow, set all of this in the builder’s Appearance panel. Every embed and hosted link inherits it, and a re-publish updates it everywhere with no redeploy. The appearance object below is the code-side equivalent for prop-configured mounts (a workflow’s values win on overlap).
All three SDKs accept an appearance object to match the flow to your brand. The same fields exist on each platform: React and React Native take CSS-style colour strings (e.g. "#5645F5"); Flutter takes Color values. On the web, the colours are injected as CSS variables scoped to the SDK (they never leak into your page); setting one colour cascades to all of its shades. React Native uses the identical field names and string values.
Flutter also accepts logoAsset (a bundled Image.asset path) as a fallback when logo is not set.
Logo
The logo renders as a small circular avatar in the header (top-left), persistent on every step, next to companyName.
- An image URL (
"https://…/logo.png") is used directly. 'default'uses the logo configured for your organisation under Settings → Organization in the dashboard. The SDK fetches it fromGET /config(branding.logo) on mount. If your org has no logo set, or the image fails to load, it falls back to the built-in shield icon.- Omitted shows no header logo.
Consent screen copy
The first screen of the flow (the welcome/consent step) shows a heading and a short description. Both default to Toden’s built-in copy. In a workflow, override them in the builder’s Consent panel; the consent object below is the code-side equivalent, with identical fields on every SDK.
Both fields support {firstName} and {lastName} tokens, which are replaced with the values you pass in userData (an empty string when absent), so a custom title can still greet the user by name.
Omit consent (or either field) to keep the defaults.
Success screen copy
The final screen, shown after the user submits, displays a confirmation heading and a short description. Both default to Toden’s built-in copy. In a workflow, override them in the builder’s Success panel; the success object below is the code-side equivalent, with identical fields on every SDK.
Both fields support the same {firstName} / {lastName} tokens as consent, which are replaced with the values you pass in userData (an empty string when absent).
Omit success (or either field) to keep the defaults. This screen is purely cosmetic; the verification outcome still arrives asynchronously (see Handling results).
Handling results
The SDK finishing only means the verification was created, never that it passed. Treat the outcome as eventual:
- The SDK uploads media and creates the verification, then invokes
onSubmitwith aKYCSubmission. - Your backend receives the terminal
verification.*webhook (or fetches the full result with a secret key; the SDK’s publishable key can only poll minimal status). - You update the user’s state from that authoritative result.
The onSubmit payload (KYCSubmission) carries:
Always pass a stable requestId in metadata so retries are idempotent.
Errors
onError fires for technical failures only, never for a failed verification, which arrives asynchronously via webhook. The error carries a stable code (the same set across all three SDKs):
All SDKs deliver the same typed error: in React and React Native onError receives a KYCError, a real Error (so existing (error: Error) handlers keep working) that also carries code and optional details; in Flutter it receives a KYCError with code, message, and optional details. See Errors for the API-level error model.
Voice guidance is text-to-speech output; it never records audio, so there is no microphone permission and no microphone error code.
Resilience & capture quality
All three SDKs handle real-world conditions so the flow doesn’t crash, hang, or capture unusable media:
-
Network retries. Media uploads and the verify submission retry transient failures (network / timeout /
5xx) with exponential backoff + jitter; terminal4xxsurface immediately. The UI shows “Reconnecting… / retrying (n/3)…”, andonErrorfires only after retries are exhausted. -
Camera permission. A denied camera shows a clear “camera access needed” screen (with how to re-enable it: an Open Settings action on Flutter & React Native) and reports
camera_permission_denied. Document capture keeps a gallery-upload fallback on that screen as an escape hatch. -
Multiple faces. During liveness, if more than one face is in frame the challenge pauses (“Make sure only your face is visible”) and resumes automatically when only one remains, guarding capture quality and a class of spoofing.
-
Lighting. Too-dark and too-bright (glare) conditions are detected live and surfaced as guidance (“Move to a brighter area” / “Too bright, reduce glare”); auto-capture is discouraged until lighting is acceptable.
-
Liveness is on-device & native on mobile: Apple Vision (iOS) + Google ML Kit (Android) on both React Native and Flutter; the web SDK uses MediaPipe in the browser. The selfie is auto-captured once the challenges pass (you can’t trigger it on a static image), and a short liveness video is recorded for server-side review.
For the full prop reference and styling options, see each package’s README.