The Integration Guide
16 min read
Footprint makes it easy to onboard your users, whether you need KYC, KYB, identity document verification, or document collection. Security, compliance, and risk/fraud prevention come bundled in. This is the definitive guide to integrating Footprint into your product, including the advanced options and features that let you fully customize and own your flow.
Core concepts
Vault
Each entity in Footprint is backed by a secure data Vault that stores
identity, financial, documents, and custom data attributes. When a user onboards
via a Footprint flow all data collected is automatically stored in the user’s
vault. Vaults store both structured and unstructured data, and keep track of
each change to every attribute with a versioned history. Footprint's vaulting
aims to be flexible while providing base-level validation logic for structured
vault data such as Identity or PCI data. All attribute values are referenced by
specific data identifiers (such as id.ssn9 references the full SSN of a
user). Vault data fields are a core part of the Footprint platform: they support
granular role-based access controls (RBACs) for data access and can be used to
transmit data securely (via the Vault Proxy) to third-party destinations. Read
more about all the
vault data fields here.
The "fp_id"
Also known as the “Footprint ID”. This is the unique, per-user identifier for an
entity inside of Footprint. It appears in API request, responses, and on the
dashboard to uniquely identify an entity. Similar to fp_id, an fp_bid is the
unique identifier for a business entity.
The "external_id"
This is an identifier that you provide for a user or business. This provides a mechanism which you can map entities in your system to Footprint without storing/knowing the Footprint ID for that entity.
Playbook
A Playbook defines the end-to-end onboarding flow powered by Footprint: (a) what
information needs to be collected, (b) what verification checks need to run, and
(c) the rules that define decisioning based on the verification checks. A
playbook_key is the unique, publishable identifier for a playbook and appears
in API requests, responses, and in the dashboard.
Onboarding
An onboarding represents a user/business onboarding onto a Playbook. Each time a user/business goes through a playbook, it creates a new onboarding.
Integration overview
A user's journey with Footprint starts via the POST /onboardings API. It runs one of your playbooks against a user or business and returns the result. How much of the flow runs headlessly depends on how much data you've already collected:
- Fully headless: if your application already collects all the data the playbook needs, vault that data and run the onboarding entirely server-side, with no Footprint UI shown at all. The decision comes back synchronously inline or asynchronously via webhooks, depending on your settings.
- Interactive: if there is still information to collect from the user, the
API returns a
continue_onboardingtoken and link. Hand these to your frontend so the user can finish the remaining steps in one of two ways:- Hosted: a web page hosted by Footprint that includes the rest of the
onboarding flow. Send the
linkto your user via email, SMS, or a button in your app. - Embedded: use one of our many SDKs across web, iOS, and Android to
embed the rest of the flow inside your product, launched with the
token.
- Hosted: a web page hosted by Footprint that includes the rest of the
onboarding flow. Send the
Customization
The interactive flow supports customization to varying degrees:
- Hosted: Coming soon, use our appearance editor in the dashboard to control every element just like in the embedded flow.
- Embedded: use our SDK to fully customize the look and feel of each element including fonts, colors, borders, and much more. We support over 100 attributes of customization. See here for full details: https://docs.onefootprint.com/articles/integrate/customization.
Identity documents & document collection
One important caveat: Footprint handles the complexity of document collection and verification. Document collection is considered a singular component which includes everything from: device handoff (leveraging a mobile device when starting the flow on desktop), automatic capture and liveness, document classification, and selfie capture. The customization options extend to the full document collection and scanning experience.
The end-to-end integration
This guide covers all the most common steps to getting Footprint fully up and running in just a few minutes.
Step 1: Get your secret API key
Go to the Footprint dashboard and create a secret key. Store this key somewhere safe.
Step 2: Create a playbook
Go to the Footprint dashboard and create a Playbook. Playbooks define the onboarding: (a) what information needs to be collected, (b) what verification checks need to run, and (c) the rules that define decisioning based on the verification checks.
Step 3: Create the user and vault their data
Create the user with POST /users (or a business with POST /businesses) and write whatever data you have already collected:
bash
See Vault fields for the full list of fields you can vault, and Migrating user data to bring over data you already hold. If you expect the user to provide most of their information through the interactive flow, it's fine to vault only what you have, or nothing at all.
x-external-id header when creating the user.
You can then reference the user by external_id in later API calls instead of
storing the fp_id.Step 4: Run the playbook
Call POST
/onboardings with the entity and the playbook key. Set
synchronous_timeout_secs (max 30) to wait for the decision and receive it
inline:
bash1curl -X POST https://api.onefootprint.com/onboardings \ 2 -u <SECRET_API_KEY>: \ 3 -d '{ 4 "fp_id": "fp_id_K0q6Eh6Rr3WOOfFBLPiHsr", 5 "key": "<PLAYBOOK_KEY>", 6 "synchronous_timeout_secs": 30 7 }'
json1{ 2 "id": "ob_SRFT2a1mN7DAWJ0VPXkiqK", 3 "status": "pass", 4 "requires_manual_review": false, 5 "continue_onboarding": null, 6 "error_message": null 7}
If you omit synchronous_timeout_secs, the call returns immediately with
status: "pending" and the run continues in the background; the final decision
arrives via webhook (step 6). You'll generally only run a playbook
asynchronously when you have already collected all the information it needs.
This mode is useful for latent operations, like running an AI agent, that may
not finish within the synchronous timeout.
For a business, put the fp_bid in the fp_id field; there is no separate
fp_bid field. The key also accepts a version tag (pb_live_xxx:v3) to run a
specific playbook version, though we recommend deploying the version you want
from the dashboard rather than pinning it in code.
A KYB playbook that also verifies its beneficial owners can't run here: the owners have to complete their own KYC, which this API can't prompt for. Run those playbooks through an onboarding session instead.
Step 4a: Optional configuration
| Attribute | Description |
|---|---|
external_id | Reference the user or business by your own identifier instead of fp_id. This is the same external_id set when the entity was created. Cannot be provided alongside fp_id. |
onboarding_external_id | Use to control onboarding idempotency and to associate an onboarding with an event in your application (for example, an account application ID). If an onboarding with this ID already exists on the playbook, its result is reused and returned. If not, a new onboarding is created and the entity re-onboards. |
synchronous_timeout_secs | Wait up to this many seconds (maximum 30) for the run to finish and return the decision inline. Omit to run asynchronously. |
prerequisite_data | If your playbook requires additional information from your backend, configure a prerequisite node on the playbook and pass that data here. Only accepted when the playbook has a prerequisite node. |
POST /onboardings again without a new onboarding_external_id returns a 409 with the error "Already onboarded onto playbook".
See Run a playbook for the full reference on
POST /onboardings, including reonboarding patterns, KYB, and passing
onboarding data.
Step 5: Handle the decision
Your playbook defines a set of rules used to evaluate the entity and to decide
whether it should be flagged for manual review. Use the status and
requires_manual_review fields in the response to decide whether or not to
onboard this user to your product.
| STATUS | WHAT DOES THIS MEAN? |
|---|---|
pass / fail / none | An action node in your playbook executed and set the user's status. Conventionally, these are the output of rules that you define. |
pending | Either you ran asynchronously, or the playbook took longer than synchronous_timeout_secs to execute. Certain steps of a playbook, like AI agents or verification checks, may take longer. The final decision will be delivered via webhooks. |
incomplete | The onboarding could not finish headlessly because more information is needed from the user. Use continue_onboarding to let them finish (see below). |
error | The run failed due to logic configured on your playbook. See error_message. |
| REVIEW | WHAT DOES THIS MEAN? |
|---|---|
| False | Your playbook's rules have made a decision automatically. |
| True | Your playbook's rules have requested that this user is reviewed manually before onboarding OR the user’s previous onboarding status caused the review flag to remain enabled. |
If Footprint still needs information from the user (for example, your playbook
collects a field you didn't vault, or requires an identity document), the status
is incomplete and the response carries a continue_onboarding object:
json1{ 2 "id": "ob_SRFT2a1mN7DAWJ0VPXkiqK", 3 "status": "incomplete", 4 "requires_manual_review": false, 5 "error_message": null, 6 "continue_onboarding": { 7 "token": "obtok_UxM6Vbvk2Rcy1gzcSuXgk3sj3L9I0pAnNH", 8 "link": "https://verify.onefootprint.com/?type=user#obtok_UxM6Vbvk2Rcy1gzcSuXgk3sj3L9I0pAnNH", 9 "expires_at": "2025-05-08T12:00-07:00" 10 } 11}
The token resumes this exact onboarding: the user picks up where the headless
run stopped, and the completed run keeps the same id. Treat the token as a
secret, and use it before expires_at (12 hours). Hand it to your frontend to
let the user finish the remaining steps, using either of the two launch options
below.
Step 5a: Finish via Hosted
If using the Hosted launch option, extract the link and deliver it to your
end user via email, SMS, or through a button in your app.
Step 5b: Finish via Embedded
If using one of our embedded SDKs, extract the token and use that to launch
Footprint. Below find some examples of different SDKs.
Install: Web (JS/TS/React/Vue/Angular): npm install @onefootprint/footprint-js. iOS: via
Swift Package Manager
or Cocoa Pods. Android: see the
installation instructions.
1import "@onefootprint/footprint-js/dist/footprint-js.css";
2import { onboarding } from "@onefootprint/footprint-js";
3
4const App = () => {
5 const launch = () => {
6 onboarding.initialize({
7 // replace with `continue_onboarding.token` from the api response
8 onboardingSessionToken: "obtok_UxM6Vbvk2Rcy1gzcSuXgk3sj3L9I0pAnNH",
9 onComplete: (validationToken) => {
10 console.log("completed", validationToken);
11 },
12 });
13 };
14
15 return <button onClick={launch}>Verify Identity</button>;
16};When the user finishes the remaining steps, the SDK invokes the onComplete
handler with a validation_token. To get the state of the onboarding
immediately, validate that token (step 5c). The final decision is also
delivered via webhook (step 6), and you can fetch it at any time with
GET
/users/{fp_id}/onboardings/{id} using the onboarding id
from step 4.
Step 5c: Process the validation_token
Note: this only applies if you are using the Embedded SDK. If using Hosted, skip to step 6.
At the end of the onboarding flow, the SDK invokes an onComplete completion
handler that passes a validation_token to your code. Send the
validation_token to your backend and validate it using the
POST
/onboarding/session/validate API. This is the recommended way
to get the state of the onboarding immediately after the user finishes the flow.
bash1curl -X POST https://api.onefootprint.com/onboarding/session/validate \ 2 -u <SECRET_API_KEY>: \ 3 -d '{"validation_token": "<VALIDATION_TOKEN>"}'
fp_id/fp_bid of the corresponding entity that was
created or reused.
The response will look like:
json1{ 2 "user": { 3 "fp_id": "fp_id_GSxJr68GAf5jUT3pdL9ndjf7TLkA3GCX", 4 "onboarding_id": "ob_SRFT2a1mN7DAWJ0VPXkiqK", 5 "playbook_key": "pb_test_VMooXd04EUlnu3AvMYKjMW", 6 "requires_manual_review": false, 7 "status": "pass" 8 }, 9 ... 10}
Step 6: Listen to webhooks
Every onboarding's decision is delivered via webhook when it reaches a terminal
status. For asynchronous runs or synchronous runs that returned pending,
webhooks are how you receive the final result.
Step 6a: Subscribe a webhook endpoint
To enable webhook events, you need to register webhook endpoints in the Footprint dashboard. After you register them, Footprint can push real-time event data to your application's webhook endpoint when events happen in Footprint.
To get started, see the guide to consuming webhooks.
We recommend that you secure your integration by always verifying that all webhook requests are generated by Footprint. Please see our guide on securely verifying webhook signatures.
Step 6b: Recommended events
For the core Footprint integration, we recommend listening to the following three event types.
Onboarding completed
We recommend subscribing to the footprint.onboarding.completedevent, which will fire when an onboarding has reached a terminal status.
In most cases, a synchronous
POST /onboardingscall will return a terminalpass,fail, ornonedecision inline. This webhook event delivers the final decision when you run an onboarding asynchronously or when identity verification vendors are taking longer to verify a user.Manual review
Employees at your company may change a user's status while manually reviewing a user in the Footprint dashboard. This will fire the footprint.user.manual_reviewevent. Upon receiving this webhook, we recommend consulting the GET /users/{fp_id} API for information on the user's new manual status.
Watchlist checks
If your playbook has continuous monitoring enabled, Footprint will regularly check if any of your users are found on AML watchlists. Updates on watchlist checks are sent using the footprint.watchlist_check.completedevent.
Appendix
Advanced integration options
Below we’ve high-lighted some additional, more advanced options available to you as you integrate Footprint into your product. All of these are optional and using these methods typically indicate you are using Footprint in less common ways. Note some of these APIs may be gated, so please reach out to us if an API you need is not enabled on your account.
Use the API to fetching Onboardings, PII, Decisions, Risk signals, Documents, and more
In more advanced integration cases, you may want to process more detailed verification data and results from Footprint (instead of only viewing it in the dashboard). This can be useful if you are embedding results from Footprint in your application (i.e. a seller marketplace app who needs to pass risk signals to the seller who will verify a buyer for large transactions).
The Onboarding object
Every time a user or business onboards onto a playbook, an “onboarding” is
generated, and each onboarding has a unique ID often referenced as
onboarding_id. These IDs can be used to fetch risk signals, decisions,
documents and data collected, and more at a specific “onboarding”. An onboarding
ID lets you track the user as they update and modify data over time.
The two main places where onboarding IDs will be provided to you are:
- The
idfield of the POST /onboardings response - A Webhook when an onboarding is completed.
You can list onboardings for a user/business by using the GET /users/{fp_id}/onboardings and GET /businesses/{fp_bid}/onboardings APIs.
Fetch risk signals, and list collected data and documents by onboarding ID
Once you have a particular onboarding_id you can use the
GET
/users/{fpid}/onboardings/{onboardingid}/risk_signals and
GET
GET /users/{fpid}/documents?onboardingid=ob_xyz.. APIs to
fetch onboarding specific risk signals and captured documents.
Fetch decisions
Given a user or a business, you can fetch all the decisions (including manual review decisions that occurred with a human in the loop). Use the list all decisions API (for users/businesses). The response will look like following:
json1{ 2 "data": [ 3 { 4 "kind": "playbook_run", 5 "playbook_key": "pb_live_fZvYlX3JpanlQ3MAwE45g0", 6 "status": "fail", 7 "timestamp": "2022-01-04T12:00-07:00" 8 }, 9 { 10 "kind": "manual", 11 "status": "pass", 12 "timestamp": "2022-01-04T12:00-07:00" 13 } 14 ], 15 "meta": { 16 "next_page": 2 17 } 18}
Decrypt PII/documents from the vault at a specific onboarding
Footprint’s information systems are built around highly-secured vaulting infrastructure with granular access controls. Use the decrypt API to access plaintext sensitive user/business data.
bash1curl -X POST https://api.onefootprint.com/users/{fp_id}/vault/decrypt \ 2 -u <API_KEY>: \ 3 -d '{ 4 "fields": [ 5 "id.ssn9", 6 "id.last_name", 7 "document.passport.front.image", 8 "document.passport.dob" 9 ], 10 "reason": "compliance", 11 "at_onboarding_id": "ob_id_xyz..." 12 }'
You may specify the at_onboarding_id field to decrypt a user's historical
information at the time of the provided onboarding.
Linking users to businesses via API
If you are using KYB playbooks but not verifying beneficial owners (i.e. you are not using Footprint’s feature of verifying business owners together with the business), you can still take advantage of linking users to their businesses (and vice-versa) so that you can connect entities in the API and see the connections in the Footprint dashboard. Use the link a business owner API after onboarding both a business and the user(s).