Migrating user data

In order to migrate your authentication from an existing system to Stytch's B2B SaaS Authentication platform, you will need to import all current organization and user data to Stytch via API or SDK.

Stytch recommends the data migration approaches outlined below. This involves creating a set of jobs to synchronize organization and user data to Stytch.


Dual-write and Backfill

Dual-write and Backfill is a technique for static migrations where logic is introduced to keep Stytch in sync with the existing authentication provider in addition to running a one-time data backfill. This prevents Stytch from ever getting out of sync with the existing authentication service during the cutover.

If you have less than 500k users, we recommend using the Export and Import static migration approach which is explained further below.

Dual-write Backfill Img

The above is an example diagram of a Dual-write and Backfill process for users and organizations.

Step 1: Set up dual-write using the Create Organization and Create Member endpoints

Dual-write is a method that involves deploying logic to sync all changes between your internal user and organization tables and Stytch. This includes new user signups, user updates, and user deletions, as well as organization creations, updates, and deletions.

For every write into your internal tables, duplicate that write to Stytch via API. The returned Stytch member_id or organization_id should be saved in your tables so you know the user or organization has been migrated.

Organization API endpoints:

Member API endpoints:

  • Create user via Create Member
  • Deletions: Delete user via Delete Member
  • Updates:
    • If the user doesn't already exist in Stytch, create the user via Create Member. Use Migrate Member if the user has a password hash in your db.
    • If the user already exists and the change is limited to metadata, name, role, phone number, or authentication settings, update the user via Update Member.
    • Else, delete Stytch Member and recreate the user via Create Member. Ensure the new Stytch member_id is updated in your user db.

Step 2: Deploy a backfill

While dual-write is continuously running, you can assume that all users and organizations in your internal tables without an associated Stytch member_id or organization_id must run through a backfill job that adds them to Stytch via the Create Organization endpoint or the Create Member endpoint, one at a time.

Create Organization:

curl --request POST \
  --url https://test.stytch.com/v1/b2b/organizations \
  -u 'PROJECT_ID:SECRET' \
  -H 'Content-Type: application/json' \
  -d '{
    "organization_name": "Example Org Inc.",
    "organization_slug": "example-org",
    "mfa_policy": "REQUIRED_FOR_ALL",
    "email_allowed_domains": ["example.com"],
    "email_invites": "ALL_ALLOWED",
    "email_jit_provisioning": "RESTRICTED",
  }'

Create Member:

curl --request POST \
  --url https://test.stytch.com/v1/b2b/organizations/{ORGANIZATION_ID}/members \
  -u 'PROJECT_ID:SECRET' \
  -H 'Content-Type: application/json' \
  -d '{
    "email_address": "adalovelace@stytch.com",
    "mfa_phone_number": "+18000000000",
    "mfa_enrolled": true
    "trusted_metadata": {"internal_id": "407207d7-2a19-44e8-b192-4e2d45428b31"}  
  }'

Your backfill job should start with Organizations, then backfill Members once Organizations are complete. This job should submit requests to Stytch at a rate of 100 r/s maximum.

Step 3: Move password hashes to Stytch

If your manage passwords in-house within your own databases, you can integrate the logic for migrating passwords hashes into the core dual-write and backfill steps.

However, if you are migrating over from a legacy auth provider, like Auth0, that stores password hashes on your behalf, you will need a full data export. In order to minimize the time for drift on password changes, we recommend migrating password hashes at the end of this process by executing a script to call our Migrate Password endpoint for each user after backfill has been completed.

You may call Migrate Password endpoint for existing Stytch users. Stytch will recognize the email address and add the password hash to the existing Member object.

curl --request POST \
  --url https://test.stytch.com/v1/b2b/passwords/migrate \
  -u 'PROJECT_ID:SECRET' \
  -H 'Content-Type: application/json' \
  -d '{
    "email_address": "adalovelace@stytch.com",
    "hash": "$2a$12$vefoDBbzuMb...",
    "hash_type": "bcrypt",
    "organization_id": "organization-test-07971..."
  }'

If you are migrating over from an in-house build, you may fold password hashes into the dual-write and backfill logic given this information is readily available in your own db.


Export and Import

First, you will need to export your organization and user data from your current auth service. We recommend querying this information from your internal user and organization tables if possible. If you don't have a copy of user and workspace records outside of your auth provider, here are some helpful resources to export from various auth providers:

Next, you will write an import job that calls Stytch's API to create each Organization and Member in Stytch. The logic should resemble the following steps:

Step 1: Migrate to Stytch Organizations

Pass each application user group's name, slug, and authentication settings into Stytch create Organization API endpoint.

  • If the Organization has Single Sign-On connections with an identity provider, you will need to create SAML and OIDC connection objects. See Additional migration considerations for more information.
  • Configure an Organization's auth settings to control approved authentication methods, allowed email domains, invites, MFA, JIT provisioning, SSO connections, and more. See the managing Organization settings guide for more information.
curl --request POST \
  --url https://test.stytch.com/v1/b2b/organizations \
  -u 'PROJECT_ID:SECRET' \
  -H 'Content-Type: application/json' \
  -d '{
    "organization_name": "Example Org Inc.",
    "organization_slug": "example-org",
    "email_allowed_domains": ["exampleorg.com"],
    "email_invites": "RESTRICTED"
  }'

Step 2: Migrate users to Stytch Members

For each Stytch Organization a user belongs to, you will need to create a Member object. Pass the user's email address, phone number (optional), and their password hash (optional) into the corresponding Stytch API endpoints:

curl --request POST \
  --url https://test.stytch.com/v1/b2b/organizations/{ORGANIZATION_ID}/members \
  -u 'PROJECT_ID}:SECRET' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Ada Lovelace",
    "email_address": "adalovelace@stytch.com"
  }'

What's next

Check out the additional migration considerations guide to learn how to move your app logic to Stytch and for more user import guidance.