Take the person through the capture in a browser, using the token and link returned by Human Plugin.
Your back-end creates the process in Human Plugin with a Journey flow. The 201 response has three values the front-end needs:
| Field | Used for |
|---|---|
id | The Human Plugin process id. The SDK takes it as transactionId, and your back-end reads the outcome with it |
token | Starts the capture in the Journeys SDK |
link | The hosted capture page |
token and link are returned only by the create. Pass them to the front-end in the same request, or store them yourself. See Human Token Journey.
Requirements
The capture runs in the browser and needs camera access.
| OS | Chrome | Firefox | Safari | Samsung Internet | Opera | Edge |
|---|---|---|---|---|---|---|
| Windows | ✅ | ✅ | N/A | N/A | ❌ | ❌ |
| macOS | ✅ | ✅ | ✅ | N/A | ❌ | ❌ |
| Android | ✅ | ❌ | N/A | ✅ | ❌ | ❌ |
| iOS | ✅ | ✅ | ✅ | N/A | ❌ | ❌ |
- Pages must be served over HTTPS. The camera only works in a secure context.
- In-app browsing needs Android 8 (API 26) or iOS 13 or later.
- Browsers inside social-network apps are not supported.
Choose a model
| Model | Best for |
|---|---|
| Hosted link | The simplest setup. No library: the person goes to the link and comes back to your callbackUri |
| Journeys SDK | The capture opens inside your page, so the person never leaves it |
- Hosted link
- Journeys SDK
Send callbackUri in the create request. It is the page the person returns to when the capture ends.
{
"flow": "humantoken",
"clientId": "client-a",
"correlationId": "order-1001",
"credential": { "type": "DUI_TYPE_NG_BVN", "value": "<document number>" },
"callbackUri": "https://app.example.com/capture/done"
}
Then send the person to link, in one of two ways:
- Redirect. Navigate to
link. At the end, the person is sent back tocallbackUri. - New tab. Open
linkwithwindow.open(), watch for the tab to reachcallbackUri, and close it.
When the person is back, tell your back-end, which calls GET /v1/processes/{id}.
The SDK opens the capture in an iFrame on your page. It works with any framework (React, Angular, Vue) or plain JavaScript.
Before you start, ask Unico support to register your domains. They must use HTTPS.
1. Install
npm install unico-journey-sdk
The SDK follows semantic versioning, so minor and patch updates are safe to take. Keep it up to date: security and bug fixes ship in new versions.
2. Allow the SDK in your headers
Skip this step if your page sends no Content-Security-Policy or Permissions-Policy header. Otherwise, add:
Content-Security-Policy:
frame-src https://*.unico.io https://*.unico.app;
script-src https://idpay.unico.io;
style-src https://idpay.unico.io;
connect-src https://api.cadastro.unico.app;
Permissions-Policy:
camera=(self "https://human-token.unico.io" "https://cadastro.unico.app" "https://id.unico.io" "https://retry.unico.io" "https://ultimatum.unico.io"),
geolocation=(self "https://human-token.unico.io" "https://cadastro.unico.app" "https://id.unico.io" "https://retry.unico.io" "https://ultimatum.unico.io")
3. Initialize
Call init as soon as you know the capture is needed. It preloads the capture.
import { ByUnicoSDK } from 'unico-journey-sdk';
ByUnicoSDK.init({ token });
4. Open the capture
| Parameter | Required | Value |
|---|---|---|
transactionId | Yes | The Human Plugin id |
token | Yes | The token from the create |
onFinish | Yes | Called when the capture ends or the person closes it |
onWidgetVisibilityChange | No | Called when the capture is shown or hidden |
ByUnicoSDK.open({
transactionId: id, // the Human Plugin id
token,
onFinish: ({ type }) => {
if (type === 'FINISH') {
// The capture ended. Ask your back-end to read the outcome.
}
// type === 'CLOSE': the person closed it before the end.
},
// Optional: hide your own overlays while the capture is visible.
onWidgetVisibilityChange: (visible) => {},
});
// To close it yourself:
ByUnicoSDK.close();
onFinish receives:
| Field | Description |
|---|---|
type | 'FINISH' when the capture ended, 'CLOSE' when the person closed it first |
transaction.redirectUrl | Where to send the person next. Present only for 'FINISH' |
onFinish says the capture ended, not how. The outcome comes only from GET /v1/processes/{id} on your back-end.
Use onFinish also to move the person to the next screen, and to avoid creating a new process right away if they start again.
Troubleshooting
- The flow breaks or behaves oddly. Make sure no script of yours changes the SDK's iFrame in the DOM.
- The capture looks different. Broad CSS rules, such as tag selectors, can reach the iFrame. The SDK's own ids and classes start with
unico. - Unexpected errors after an update. Install the SDK only through npm or yarn, and never edit its files.
Close the browser DevTools before you test a capture end to end. An open DevTools blocks the submission.
- The SDK inside a mobile WebView. In an app, open the
linkinstead. See the Android, iOS, Ionic, React Native and Flutter guides. - Your own
<iframe>pointing to the capture. Use the SDK, which manages the iFrame.