React Native SDK

@switchlabs/verify-ai-react-native ships a verification client, a React hook, and an optional camera scanner component that handles the full capture / upload / retry loop.

Install

Core SDK (client, hooks, types):

bash
npm install @switchlabs/verify-ai-react-native

With the built-in camera scanner:

bash
npm install @switchlabs/verify-ai-react-native expo-camera expo-image-manipulator expo-sensors

For offline queue support, also install @react-native-async-storage/async-storage.

For on-device inference, also install expo-file-system, react-native-fast-tflite, and configure the delegates you plan to use.

Peer dependencies

The scanner peer dependencies are intentionally optional — if you only need the verification client, none of the Expo camera modules are required.

Quick start

Guided vehicle inspection

For a complete inspection, use SDK 2.9.1 or later and the dedicated inspection entry point. 2.8.0 added camera-only sessions and the windscreen, engine-compartment and tyre views that lending inspections use; 2.8.1 waits long enough for photos that take longer to check. 2.9.0 keeps the camera available while earlier photos are checked in sessions with background checks or camera-only capture (as the hosted page does), and hands free-order, video and coverage-collection sessions to the browser with onHostedHandoff, since the native screen does not capture those. Your backend creates the session and sends its signed url to your app. Keep the permanent tenant API key on your backend. See the inspection integration guide for the create request, hosted links, custom API screens and cancellation.

tsx
import { useMemo } from 'react';
import { InspectionClient, VerifyAIInspection, type VerifyAIInspectionProps } from '@switchlabs/verify-ai-react-native/inspection';
 
type Props = Pick<VerifyAIInspectionProps, 'onClose' | 'onSubmitted'> & {
  captureUrl: string;
};
 
function VehicleInspection({ captureUrl, onClose, onSubmitted }: Props) {
  const client = useMemo(() => new InspectionClient({ captureUrl }), [captureUrl]);
  return <VerifyAIInspection client={client} onClose={onClose}
    onSubmitted={onSubmitted} />;
}

Install the camera, image manipulation, sensor and filesystem peers listed in the package README. Configure camera permission for both mobile platforms. Capture includes guides, preview, retakes, progress recovery, optional close-ups, signature and submission. Supply pickPhoto for your photo library and onOpenReport for your PDF viewer. Submission confirms saved evidence; condition review remains a separate step.

Individual photo verification

tsx
import { useVerifyAI } from "@switchlabs/verify-ai-react-native";
 
function ParkingScreen() {
  const { verify, loading, lastResult } = useVerifyAI({
    apiKey: process.env.EXPO_PUBLIC_VERIFY_AI_KEY!,
  });
 
  const onPhoto = async (base64: string) => {
    const result = await verify({
      image: base64,
      policy: "scooter_parking",
    });
    if (result?.is_compliant) {
      // end the ride
    }
  };
 
  return null;
}

Drop-in scanner

The scanner is exported from a separate subpath so the camera modules don't get pulled in for consumers that only use the client.

tsx
import { useVerifyAI } from "@switchlabs/verify-ai-react-native";
import { VerifyAIScanner } from "@switchlabs/verify-ai-react-native/scanner";
 
function ScannerScreen() {
  const { verify } = useVerifyAI({ apiKey: process.env.EXPO_PUBLIC_VERIFY_AI_KEY! });
 
  return (
    <VerifyAIScanner
      policy="scooter_parking"
      onCapture={(base64) => verify({ image: base64, policy: "scooter_parking" })}
      onResult={(result) => console.log(result.is_compliant ? "PASS" : "FAIL")}
      onClose={(result) => console.log("closed", result?.id)}
      showCloseButton
      overlay={{
        instructions: "Center the scooter in the frame",
        processingMessage: "Checking parking compliance...",
        failureMessage: "Parking issue detected",
        retryMessage: "Try again. {remaining} attempts left.",
        terminalResultDisplayMs: 3000,
        terminalActionLabel: "Continue",
      }}
    />
  );
}

Passing policy enables policy-aware default copy and guide overlays for scooter, bike, and forest parking policies. Override any strings through the overlay prop.

Offline mode

tsx
const { verify, queueSize, processQueue } = useVerifyAI({
  apiKey: process.env.EXPO_PUBLIC_VERIFY_AI_KEY!,
  offlineMode: true,
});
 
const result = await verify({ image: base64, policy: "scooter_parking" });
// If the network was down, the request was queued and result is null.
// The SDK retries it automatically; queueSize counts what is waiting.

Offline mode requires @react-native-async-storage/async-storage. The SDK queues transient failures (network errors, timeouts, 429, 5xx) and retries them in the background.

Metadata enrichment

The hook attaches device metadata automatically (model, OS version, app version, app build, scanner SDK version, GPS if granted) so every verification carries the context you need for incident review:

tsx
const result = await verify({
  image: base64,
  policy: "scooter_parking",
  metadata: { user_id: "usr_…", trip_id: "trip_…" },
});
 
// result.metadata also includes:
//   sdk_version, app_version, device_model, os_version, gps, etc.

API surface

ExportDescription
useVerifyAI(options)React hook — exposes verify, loading, lastResult, queue helpers.
VerifyAIClientDirect client class. Use if you don't want the hook.
VerifyAIScannerCamera scanner UI (separate subpath).
typesRe-exports VerificationResult, PolicyConfig, etc.

See the package README on npm for the full API.

Versioning

The current published version is 2.9.1. The SDK follows semver — patch for fixes, minor for new features, major for breaking changes. Check your installed version against npm view @switchlabs/verify-ai-react-native version.

What do you need to verify?

Tell us about the evidence, the decision and the workflow around it.

Discuss your workflow