Usage
Coming from @getvouch/react-native-sdk? The Modal API keeps the legacy VouchSDK.start / startHeadless calls working — see the migration guide for what changes.
Overview
The Vouch React Native SDK embeds the full verification flow in your app: screens, state machine, and backend transport that take a proof request from start to finished proof. Integration is hook-first: mount one provider, drive the flow with the useVouch hook, and render it with VouchScreen wherever your app decides to show it.
1. Mount the provider
Mount VouchVerifierProvider once at the app root. It owns the flow state; everything else renders under it.
import { VouchVerifierProvider } from "@getvouch/mobile-sdk";
function App() {
return (
<VouchVerifierProvider apiKey="API_KEY">
<YourScreens />
</VouchVerifierProvider>
);
}| Prop | Type | Required | Description |
|---|---|---|---|
apiKey | string | Yes | Your customer API key, required to create new proof requests. See First steps for where to find it |
customerId | string | No | Required only by the Modal API; the hook API takes it per flow inside createProofRequest |
baseUrl | string | No | Defaults to https://app.getvouch.io |
languageCodeOverride | string | No | BCP 47 tag (en, pl-PL, …) overriding the device language for modal starts; the hook API takes it per flow on startProve |
webviewDebuggingEnabled | boolean | No | Off by default. Development builds are always inspectable; this opts release builds into Chrome DevTools / Safari Web Inspector too. Leave it off in production: the proof WebView holds the user's authenticated session with the data source |
2. Start a flow and render it
Drive the flow with the useVouch hook and render it with VouchScreen:
import { useEffect } from "react";
import { VouchScreen, useVouch } from "@getvouch/mobile-sdk";
function ProveScreen() {
const { state, startProve, reset } = useVouch();
useEffect(() => {
// a. Resume a proof request your backend already created:
startProve({ requestId: "EXISTING_REQUEST_ID" });
// b. …or create one on the fly:
// startProve({
// createProofRequest: {
// customerId: "CUSTOMER_ID",
// dataSourceId: "DATA_SOURCE_ID",
// webhookUrl: "https://your-server.com/webhook",
// inputs: { INPUT_NAME: "value" },
// },
// });
return () => reset();
}, [startProve, reset]);
useEffect(() => {
if (state.status === "success") {
// state.result.proofId identifies the finished proof — navigate away here.
}
}, [state]);
return <VouchScreen />;
}startProve takes either { requestId } to resume an existing proof request, or { createProofRequest } to create one.
requestId is a string identifying a proof request your backend already created.
createProofRequest accepts:
| Parameter | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes | Your unique customer identifier from Vouch |
dataSourceId | string | Yes | The identifier for the data source to use for verification |
webhookUrl | string | No | The URL where verification results will be sent |
inputs | Object | No | Additional input parameters required by the data source |
metadata | string | No | An optional value passed alongside the proof for easier identification |
For detailed documentation on dataSourceId, webhookUrl, and inputs, see the getDataSourceUrl Parameters section.
3. Observe the state
state.status moves through idle → launching → processing → proving → success, or ends in error or cancelled (the user closed the flow; it carries the requestId of the flow it ended). While the status is idle, VouchScreen renders nothing.
Calling startProve again after any terminal state seeds a fresh flow — no explicit reset() needed; reset() returns the machine to idle without starting a new one.
4. Closing and re-entry
The user can leave the flow from the SDK's own chrome — the close control in the proof browser's header, the close on the video and error screens, or the Android hardware back button on any of those steps. Every one of them ends the flow the same way:
- Hooks API: the flow lands on the terminal
cancelledstatus, carrying therequestIdit ended. Compare that id against your own flow's before acting on it, so a shared provider's stalecancelledfrom an earlier flow does not move the wrong screen. - Modal API:
start/startHeadlessreject withdescription: "Vouch flow was closed"and reason0.
Two stages carry no close of their own: launching, while the proof request loads, and proving, where cancelling would throw away a proof that is nearly finished. In hooks mode nothing interrupts those stages — hardware back falls through to your own navigation, and it is your screen that decides what to do; in modal mode Android back dismisses the modal from any stage. proving continues without the flow UI on screen, so hiding your own screen during it is safe.
Closing discards the attempt — the proof request is not finished, and nothing is uploaded. To let the user try again, call startProve (or start) again; a modal host always starts a fresh proof request that way. Hooks hosts can also pass startProve({ requestId }) with the closed flow's id to re-enter that same proof request from the beginning instead of creating a new one; WebView cookies survive the close, so the user is usually still signed in to the data source. A request that already produced a proof cannot be reused — start a new one.
Modal API
Hosts migrating from the legacy imperative SDK can use the provider-backed modal API instead of the hook. It presents the flow in a full-screen modal and resolves a promise, so no VouchScreen is mounted. The provider must carry both customerId and apiKey — without either, start rejects with reason 14:
import VouchSDK, { VouchVerifierProvider } from "@getvouch/mobile-sdk";
function App() {
return (
<VouchVerifierProvider customerId="CUSTOMER_ID" apiKey="API_KEY">
<YourScreens />
</VouchVerifierProvider>
);
}
// Call this from a handler on a screen under the provider. `start` resolves the
// controller the mounted provider registers, so calling it at module scope —
// before that happens — rejects with reason 14.
async function verify() {
const { proofId } = await VouchSDK.start({
dataSourceId: "DATA_SOURCE_ID",
webhookUrl: "https://your-server.com/webhook",
inputs: { INPUT_NAME: "value" },
metadata: "YOUR_OWN_REFERENCE", // optional, travels with the proof
});
return proofId;
}VouchSDK.startHeadless(params, onProgress?) runs the same flow and takes the same params, but only presents UI during the sniffingRequests stage; it reports progress as downloadingConfig → sniffingRequests → proving → finished.
Both reject with a plain VouchError object — { reason, description, proofId? }, not an Error. A user who closes the flow rejects it too, with description: "Vouch flow was closed"; see Closing and re-entry and Error codes.
Cleanup
Call await VouchSDK.destroy() to remove WebView cookies. This works without a mounted provider. On Android it clears the dedicated Vouch WebView profile when the installed WebView provider supports profiles; older providers use the process default cookie store, so cleanup also removes cookies created by host WebViews. On iOS it clears the shared default WebKit cookie store, including cookies created by other WebViews in the host app. It does not clear other website data or cancel an active proof flow.
Error codes
A modal-API rejection carries a numeric VouchError.reason:
| Code | Description |
|---|---|
| 0 | Data source or customer not found |
| 1 | Outdated SDK version |
| 2 | Failed to create verification |
| 3 | Background timeout |
| 4 | Request too large |
| 5 | Data source misconfigured |
| 6 | Verification failed |
| 7 | Verification upload failed |
| 8 | Attachment reupload failed |
| 9 | Verification ID already taken |
| 10 | Network connection lost |
| 11 | Processing timeout |
| 12 | Wrong API key |
| 13 | Internal server error |
| 14 | Provider missing or unconfigured |
Code 0 doubles as the fallback for rejections without a more specific cause — including a cancelled flow — so branch on description rather than treating 0 as diagnostic.
Best Practice: Always handle both success and error cases. Log the proofId (when present) for debugging and user support purposes, even in error cases.