Export your users
Take your users with you: ids, emails, linked logins, organisations and roles, and their password hashes if you want them, as a file Anchr.ing or Auth0 imports. No lock-in.
- You get
- A file with your users, their logins, organisations and roles that Anchr.ing or Auth0 imports.
- For
- Ops
- Time
- About 10 min
- Products
- Sign-inOrganisations and roles
Your users are yours. Export them any time, from the dashboard or your backend, as a file you can import again here or at another provider. Their ids stay the same, so the sub your app stores keeps working.
1. Make an export
In the dashboard, pick the environment, then Users → Export. Choose a format and what to include, then Export users. You confirm your sign-in with your second factor first. A project with up to 1,000 users is ready at once; a larger one is prepared in the background and shows up under Recent exports a few minutes later. Each file can be downloaded for 24 hours, then it is deleted. You can delete it sooner.
The project owner can always export. Give other members the User export permission on the project's Members list. Every export and download is in the audit log.
2. What is in the file
For every user: the id, email and whether it is verified, name, picture, metadata, status (active or disabled), when they joined and last signed in, their linked social logins (provider and subject), their passkeys (credential id and public key), their organisations and roles, and their consent records. The Anchr.ing formats also carry the organisations and your custom organisation roles.
Password hashes are included only when you tick them. They are as stored: argon2id, or the format a user was imported in (bcrypt, PBKDF2, Firebase scrypt) until they sign in once. Anyone with the file can try to crack them offline, so every owner of the project gets an email when hashes are exported.
TOTP secrets (authenticator apps) are off by default. Only the owner can include them, after a warning: the file then holds your users' second factors in plain text. Recovery codes are never exported. Passkeys only work on the domain they were registered on, so another provider on another domain can't use them: your users add a new one there.
3. Pick a format
Anchr.ing JSON is one document that Users → Import reads back, here or in another project:
{
"format": "anchring.users/1", "project": "acme", "environment": "prod", "passwords": true, "totp_secrets": false,
"orgs": [{ "slug": "globex", "name": "Globex" }],
"org_roles": [{ "name": "auditor", "permissions": ["report:read"] }],
"users": [{
"id": "k3x9…", "email": "ada@acme.example", "email_verified": true, "name": "Ada", "status": "active",
"metadata": { "plan": "pro" }, "created_at": "2026-01-04T09:12:00Z", "last_login": "2026-10-29T17:40:00Z",
"password_hash": "$argon2id$v=19$m=65536,t=3,p=4$…",
"identities": [{ "preset": "google", "connection_name": "Google", "subject": "1078…" }],
"passkeys": [{ "credential_id": "…", "public_key": "…", "name": "MacBook" }],
"orgs": [{ "slug": "globex", "role": "auditor" }],
"consents": [], "mfa": { "totp": [{ "name": "Authenticator app" }] }
}]
}Anchr.ing NDJSON is the same as JSON Lines: a header line, then one user per line, for large projects and tools that read line by line. The import reads it too.
Auth0 bulk import is Auth0's user import file: hashes as custom_password_hash (argon2, bcrypt and PBKDF2), disabled users as blocked, metadata as user_metadata, and the Anchr.ing id, organisations and logins in app_metadata.anchring. Users without an email are left out, because Auth0's database users need one. Auth0 takes files of up to 500 KB per import job, so split a larger file.
4. From your backend
A server key with the users:export scope exports without password hashes or TOTP secrets: those always need a person in the dashboard. It's useful for scheduled backups of your user list:
import { createAdminClient } from '@anchring/auth/admin';
const admin = createAdminClient(); // ANCHRING_PROJECT, ANCHRING_SERVER_KEY (scope users:export)
let e = await admin.users.exports.create({ format: 'anchring-ndjson' });
while (e.status === 'queued' || e.status === 'running') {
await new Promise((r) => setTimeout(r, 5000));
e = await admin.users.exports.get(e.id);
}
if (e.status !== 'ready') throw new Error('the export failed');
await Bun.write('users.ndjson', await admin.users.exports.download(e.id));Every option, error and token type: the SDK README.