Import users from Clerk or other providers and set up migration journeys.
User Import & Migration
Import users from your existing auth provider into AscendKit. Currently supports Clerk.
Prerequisites
- Initialize the CLI and link your environment with
ascendkit set-env - Have your Clerk secret API key ready (found in Clerk Dashboard → API Keys)
Import workflow
1. Preview settings (dry run)
See what auth methods are detected from your Clerk users without making changes:
ascendkit import clerk preview --api-key sk_live_... --settings
This fetches all users from Clerk, analyzes their auth methods, and shows what providers would be enabled (credentials, Google, LinkedIn, etc.).
2. Preview users (dry run)
Preview the full import — users and settings:
ascendkit import clerk preview --api-key sk_live_...
By default, the import runs in dry-run mode. It shows how many users would be imported, how many are duplicates, and what auth settings would be applied.
3. Execute the import
When you're satisfied with the preview:
ascendkit import clerk run --api-key sk_live_...
This imports users, creates OAuth account links, updates auth settings, and emits lifecycle events.
4. Create migration journeys
Set up email templates and draft journeys for notifying your users:
ascendkit import migration-journey create
This creates:
- 5 email templates: announcement, go-live, reminder, password reset, and password reset reminder
- 2 draft journeys:
- Announcement cadence (all users): Day 0 announcement → Day 3 go-live → Day 7 reminder
- Password reset cadence (credential users only): Day 1 password reset → Day 4 reminder
Journeys are created in draft status. Review and customize the templates before activating.
5. Review and customize
ascendkit template list
ascendkit journey list
ascendkit journey show <journey-id>
Edit templates in the portal to match your brand. Update journey node variables (e.g., loginUrl, resetUrl) to point to your app.
6. Activate journeys
ascendkit journey activate <journey-id>
Migration journeys automatically backfill enrollment for previously imported users when activated. You don't need to re-import or re-emit events — all imported users are enrolled at activation time.
Command reference
ascendkit import clerk preview|run
ascendkit import clerk preview --api-key <key> [options]
ascendkit import clerk preview --file <path> [options]
ascendkit import clerk run --api-key <key> [options]
ascendkit import clerk run --file <path> [options]
| Flag | Description |
|---|---|
--api-key <key> | Clerk secret API key (fetches users from Clerk API) |
--file <path> | Path to Clerk JSON export (alternative to API) |
--users | Import only users (skip auth settings) |
--settings | Import only auth settings (skip users) |
--providers <list> | Override SSO providers, comma-separated (e.g., --providers linkedin) |
--from-identity <email> | Sender email for migration journey emails |
Use preview for dry-run mode and run to apply changes. By default, both users and settings are imported. Pass --users or --settings alone to run only that phase.
ascendkit import migration-journey create
ascendkit import migration-journey create [--from-identity <email>]
Creates migration templates and journeys in draft status. Pass --from-identity to set the sender email on all journey email nodes.
What gets imported
Users
| Source (Clerk) | Destination (AscendKit) |
|---|---|
id | metadata.import.sourceId |
email_addresses[0] | email |
first_name + last_name | name |
image_url | image |
email_addresses[].verification.status | emailVerified |
password_enabled | Tag: import:needs-password-reset |
external_accounts | OAuth account links |
created_at | createdAt (original signup date preserved) |
last_sign_in_at | lastLoginAt |
public_metadata | metadata |
Auth settings
Providers are detected from user data:
- Users with
password_enabled: true→ enablescredentials - Users with linked
external_accounts→ enables corresponding OAuth providers (google, linkedin, github, etc.)
Use --providers to override which SSO providers are enabled if some are no longer active in Clerk.
Tags
Imported users are tagged for segmentation:
| Tag | Meaning |
|---|---|
import:clerk | Imported from Clerk |
import:needs-password-reset | Had a password in Clerk, needs to set a new one |
import:social-only | Only used OAuth login (no password) |
Events
The import emits events that power journeys and analytics:
| Event | When | Payload |
|---|---|---|
user.imported | Each user imported | source, sourceId, hadPassword, hasOAuth |
user.login | Users with prior login activity | synthetic: true, originalLoginAt |
The user.login event is synthetic — it preserves the user's last login timestamp from Clerk so existing journeys that trigger on login events work correctly.
Migration journey details
Announcement cadence (all imported users)
| Timing | Template | Purpose |
|---|---|---|
| Day 0 | migration-announcement | "We're moving to a new platform" |
| Day 3 | migration-go-live | "Migration is live — try logging in" |
| Day 7 | migration-reminder | "Have you logged in yet?" |
Password reset cadence (credential users only)
| Timing | Template | Purpose |
|---|---|---|
| Day 1 | migration-password-reset | "Set your new password" |
| Day 4 | migration-password-reset-reminder | "Reminder: set your password" |
Social-only users receive only the announcement cadence — their OAuth login carries over automatically.
Importing from a file
If you prefer to export from Clerk's dashboard instead of using the API:
ascendkit import clerk run --file ./clerk-export.json
The file should be a JSON array of Clerk user objects or an object with a users key.