Skip to content
  • Get started
  • Switch to Kinde

Create users with the Kinde API during migration

Use the Kinde Management API to create and provision users programmatically — the right approach when you need to intercept live sign-ups or password changes during a migration window, or when you control the login form in a custom auth system and can hook directly into the sign-in path.

When to use this approach

Link to this section
  • Migration window safety net — your app intercepts logins/sign-ups in your legacy system and pushes users to Kinde in parallel, so no one is missed during the transition.
  • Custom auth systems — you host your own login form and can add a Kinde API call to the sign-up/sign-in path.
  • Real-time password sync — when a user successfully authenticates against your old system, you create them in Kinde with the same password.

For automated drip-feed migration (no code changes to your app), see Drip-feed migration instead.

  • A Machine to Machine application authorized to use the Kinde Management API - see the quickstart guide.
  • Required scopes: create:users and update:user_passwords
  • A preferred way to use the Management API (Node.js, Python, etc.) - see usage guide.

Core API steps

Link to this section

1. Check if the user already exists

Link to this section

Before creating a user, check whether they already exist in Kinde to avoid duplicates.

Terminal window
GET https://your-kinde-domain.kinde.com/api/v1/users?email={user_email}
Authorization: Bearer {access_token}
  • If the response returns a user, skip creation and go to Step 3 to update their password if needed.
  • If the response is empty, proceed to Step 2.

2. Create the user

Link to this section
Terminal window
POST https://your-kinde-domain.kinde.com/api/v1/user
Authorization: Bearer {access_token}
Content-Type: application/json
{
"profile": {
"given_name": "Lee",
"family_name": "Liu",
"email": "lliu@company.com"
},
"identities": [
{
"type": "email",
"details": {
"email": "lliu@company.com"
}
}
]
}

A successful response returns the new user’s Kinde ID (id). Save this for the next step.

3. Set the user’s password

Link to this section
Terminal window
PUT https://your-kinde-domain.kinde.com/api/v1/users/{user_id}/password
Authorization: Bearer {access_token}
Content-Type: application/json
{
"hashed_password": "$2a$10$examplehashvalue",
"hashing_method": "bcrypt",
"is_temporary_password": false
}

Supported hashing_method values: bcrypt, crypt, md5, sha256, wordpress, pbkdf2, firebase-scrypt, and aspnet-identity-v2. Each method requires different parameters — pbkdf2 needs a variant, and firebase-scrypt needs your project’s signer_key, salt_separator, rounds, and mem_cost. See the Set user password API reference for the full parameter rules.

If you have access to the user’s plaintext password at the time of login (because your app owns the login form), you can set it directly:

{
"password": "userPlaintextPassword",
"is_temporary_password": false
}

4. Force a password reset (optional)

Link to this section

If a user changed their password during the migration window and their hash in Kinde is out of date, prompt them to reset it:

Terminal window
PATCH https://your-kinde-domain.kinde.com/api/v1/users/{user_id}
Authorization: Bearer {access_token}
Content-Type: application/json
{
"is_password_reset_requested": true
}

The user will be prompted to set a new password on their next sign-in.

Handling the migration window

Link to this section

The typical pattern when running a migration window alongside live traffic:

  1. Before cutover — bulk import existing users from a CSV (see Bulk import).
  2. During the window — intercept sign-ups and sign-ins in your legacy system. For each:
    • Check if the user exists in Kinde (GET /api/v1/users?email=).
    • If not, create them (POST /api/v1/user) and set their password.
    • If they exist but their password may have changed, update the password (PUT /api/v1/users/{id}/password).
  3. After cutover — route all auth traffic to Kinde. Run a final re-import or re-sync to catch any users you missed.

Rate limits and batching

Link to this section

The Kinde Management API has rate limits. For large user bases:

  • Batch API calls and add delays between requests.
  • For bulk provisioning of thousands of users, prefer the CSV import method — it’s designed for volume.
  • Use the API approach for incremental syncing (new users, password changes) rather than full migrations.

For full API reference, see the Kinde Management API docs.