This guide moves sensitive user data from your own data stores into Footprint's Nitro Enclave-backed vaults. Migrated users use the same vaulting APIs as users who onboard through Footprint's embedded KYC flows: create, decrypt, search, and proxy all work the same way. Progressive onboarding, watchlist checks, and embedded components also work on migrated user data.

Before you start

You need a server-side API key; see API authentication.

1. Create a user vault

If the user has no fp_id yet, create a vault with POST /users. Pass the data you already hold for the user as a key-value map, and the vault is created with it.

bash
1curl https://api.onefootprint.com/users \
2    -X POST \
3    -u sk_test_CXUsbCR8j2kH6e5GeEl8eSBnQTIPCUaKpv: \
4    -d '{
5        "id.first_name": "Jane",
6        "id.middle_name": "Samantha",
7        "id.last_name": "Doe",
8        "id.dob": "1988-12-30",
9        "id.ssn9": "123-45-6789",
10        "id.address_line1": "1 Penguin Pond",
11        "id.city": "Polar Plunge",
12        "id.state": "NY",
13        "id.zip": "10014",
14        "id.country": "US",
15        "id.phone_number": "+15555550100",
16        "card.primary.number": "4242424242424242",
17        "card.primary.cvc": "424",
18        "card.primary.expiration": "12/24",
19        "custom.account_number": "42421212312",
20        "custom.routing_number": "12121212121"
21    }'

The response returns the user's fp_id.

json
1{
2  "id": "fp_id_K0q6Eh6Rr3WOOfFBLPiHsr"
3}

The fp_id is the only identifier you need to store for this vault; every piece of vault data is referenced by it.

A successful response means the data passed validation, the vault exists, and the data is stored. Otherwise the error names the field that failed validation, and no vault is created.

A vault holds identity data, debit and credit card data, identity documents such as driver's licenses and passports, custom key-value records, and more. Footprint validates structured data as it is vaulted. The POST /users reference covers the field names and the request in detail.

2. Check data integrity (optional)

On a large migration you may want proof that what landed in the vault matches your database byte for byte. The integrity endpoint computes signed HMAC-SHA256 hashes of the vaulted values so you can compare them against your own. It is being phased out in favor of the transforms option on decrypt, which covers the same need; prefer that in a new integration.

Send a hex-encoded signing_key and the fields to check in fields. For each key in fields, the response contains hmac-sha256(signing_key, vault[key]).

bash
1curl https://api.onefootprint.com/users/fp_id_K0q6Eh6Rr3WOOfFBLPiHsr/vault/integrity \
2  -X POST \
3  -u sk_test_CXUsbCR8j2kH6e5GeEl8eSBnQTIPCUaKpv: \
4  -d '{
5          "fields": ["id.first_name", "id.last_name", "id.ssn9", "card.my_alias.number"],
6          "signing_key": "a1f928d87278290bf9dece075d0e46330a01d21b346073f4f193739078dca458"
7      }'

The response returns one signature per field.

json
1{
2  "id.first_name": "6e9b8af84ffc8829f03911f73c997d27c62a4c2078d90320ebcb7dbbce0e39a5",
3  "id.last_name": "55c6c9c45dc54391fdd2f98d719095479ca3022f8583d1a6442d4c66889f8bb9",
4  "id.ssn9": "18568e3cd81f27a50e56750317d3446a3080f3aba4a726af3b848b51eb37071f",
5  "card.my_alias.number": "4f8a7abfbf11912991b364fd429f2a59cea4c859619692e712b628752cb83ecf"
6}

Next steps

Manual migration assistance

For help with a migration, email support@onefootprint.com with the details of your request. Encrypt any sensitive data with the PGP key below before sending it.

Footprint PGP instructions

Use GPG to import the public key below, then encrypt each file.

bash
1gpg --encrypt --recipient 1ED420961981B558 <FILENAME>

In this command:

  • 1ED420961981B558 is Footprint's key ID.
  • <FILENAME> is the plaintext file you are encrypting.
  • <FILENAME>.gpg is the encrypted output to send to Footprint.

Footprint PGP public key

text
1-----BEGIN PGP PUBLIC KEY BLOCK-----
2
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
50OwC3wKkvTn6QpiPA9DDuE3PSp2ZZ
51=EpSl
52-----END PGP PUBLIC KEY BLOCK-----