# Onboarding sessions

Onboarding sessions allow you to initiate an onboarding flow from your backend, passing relevant information for the session like an existing user's `fp_id`, bootstrap data, or external IDs. They are an alternative to passing all arguments directly into the Footprint SDK and include a few additional features since they are initiated with authority of your secret API key.

* Control when a user is allowed to reonboard onto a playbook
* Set the `external_id` for the user (or business) that will be created by this onboarding session
* Bootstrap data from your backend into an onboarding session

For more information, visit the API reference for POST /onboarding/session.

## Example

From your backend, using a secret API key, generate an onboarding session token using the POST /onboarding/session API. In its simplest form, an onboarding session token may be created with just a playbook key.

### Example request

```bash
curl -X POST https://api.onefootprint.com/onboarding/session \
  -u sk_test_CXUsbCR8j2kH6e5GeEl8eSBnQTIPCUaKpv: \
  -d '{"kind": "onboard", "key": "pb_live_qBV2iO3nQI5moqo5GJlFhI"}'
```

### Example response

```json
{
  "token": "obtok_UxM6Vbvk2Rcy1gzcSuXgk3sj3L9I0pAnNH",
  "link": "https://verify.onefootprint.com/?type=user#obtok_UxM6Vbvk2Rcy1gzcSuXgk3sj3L9I0pAnNH",
  "expires_at": "2025-01-04T12:00-08:00"
}
```

You will then provide the resulting token to the Footprint SDK as the `authToken`. If you are launching the user into a KYC onboarding flow, you would pass the `authToken` as a prop like so:

```javascript
import "@onefootprint/footprint-js/dist/footprint-js.css";
import footprint from "@onefootprint/footprint-js";

const handleClick = () => {
  const component = footprint.init({
    kind: "verify",
    authToken: "obtok_UxM6Vbvk2Rcy1gzcSuXgk3sj3L9I0pAnNH", // token from above
    onComplete: (validationToken) => {
      // TODO
    },
  });
  component.render();
};
```

## Example use cases

### Guarantee resolution to a specific user

You should aim to have one Footprint user `fp_id` per user in your own application. If you launch the Footprint flow inside a logged-in context in your application, you can provide the identifier of the user in your own database as the `user_external_id`. The onboarding session will then resolve to the existing Footprint user with this `external_id`, or create a new Footprint user with this `external_id`.

```bash
curl -X POST https://api.onefootprint.com/onboarding/session \
  -u sk_test_CXUsbCR8j2kH6e5GeEl8eSBnQTIPCUaKpv: \
  -d '{
    "kind": "onboard",
    "key": "pb_live_qBV2iO3nQI5moqo5GJlFhI",
    "user_external_id": "8c992273-987d-4830-84f7-01324ab66899"
  }'
```

External IDs may only include alphanumeric characters, `_`, `-`, or `.` and must be between 10 and 256 characters.

Or, if you know that the user has an existing `fp_id`, you can provide it directly:

```bash
curl -X POST https://api.onefootprint.com/onboarding/session \
  -u sk_test_CXUsbCR8j2kH6e5GeEl8eSBnQTIPCUaKpv: \
  -d '{
    "kind": "onboard",
    "key": "pb_live_qBV2iO3nQI5moqo5GJlFhI",
    "fp_id": "fp_id_K0q6Eh6Rr3WOOfFBLPiHsr"
  }'
```

### Guarantee resolution to a specific business

Similarly, if you are launching a Footprint KYB flow, you may also provide a `business_external_id` to log into the existing business with this `external_id` or create a new business with this `external_id`. Note that the located user must be marked as an owner of the located business or the onboarding session will result in an error.

```bash
curl -X POST https://api.onefootprint.com/onboarding/session \
  -u sk_test_CXUsbCR8j2kH6e5GeEl8eSBnQTIPCUaKpv: \
  -d '{
    "kind": "onboard",
    "key": "pb_live_qBV2iO3nQI5moqo5GJlFhI",
    "user_external_id": "8c992273-987d-4830-84f7-01324ab66899",
    "business_external_id": "2f55b318-5dec-4634-880f-38c4968d3b71"
  }'
```

External IDs may only include alphanumeric characters, `_`, `-`, or `.` and must be between 10 and 256 characters.

Or, if you know that the business has an existing `fp_bid`, you can provide it directly:

```bash
curl -X POST https://api.onefootprint.com/onboarding/session \
  -u sk_test_CXUsbCR8j2kH6e5GeEl8eSBnQTIPCUaKpv: \
  -d '{
    "kind": "onboard",
    "key": "pb_live_qBV2iO3nQI5moqo5GJlFhI",
    "fp_id": "fp_id_K0q6Eh6Rr3WOOfFBLPiHsr",
    "fp_bid": "fp_bid_fr7JHcV3hIzC7KbqTAsD3n"
  }'
```

### Bootstrap data

If you already have existing data for a user on your backend, you may create an onboarding session that will automatically prefill your existing data as bootstrap data for the user that is created.

```bash
curl -X POST https://api.onefootprint.com/onboarding/session \
  -u sk_test_CXUsbCR8j2kH6e5GeEl8eSBnQTIPCUaKpv: \
  -d '{
    "kind": "onboard",
    "key": "pb_live_qBV2iO3nQI5moqo5GJlFhI",
    "bootstrap_data": {
      "id.first_name": "Jane",
      "id.last_name": "Doe"
    }
  }'
```

To see which fields are available to bootstrap and the format in which they need to be provided, see [here](/articles/integrate/bootstrap-data).

### Onboarding idempotency

By default, when a user starts an onboarding session onto a playbook onto which they've already onboarded, Footprint will reuse the result of the user's last onboarding to prevent you from incurring accidental charges for repeat onboardings. `onboarding_external_id` gives you more control over this default behavior: if the user already has an onboarding with this `onboarding_external_id`, its results will be reused. If not, a new onboarding will be created and the user will be allowed to reonboard.

For example, if you'd like your users to be able to reonboard onto the same playbook every time they fill out a new account application in your product, you can provide the application's identifier as the `onboarding_external_id`.

```bash
curl -X POST https://api.onefootprint.com/onboarding/session \
  -u sk_test_CXUsbCR8j2kH6e5GeEl8eSBnQTIPCUaKpv: \
  -d '{
    "kind": "onboard",
    "key": "pb_live_qBV2iO3nQI5moqo5GJlFhI",
    "user_external_id": "8c992273-987d-4830-84f7-01324ab66899",
    "onboarding_external_id": "bc13ca5b-210f-49af-9aba-e98db366484a"
  }'
```

As another example, if you'd like users to reonboard onto the same playbook once every month, you can provide an `onboarding_external_id` that is a function of the current month:

```bash
curl -X POST https://api.onefootprint.com/onboarding/session \
  -u sk_test_CXUsbCR8j2kH6e5GeEl8eSBnQTIPCUaKpv: \
  -d '{
    "kind": "onboard",
    "key": "pb_live_qBV2iO3nQI5moqo5GJlFhI",
    "user_external_id": "8c992273-987d-4830-84f7-01324ab66899",
    "onboarding_external_id": "onboarding-2025-01"
  }'
```

We recommend using an `onboarding_external_id` value that implies some limit to how frequently a user can reonboard onto one playbook as you will be responsible for onboarding charges incurred for each reonboard.

External IDs may only include alphanumeric characters, `_`, `-`, or `.` and must be between 10 and 256 characters. Also note that since `onboarding_external_id`s are scoped to individual users, you must provide either an `fp_id` or `user_external_id` when creating the onboarding session.

### Collect outstanding data

If you have previously requested information from a user via the Footprint dashboard, you can create an onboarding session for that user that allows them to provide any remaining requested information.

A common flow is to check via API if a user has an outstanding request to provide more info using the GET /users/{fp_id} API:

```bash
curl https://api.onefootprint.com/users/fp_id_K0q6Eh6Rr3WOOfFBLPiHsr \
  -u sk_test_CXUsbCR8j2kH6e5GeEl8eSBnQTIPCUaKpv:
```

```json
{
  "id": "fp_id_K0q6Eh6Rr3WOOfFBLPiHsr",
  "requires_manual_review": false,
  "status": "pass",
  "requires_additional_info": {
    "timestamp": "2023-12-12T21:28:38.771377Z",
    "note": "Hi Christian, we can't wait for you to get started with your Acme Bank credit card! To finish verifying your identity, can you please submit a photo of your SSN card? Once received, we can approve your application and mail out your credit card."
  }
}
```

If the `requires_additional_info` field is non-null, there is an outstanding request to collect information from this user. It will also include a human-readable note you provided in the dashboard to display to your user, which you may choose to render in your own application. You can create an `inherit` onboarding session to collect the requested info:

```bash
curl -X POST https://api.onefootprint.com/onboarding/session \
  -u sk_test_CXUsbCR8j2kH6e5GeEl8eSBnQTIPCUaKpv: \
  -d '{
    "kind": "inherit",
    "fp_id": "fp_id_K0q6Eh6Rr3WOOfFBLPiHsr"
  }'
```

### Update login methods

You may also programatically allow a user to update any/all of their login methods (phone and email) using the Footprint Auth SDK. They will first be asked to log in using an existing login method on their account, and then they will be able to add a passkey or update their phone or email.

If you'd like to limit which auth methods are allowed to be updated, you can pass the list of desired methods in `limit_auth_methods` when creating the token. For example, if you'd only like the user to be allowed to update their phone number, you can create a token like so:

```bash
curl -X POST https://api.onefootprint.com/onboarding/session \
  -u sk_test_CXUsbCR8j2kH6e5GeEl8eSBnQTIPCUaKpv: \
  -d '{
    "kind": "update_login_methods",
    "fp_id": "fp_id_K0q6Eh6Rr3WOOfFBLPiHsr",
    "limit_auth_methods": ["phone"]
  }'
```

You would pass the `authToken` as a prop like so:

Make sure you are using at least the @onefootprint/footprint-js\@3.9.0 version.

```javascript
import "@onefootprint/footprint-js/dist/footprint-js.css";
import footprint from "@onefootprint/footprint-js";

const handleClick = () => {
  const component = footprint.init({
    kind: "update_login_methods",
    authToken: "obtok_UxM6Vbvk2Rcy1gzcSuXgk3sj3L9I0pAnNH",
    onComplete: (validationToken) => {
      // TODO
    },
  });
  component.render();
};
```