Sekyro AIDocs

React Native SDK

The native drop-in flow for React Native apps on Android and iOS.

Status: release candidate, not yet on npm. The package and its native SDKs (ai.sekyro:* 0.1.0-rc.2 on Maven Central, SekyroKit 0.1.0-rc.2 on sekyro-ios-dist) are published together; until then, Ibtikar shares a packed tarball (npm pack) for pilots.

@sekyro/react-native runs the Sekyro AI native drop-in (consent, document capture, NFC chip, liveness, phone or e-mail OTP, registry) full screen from a React Native app and returns a display-only result. It is a thin TurboModule over the binary Android and iOS SDKs: every capture, network and UI line lives in the native SDKs, so a React Native app gets exactly the same flow as a native one.

  • React Native 0.76 or later, New Architecture only (the default since 0.76). No Expo Go (it cannot load native modules); Expo apps use a development build or expo prebuild with the config plugin below.
  • Android minSdk 24, iOS 15.1.
  • The client token comes from your server (@sekyro/node sessions.create). API keys never ship in an app.
  • Results are for display. Decide on your server from webhooks or sessions.get (see quickstart §4).

1. Install

Release candidate

The React Native SDK is a release candidate. Chip reading (NFC) and email codes in the drop-in flow are staging-only for now: see Availability.

npm install @sekyro/react-native

Android

The native SDK comes from Maven Central (ai.sekyro:sekyro-bom + ai.sekyro:sekyro-ui, version pinned by the npm package), so mavenCentral() must be in your repositories (it is in every React Native template). Set minSdkVersion to 24 or more. Nothing else: the SDK's manifest merges the CAMERA and NFC permissions, the optional camera/NFC features and its SekyroActivity. Your MainActivity must be a ReactActivity (any ComponentActivity works).

Add one packaging block to android/app/build.gradle (the chip reader's Bouncy Castle jars and jspecify ship duplicate META-INF files; without it mergeDebugJavaResource fails with "2 files found with path 'META-INF/LICENSE.md'"):

android {
    packaging {
        resources {
            excludes += ["META-INF/versions/9/OSGI-INF/MANIFEST.MF"]
            pickFirsts += ["META-INF/LICENSE.md", "META-INF/NOTICE.md", "META-INF/LICENSE.txt", "META-INF/NOTICE.txt"]
        }
    }
}

iOS

SekyroKit is not on CocoaPods trunk. Declare where it comes from once in your Podfile, after use_native_modules!:

require Pod::Executable.execute_command('node', ['-p',
  'require.resolve("@sekyro/react-native/package.json", {paths: [process.argv[1]]})', __dir__]
).strip.sub(/package\.json$/, 'scripts/sekyro_pods.rb')

target 'YourApp' do
  config = use_native_modules!
  sekyro_kit_pod!   # SekyroKit from github.com/IBTIKAR-Technologies/sekyro-ios-dist at the pinned version
  # ...
end

Then cd ios && pod install. sekyro_kit_pod! installs the signed SekyroKit.xcframework named by the dist repo's podspec (its download is checksum-verified). Static or dynamic frameworks (use_frameworks!) both work.

Info.plist (camera always; NFC only if you read document chips):

KeyValue
NSCameraUsageDescriptione.g. "The camera is used to capture your face and your identity document for verification."
NFCReaderUsageDescriptione.g. "NFC is used to read the chip of your passport or identity card."
com.apple.developer.nfc.readersession.iso7816.select-identifiersA0000002471001, A0000002472001

Capabilities (Xcode → Signing & Capabilities): App Attest (entitlement com.apple.developer.devicecheck.appattest-environment = production for TestFlight / App Store) and, for chip reading, Near Field Communication Tag Reading (com.apple.developer.nfc.readersession.formats = TAG).

Expo (development builds / prebuild)

{ "expo": { "plugins": [["@sekyro/react-native", { "nfc": true, "appAttest": "production" }]] } }

Options: nfc (default true), appAttest ("production" default, "development", or false), cameraPermission and nfcPermission (your usage strings). The plugin writes the Info.plist keys, the NFC AIDs, the entitlements and the sekyro_kit_pod! Podfile line (idempotent), and fails the prebuild when Android minSdkVersion (expo-build-properties) is below 24. Unknown options are an error.

2. Register the app (Sekyro dashboard → Apps → your app → Platforms)

Device attestation (Google Play Integrity / Apple App Attest) is described in native-attestation.md. For a React Native app register the same identifiers as a native app: the Android applicationId with its signing-certificate SHA-256 digests (Play app signing key, upload key, debug key for internal builds) and the iOS bundle id with your Team ID.

3. Start a verification

import { startSekyro, SekyroError } from '@sekyro/react-native';

async function verify(clientToken: string) {
  try {
    const result = await startSekyro({
      clientToken,                       // from your server, one per session
      locale: 'fr',                      // 'ar' | 'fr' | 'en'; default: the session's / device language
      theme: { colors: { brand: '#0B6E4F' }, radius: 12 },
      onEvent: (e) => analytics.track('kyc_step', e), // no personal data in events
    });
    switch (result.status) {
      case 'finished': // result.sessionId, result.displayStatus: 'approved' | 'review_pending' | 'rejected'
        break;
      case 'cancelled': // the person closed the flow
        break;
      case 'failed': // result.code from the Sekyro error catalog (e.g. 'session_expired', 'session_token_invalid')
        break;
    }
  } catch (e) {
    if (e instanceof SekyroError) {
      // Programmer errors only: 'invalid_config' | 'flow_in_progress' | 'no_activity' | 'unsupported_platform'
    }
  }
}

Or declaratively — <SekyroFlow> presents the flow when it mounts and renders nothing. Mount it once per session (remount with a new clientToken to restart):

import { SekyroFlow } from '@sekyro/react-native';

{token ? <SekyroFlow clientToken={token} locale="ar" onResult={(r) => setResult(r)} /> : null}
  • What the person sees follows your app's eKYC profile, in three sections: contact (phone/email code, or one of them by choice), identity (national eID, NNI, document photo or chip, then an optional summary to confirm), live photo. See the flow model. The identity summary stays on the device screen: it is never in onEvent, the result or webhooks.
  • One flow at a time. A second startSekyro while one runs rejects flow_in_progress.
  • apiOrigin is only for Ibtikar staging tests (https://api-staging.sekyro.ai); leave it unset in production.
  • An expired session resolves { status: 'failed', code: 'session_expired' }; create a new session.
  • unsupported_platform: the native module is not linked (Expo Go, web, a missing pod install, or an app with the New Architecture turned off).

4. Events

onEvent receives { type: 'step', step, retryReason? } when the screen changes, and { type: 'waiting_for_network' } while the SDK waits for connectivity. Steps: consent, method, phone_otp, email_otp, registry, document, nfc, liveness, processing, result, update_required. retryReason is a catalog code (for example liveness_retry, chip_read_failed) when the person is asked to try again. Events never contain personal data, the token or a decision; use them for analytics and your own progress UI only.

5. Theming and copy

theme fieldAndroidiOS
colors.brand, brandFg, bg, surface, fg, fgMuted, danger, success, warning (#RRGGBB)yesyes
colors.borderignored in 0.1yes
radius (0–32, dp / pt)yesyes
fontFamily (a font bundled in your app)ignored in 0.1yes
darkMode ('system' | 'light' | 'dark')yesyes

The runtime theme wins over the branding set in the dashboard, which wins over Sekyro's defaults.

strings overrides copy by catalog key, per locale. It needs locale (only the active locale's map is sent):

startSekyro({ clientToken, locale: 'fr', strings: { fr: { 'consent.title': 'Vérification du client' } } });

Named placeholders such as {channel} are filled in your text. Unknown keys are ignored.

6. Test it

The sample app sekyro-mobile/examples/react-native-sample (in the SDK distribution) takes a hosted link (https://verify-staging.sekyro.ai/fr/abc-defg-hjk or https://verify.sekyro.ai/...), starts the flow and lists the events and the display result. Create the session from your server or the dashboard and paste its link.

On this page