> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate your users

> Preview and import Authentication identities with stable external IDs, supported password hashes and explicit reset handling.

<Warning>
  The current early-access import accepts bounded batches. Additional password formats, linked sign-in accounts, MFA secrets and asynchronous migration jobs are release-dependent. Test an import in your sandbox application before moving live users.
</Warning>

## Prepare a migration

Export only the fields you need from your existing identity system. Choose an immutable `external_id` for every person and preserve your own mapping to [vendor\_data](/entities/vendor-data-linking). Check conflicts before importing. Never use an email match alone as proof that two identities belong to the same person.

The current endpoint is `POST /auth/v2/organizations/{org_id}/applications/{application_id}/authentication/imports/` on your configured authentication origin. It requires a console access token with `write:authentication`, not an end-user token or verification API key.

## Preview first

Send the following JSON with `Content-Type: application/json` and `Authorization: Bearer <console_access_token>`. Replace the example identifier and reserved email with your test user's values. Omit `password_hash` to require password reset.

```json theme={null}
{
  "rows": [
    {
      "external_id": "example-user",
      "email": "user@example.com",
      "email_verified": false,
      "display_name": "Example user"
    }
  ],
  "dry_run": true,
  "idempotency_key": "example-import-batch-1"
}
```

Preview performs no writes and reports `ready`, `skipped`, `reset_required` and `errors`. Resolve every conflict before committing. A batch accepts 1 to 1,000 identities. `external_id` and `email` are required; `email_verified` defaults to false and must reflect proof you actually hold.

## Commit and reconcile

Send the same identities and `idempotency_key` with `dry_run: false`. A successful first commit returns `201`; repeating an identical committed batch returns its recorded result. Changing the identities under an existing key fails. Conflicts reject the batch without partial import.

Use `GET imports/` with `read:authentication` to inspect prior committed batch results. Keep a private migration ledger of each key, input digest and outcome. Do not log passwords or hashes. After an uncertain response, retry the identical batch with the same key rather than creating a second import.

## Passwords and linked credentials

The current runtime accepts bounded password encodings for `pbkdf2_sha256` and `scrypt`. Unsupported or omitted hashes require a password reset; inspect `reset_required` before cutover. A hash algorithm name alone does not establish encoding compatibility.

The expanded migration contract is planned to add more hash formats, linked social accounts, authenticator secrets, organization roles and larger asynchronous CSV/JSON jobs. Those formats are not accepted by this endpoint today. Existing passkeys remain tied to their original relying-party domain and need a separate enrollment plan.

Before cutover, test sign-in with each supported imported hash, reset for an unsupported hash, duplicate batch retries, conflicting identities and application isolation. Verify [session handling](/authentication/tokens-and-jwks) and the shared person mapping before turning off your previous login flow.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.