Privy allows you to import your users in batches via REST API to simplify the migration process. To import users, pass in an array of user objects which each represent a new user. You can also create wallets during import with wallet pregeneration.

Once a user has been imported into Privy, if they log in, all of their imported accounts (wallet, email, etc.) will be included in their user object. If the imported user has an embedded wallet, that wallet will be available to the user upon sign in.

Make a POST request to:

https://auth.privy.io/api/v1/users/import

In the body of the request, include a users field with an array of up to 20 user objects.

Below is a sample cURL command for importing multiple new users into Privy:

$ curl --request POST https://auth.privy.io/api/v1/users/import \
-u "<your-privy-app-id>:<your-privy-app-secret>" \
-H "privy-app-id: <your-privy-app-id>" \
-H "Content-Type: application/json" \
-d '{
   "users": [
       {
           "linked_accounts": [
               {
                   "type": "email",
                   "address": "[email protected]"
               }
           ]
       },
       {
           "linked_accounts": [
               {
                   "type": "wallet",
                   "chain_type": "ethereum",
                   "address": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045"
               }
           ]
       },
       {
           "linked_accounts": [
               {
                   "type": "email",
                   "address": "[email protected]"
               }
           ]
       }
   ]
}'

Response Format

A successful response will include a list of results along with details about which imports succeeded and which failed:

{
  "results": [
    {
      "action": "create",
      "index": 0,
      "success": true,
      "id": "did:privy:clfn2wysq01ijykc8gyq2j2t1"
    },
    {
      "action": "create",
      "index": 1,
      "success": false,
      "code": 101,
      "error": "Account conflict caused by an existing user. Multiple users cannot share the same account.",
      "cause": "did:privy:clfmxole300rmykc89nojp3v2"
    },
    {
      "action": "create",
      "index": 2,
      "success": true,
      "id": "did:privy:clfn2wysq01ijykc8gyq2j2t3"
    }
  ]
}

Each result in the response includes:

action
string

The action taken (“create”).

index
number

The index of the user in the request array.

success
boolean

Whether the import succeeded.

id
string

The Privy DID of the created user (if successful).

code
number

Error code (if unsuccessful).

error
string

Error message (if unsuccessful).

cause
string

The conflicting DID (if there was an account conflict).

User import endpoints have a rate limit of 240 users per minute. If you are being rate limited, responses will have status code 429. We suggest you set up exponential back-offs starting at 1 second to seamlessly recover.

Was this page helpful?