Import Users using User Import API¶
Some ways to add users to your Authany project include; using the Add User UI in Authany Portal, using the createUser() mutation in Admin API, and last but not least, having the user accounts created using sign-up page on AuthUI.
A common downside of all the above-listed methods is that they do not support batch import of users. Meaning, that you have to add users one by one. This isn't ideal for importing multiple users from existing legacy systems to Authany. For adding bulk users, there is the User Import API.
In this post, you'll learn what the User Import API is and see examples of how to import bulk users to an Authany project.
User Import API¶
The User Import API is an API that supports the bulk import of users from another system to an Authany project. This API is not part of the Admin API GraphQL. However, a valid Admin API JWT token is required to access the endpoints of the User Import API.
Endpoints¶
The following are the endpoints for the User Import API.
Initiate Import¶
Use this endpoint to start a new user import task.
POST - /_api/admin/users/import
HTTP/1.1
Host: <Your Authgear Project domain>
Authorization: Bearer <Admin API JWT Token>
Content-type: application/json
Body: {
"identifier": "email",
"records": [
{
"email": "user@example.com",
"email_verified": true,
"password": {
"type": "bcrypt",
"password_hash": "$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy"
}
}
]
}
Check Status¶
Use this endpoint to verify the status of an existing user import task.
GET - /_api/admin/users/import/{ID}
HTTP/1.1
Host: <Your Authgear Project domain>
Authorization: Bearer <Admin API JWT Token>
Note
To learn more detailed information about the User Import API (such as endpoints, inputs, and responses), see the User Import API Reference.
Usage Example¶
In this section, you can find code for a simple example of using the User Import API to add multiple users to an Authany project.
Prerequisites¶
To follow this example and be able to run the code on your local machine, you must have the following:
- An Authany account. Sign up for free here.
- Node.js installation on your local computer.
- Install Express.js by running the following command from your project directory:
npm install express.
Step 1: Get Admin API JWT¶
As mentioned earlier in this post, the User Import API requires the Admin API JWT to access. In this step, we'll generate an Admin API JWT using Node.js.
First, install JsonWebToken (a Node package for generating JWT) by running the following command:
The following code shows how to get the token:
function generateJWT() {
const project_id = ""; //Your authgear app id
const key_id = ""; //you authgear key ID
const expiresAt = Math.floor(Date.now() / 1000) + (60 * 60); //the current value means token will expire in 1 hour.
//Payload to include in JWT
const claims = {
aud: project_id,
iat: Math.floor(Date.now() / 1000) - 30,
exp: expiresAt
}
const privateKey = fs.readFileSync("key.pem"); //Read value from the downloaded key file
const header = { "typ": "JWT", "kid": key_id, "alg": "RS256" }
const jwt = node_jwt.sign(claims, privateKey, { header: header });
return jwt;
}
See our post on Admin API Authentication for a more detailed guide (and examples for other programming languages/frameworks) on how to get your key ID, and private key and generate Admin API JWT.
Step 2: Import Users from a JSON Document¶
To import users to your Authany project using the User Import API, make a POST HTTP(S) request to the Initiate Import endpoint (/_api/admin/users/import).
The user data you wish to import must be provided as a JSON input in the HTTP(S) request body as specified in the API input format.
In the following steps, we'll use the node-fetch package to make HTTP requests to the User Import API. Hence, install node-fetch by running the following command:
The following code sample demonstrates how to import 2 users from a JSON document that's stored in a simple constant (const data):
const express = require("express");
const node_jwt = require('jsonwebtoken');
const fs = require('fs');
const fetch = require('node-fetch');
const app = express();
const port = 3002;
//TODO Place declaration of generateJWT() function here
app.get('/', (request, response) => {
const jwt = generateJWT();
const data = {
"identifier": "email",
"records": [
{
"email": "user1@example.com",
"email_verified": true,
"password": {
"type": "bcrypt",
"password_hash": "$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy"
}
},
{
"email": "user2@example.com",
"email_verified": false,
"name": "John Doe",
"given_name": "John",
"family_name": "Doe",
"password": {
"type": "bcrypt",
"password_hash": "$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy"
}
}
]
}
const options = {
method: 'POST',
headers: { 'Content-type': 'application/json', 'Authorization': 'Bearer ' + jwt },
body: JSON.stringify(data)
};
const appUrl = 'https://your-project.authanyid.com'; // replace wuth your authgear project url
fetch(`${appUrl}/_api/admin/users/import`, options)
.then(result => result.json())
.then(result => console.log(JSON.stringify(result)));
response.send("Request sent using the follow JWT as Bearer: " + jwt + "See console for result");
});
app.listen(port, () => {
console.log("server started! PORT: " + port);
});
If the user import was initiated successfully, you'll get a response that looks like this:
{
"id": "task_4WZ0V7EPT4GZ2ABVN03QXYZ122W835C1",
"created_at": "2024-04-04T06:56:36.02508096Z",
"status": "pending"
}
In the next step, we'll use the value of the id field from the above response to query the status of the import task.
Step 3: Get the Status of the Import Task¶
In this step, we'll make a GET HTTP(S) request to the Check Status endpoint (/_api/admin/users/import/{ID}) to get the status of the user import task we initiated in the last step. You'll need to replace {ID} in the URL with the value of id in the previous response.
To do this, add a new route to the Express app that accepts the task id as a parameter and uses that id to query the status of the task. Here's the code for the route:
app.get("/status/:id", (request, response) => {
const jwt = generateJWT()
const options = {
method: 'GET',
headers: { 'Content-type': 'application/json', 'Authorization': 'Bearer ' + jwt }
};
const appUrl = 'https://your-project.authanyid.com';
fetch(`${appUrl}/_api/admin/users/import/${request.params.id}`, options)
.then(result => result.json())
.then(result => console.log(JSON.stringify(result)));
response.send("Request sent using the follow JWT as Bearer: " + jwt + "See console for result");
});
The response to the request to query the status of the import task will look like this:
{
"id": "task_4WZ0V7EPT4GZ2ABVN03QXYZ122W835C1",
"created_at": "2024-04-04T06:56:36.02508096Z",
"status": "completed",
"summary": {
"total": 2,
"inserted": 2,
"updated": 0,
"skipped": 0,
"failed": 0
},
"details": [
{
"index": 0,
"record": {
"email": "user1@example.com",
"email_verified": true,
"password": {
"password_hash": "REDACTED",
"type": "bcrypt"
}
},
"outcome": "inserted",
"user_id": "0f0f65ee-4c7d-45a0-a740-bcbbfd3fcf06"
},
{
"index": 1,
"record": {
"email": "user2@example.com",
"email_verified": false,
"family_name": "Doe",
"given_name": "John",
"name": "John Doe",
"password": {
"password_hash": "REDACTED",
"type": "bcrypt"
}
},
"outcome": "inserted",
"user_id": "9c71fc29-6db6-4a18-aa73-774139fed16d",
"warnings": [
{
"message": "email_verified = false has no effect in insert."
}
]
}
]
}
From the response, you can see the status of the entire task (import was completed), including a summary ( { "total": 2, "inserted": 2, "updated": 0, "skipped": 0, "failed": 0 } ).
The details field contains an array of details such as the outcome for each user in the original JSON document.