Integration guide: Android SDK
@bazik/kyc-sdk shows the whole flow in your React Native app: consent, photo of the CIN or passport, selfie with challenges guided in Haitian Creole, result. The screens are in French. The Bazik server reads the document, checks the registry and decides.
Requirements
- Bare React Native (no Expo), new architecture.
- React 19 or later.
- Android
minSdkVersion24.
Install
npm install @bazik/kyc-sdk \
react-native-safe-area-context react-native-svg \
react-native-vision-camera@^5.2.4 react-native-vision-camera-face-detector@^2.1.0 \
react-native-nitro-modules react-native-nitro-image
# Optional, for the voice prompts in Haitian Creole:
npm install react-native-sound@^0.13.0 @mhpdev/react-native-speech@^1.4.4
| Module | Purpose | Required |
|---|---|---|
react-native-safe-area-context, react-native-svg | layout, icons | yes |
react-native-vision-camera, react-native-vision-camera-face-detector, react-native-nitro-modules, react-native-nitro-image | camera and face detection (ML Kit) | yes, for @bazik/kyc-sdk/vision |
react-native-sound, @mhpdev/react-native-speech | voice prompts | no, only for @bazik/kyc-sdk/voice |
Camera permission
In AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA" />
The SDK asks for the permission itself before the first photo.
Font
The screens use Plus Jakarta Sans, which ships with the package. Declare it in react-native.config.js, then run npx react-native-asset:
module.exports = {
assets: ['./node_modules/@bazik/kyc-sdk/assets/fonts'],
};
The flow in three steps
1. Your backend opens the case
The API key never goes into the app. Your backend opens the case (see the API guide) and returns access_token to the app. The token is valid for that case only, for 30 minutes.
2. The app runs the flow
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { BazikKyc, createHttpApi, type DeviceIntegrity } from '@bazik/kyc-sdk';
import { visionCamera } from '@bazik/kyc-sdk/vision';
import { kreyolVoice } from '@bazik/kyc-sdk/voice'; // optional
// No implementation yet in 0.1: see "Attestation".
const integrity: DeviceIntegrity = { attest: async () => '', sign: async () => '' };
const api = createHttpApi({
baseUrl: 'https://bazik.id',
getAccessToken: async () => caseToken, // received from your backend
integrity,
});
export function KycScreen() {
return (
<SafeAreaProvider>
<BazikKyc
api={api}
camera={visionCamera}
voice={kreyolVoice}
onComplete={(outcome) => {
// 'verified' | 'manual_review': for display only.
}}
onExit={() => {
// The person closed the flow before the end.
}}
/>
</SafeAreaProvider>
);
}
Create api once per case, not on every render.
3. Your backend reads the decision
The result the app receives is not authoritative. Your backend reads the decision with GET /v1/cases/{case_id} (see the API guide).
Reference
<BazikKyc>
| Prop | Type | Purpose |
|---|---|---|
api | KycApi | the server: createHttpApi(…) |
camera | CameraKit | visionCamera on a phone |
voice | VoiceGuide | optional: kreyolVoice speaks the selfie prompts; without it, the flow is silent |
onComplete | (outcome) => void | the person leaves the result screen |
onExit | () => void | the person closes the flow before the end |
onPrivacyPolicy | () => void | optional: shows "Lire la politique de confidentialité" on the consent screen |
onContactSupport | () => void | optional: shows "Contacter l'assistance" on the review screen |
debug | boolean | shows the detector's measurements during the selfie: never in production |
On Android, the flow takes over the back button: it goes back one step, calls onExit from the welcome screen and onComplete from the result.
createHttpApi(options)
| Option | Purpose |
|---|---|
baseUrl | address of the Bazik ID server, without a trailing / |
getAccessToken() | returns the case token; called before each request |
integrity | device attestation, see below |
timeoutMs | maximum duration of a request: 45 s by default (one side of the document reads in about ten seconds) |
Entry points
| Import | Contents |
|---|---|
@bazik/kyc-sdk | BazikKyc, createHttpApi and the types; no native camera or voice module |
@bazik/kyc-sdk/vision | visionCamera (VisionCamera + ML Kit) |
@bazik/kyc-sdk/voice | kreyolVoice: recordings in Haitian Creole, and the phone's voice for prompts not recorded yet |
createMockApi and simulatedCamera are for demos and simulators: they check nothing, never in production.
Attestation
integrity must prove that the app runs on a real device (Play Integrity) and sign the capture. Version 0.1 ships no implementation: a production server then refuses sessions without a verified attestation, and every case goes to manual review. The person sees the review screen, never a rejection.
Limitations of version 0.1
- Attestation: no implementation of
DeviceIntegrity, see above. - iOS: not tested yet.
- Selfie challenges: the thresholds still need calibrating on more phones.
- Voice: "Souri" and "Vin pi pre" have no recording yet; the phone's French voice reads them.