Authgear
Start BuildingHomePortalCommunity
  • Authgear Overview
  • Get Started
    • Start Building
    • 5-Minute Guide
    • Single-Page App
      • JavaScript (Web)
      • React
      • Angular
      • Vue
    • Native/Mobile App
      • iOS SDK
      • Android SDK
        • Android Kotlin coroutine support
        • Android OKHttp Interceptor Extension (Optional)
      • Flutter SDK
      • React Native SDK
      • Ionic SDK
      • Xamarin SDK
      • Using Authgear without SDK (Client side)
    • Regular Web App
      • Express
      • Next.js
      • Python Flask App
      • Java Spring Boot
      • ASP.NET Core MVC
      • Laravel
      • PHP
    • Backend/API Integration
      • Validate JWT in your application server
      • Forward Authentication to Authgear Resolver Endpoint
    • AI Coding tools
      • Cursor/Windsurf
  • How-To Guides
    • Authenticate
      • Add Passkeys Login
      • Add WhatsApp OTP Login
      • Add Email Magic Link Login
      • Add Biometric Login
      • Add Anonymous Users
      • Add authentication to any web page
      • Enable Two-Factor Authentication (2FA)
      • How to Use the OAuth 2.0 State Parameter
      • Reauthentication
      • How to Use Social/Enterprise Login Providers Without AuthUI
      • Passwordless Login for Apple App Store Review
      • Setup local development environment for Cookie-based authentication
      • Forgot/Reset Password settings
      • Phone number validation
      • Set Password Expiry
    • Single Sign-on
      • App2App Login
      • Pre-authenticated URLs
      • SSO between Mobile Apps / Websites
      • Force Authgear to Show Login Page
      • Single Sign-On with OIDC
      • Single Sign-On with SAML
        • Use Authgear as SAML Identity Provider for Salesforce
        • Use Authgear as SAML Identity Provider for Dropbox
        • SAML Attribute Mapping
    • Social Login / Enterprise Login Providers
      • Social Login Providers
        • Connect Apps to Apple
        • Connect Apps to Google
        • Connect Apps to Facebook
        • Connect Apps to GitHub
        • Connect Apps to LinkedIn
        • Connect Apps to WeChat
      • Enterprise Login Providers
        • Connect Apps to Azure Active Directory
        • Connect Apps to Microsoft AD FS
        • Connect Apps to Azure AD B2C
      • Force Social/Enterprise Login Providers to Show Login Screen
    • Built-in UI
      • Branding in Auth UI
      • User Settings
      • Privacy Policy & Terms of Service Links
      • Customer Support Link
      • Custom Text
    • Custom UI
      • Authentication Flow API
      • Implement Authentication Flow API using Express
      • Implement Authentication Flow API using PHP
      • Add Custom Login/Signup UI to Native Apps
      • Manually Link OAuth Provider using Account Management API
      • Implement a custom account recovery UI using Authentication Flow API
    • Integrate
      • Add custom fields to a JWT Access Token
      • User Analytics by Google Tag Manager
      • Track User Before and After Signup
      • Custom domain
      • Custom Email Provider
      • Custom SMS Provider
        • Twilio
        • Webhook/Custom Script
    • Monitor
      • Audit Log For Users Activities
      • Audit Log for Admin API and Portal
      • Analytics
    • User Management
      • Account Deletion
      • Import Users using User Import API
      • Export Users using the User Export API
      • Manage Users Roles and Groups
      • How to Handle Password While Creating Accounts for Users
    • User Profiles
      • What is User Profile
      • Access User Profiles
      • Update User Profiles
      • Profile Custom Attributes
      • Update user profile on sign-up using Hooks
    • Events and Hooks
      • Event List
      • Webhooks
      • JavaScript / TypeScript Hooks
      • Only Allow Signups from Inside the Corporate Network using Hooks
    • Mobile Apps
      • Use SDK to make authorized API calls to backend
      • Force authentication on app launch
      • Customize the Login Pop-up / Disable the login alert box
    • Languages and Localization
    • Custom Email and SMS Templates
    • Directly accessing Authgear Endpoint
    • Migration
      • Bulk migration
      • Rolling migration
      • Zero-downtime migration
    • Troubleshoot
      • How to Fix SubtleCrypto: digest() undefined Error in Authgear SDK
      • How to Fix CORS Error
  • Concepts
    • Identity Fundamentals
    • Authgear use cases
    • User, Identity and Authenticator
  • Security
    • Brute-force Protection
    • Bot Protection
    • Non-HTTP scheme redirect URI
    • Password Strength
  • Reference
    • APIs
      • Admin API
        • Authentication and Security
        • API Schema
        • Admin API Examples
        • Using global node IDs
        • Retrieving users using Admin API
        • User Management Examples
          • Search for users
          • Update user's standard attributes
          • Update user's picture
          • Generate OTP code
      • Authentication Flow API
      • OAuth 2.0 and OpenID Connect (OIDC)
        • UserInfo
        • Supported Scopes
      • User Import API
      • User Export API
    • Tokens
      • JWT Access Token
      • Refresh Token
    • Glossary
    • Billing FAQ
    • Rate Limits
      • Account Lockout
  • Client App SDKs
    • Javascript SDK Reference
    • iOS SDK Reference
    • Android SDK Reference
    • Flutter SDK Reference
    • Xamarin SDK Reference
  • Deploy on your Cloud
    • Running locally with Docker
    • Deploy with Helm chart
    • Authenticating HTTP request with Nginx
    • Configurations
      • Environment Variables
      • authgear.yaml
      • authgear.secrets.yaml
    • Reference Architecture Diagrams
      • Google Cloud Reference Architecture
      • Azure Reference Architecture
      • AWS Reference Architecture
      • Throughput Scaling Reference
Powered by GitBook
On this page
  • Endpoints
  • Initiate Import
  • Check Status
  • Update Behavior
  • Update Behavior of each field
  • Usage Example

Was this helpful?

Edit on GitHub
  1. Reference
  2. APIs

User Import API

API Reference for the User Import API that developers can use to bulk import users from another system to their Authgear project.

PreviousSupported ScopesNextUser Export API

Last updated 5 months ago

Was this helpful?

The User Import API is an API that supports the bulk import of users from another system to an Authgear project. This API is not part of the Admin API GraphQL. However, the API endpoints require the to access it.

The following are other important things to note about the User Import API:

  • The actual process of importing the users is asynchronous. This means execution is done in the background. The API provides an endpoint developers can use to query the status of the import.

  • Once an import is initiated successfully, the API will return an ID for the task. This ID is required to query the status of the import.

  • The body of HTTP requests to the API has a limit of 500KB.

  • Using the User Import API does not trigger the user.pre_create and user.created hooks.

  • The API supports the Bcrypt password format. To import passwords using this format specify the format type and password_hash in an object that will be the value of the user's password field. For example:

"password": {
        "type": "bcrypt",
        "password_hash": "$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy"
      },

Endpoints

The Import User API has two endpoints, one for initiating a user import task and the other for checking the status of the task. The endpoints only support secure HTTPS request and require a valid Admin API JWT token using Bearer authorization header (Authorization: Bearer <Admin API JWT Token>).

Here are more details about the endpoints and their expected inputs.

Initiate Import

POST /_api/admin/users/import

Use this endpoint to create a new user import task.

Headers

Name
Value

Content-Type

application/json

Authorization

Bearer <Admin API JWT Token>

Host

<Your Authgear Project Domain>

Body

The Initiate Import endpoint accepts JSON input via an HTTP(S) request body. The following is an example of the input:

{
    "identifier": "email",
    "records": [
        {
            "email": "user@example.com",
            "email_verified": true,
            "password": {
                "type": "bcrypt",
                "password_hash": "$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy"
            }
        }
    ]
}

Input Format

{
  "upsert": true,
  "identifier": "email",
  "records": [
    {
      "preferred_username": "jdoe",
      "email": "johndoe@example.com",
      "phone_number": "+85123456789",

      "email_verified": true,
      "phone_number_verified": true,

      "name": "John Doe",
      "given_name": "John",
      "family_name": "Doe",
      "middle_name": "",
      "nickname": "JD",
      "profile": "https://example.com",
      "picture": "https://example.com",
      "website": "https://example.com",
      "gender": "male",
      "birthdate": "1990-01-01",
      "zoneinfo": "Asia/Hong_Kong",
      "locale": "zh-Hant-HK",
      "address": {
        "formatted": "1 Unnamed Road, Central, Hong Kong Island, HK",
        "street_address": "1 Unnamed Road",
        "locality": "Central",
        "region": "Hong Kong",
        "postal_code": "N/A",
        "country": "HK"
      },

      "custom_attributes": {
        "member_id": "123456789"
      },

      "roles": ["role_a", "role_b"],
      "groups": ["group_a"],

      "disabled": false,

      "password": {
        "type": "bcrypt",
        "password_hash": "$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy"
      },

      "mfa": {
        "email": "johndoe@example.com",
        "phone_number": "+85123456789",
        "password": {
          "type": "bcrypt",
          "password_hash": "$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy"
        },
        "totp": {
          "secret": "secret"
        }
      }
    }
  ]
}

To understand the input better, let's take a close look at the three fields (upsert, identifier, records) that are directly on the root of the above JSON document.

  • identifier: This field is required. It tells Authgear what attribute to use to identify an existing user. The following strings are the accepted values: preferred_username, email, and phone_number.

  • records: This is where a developer can provide the data of all the users they wish to import in an array. Each direct object in the array represents a single user. Within the object, you can define the standard attributes for the user using the various fields as shown in the sample above. You may also define custom attributes in an object nested inside the custom_attributes field as also shown above.

Response

{
  "id": "task_4WZ0V7EPT4GZ2ABVN03QXYZ122W835C1",
  "created_at": "2024-04-04T06:56:36.02508096Z",
  "status": "pending"
}
{
  "error": "Invalid request"
}

id: this is the unique ID for the import task that was created. The ID is required to check the status of the task.

status: the value for status is pending after the import task is created and completed once the user import task is finished.

Check Status

GET /_api/admin/users/import/{ID}

Use this endpoint to query the status of an existing user import task. Replace {ID} with a valid ID for a user import task.

Headers

Name
Value

Authorization

Bearer <Admin API JWT Token>

Host

<Your Authgear Project Domain>

Response

{
  "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."
        }
      ]
    }
  ]
}
{
  "error": "Invalid request"
}

Update Behavior

The update behavior for an attribute determines how Authgear will treat that attribute when an existing user has the same value for the specified identifier type. For example, if the identifier is "email", the update behavior for each attribute is how Authgear will treat the attribute if a user already exists with the same email address as the current user you're trying to import.

Each attribute can have one of the three different types of update behavior described below:

  • UPDATED_IF_PRESENT_AND_REMOVED_IF_NULL: An attribute with this update behavior will update the user's attribute to the new value if that new value is not null. If the new value is explicitly null, the attribute will be deleted for the user. And if the attribute is absent, no operation is done.

  • UPDATED_IF_PRESENT: When this is the update behavior of an attribute, it will be updated if it is present. If the attribute is not present, no operation is done.

  • IGNORED: If a user exists already, the new value of this attribute is ignored. If the attribute is absent, nothing is done.

Update Behavior of each field

The following table shows all attributes and their update behavior for reference purposes:

Item
Update Behavior
Description

preferred_username, email, phone_number

UPDATED_IF_PRESENT_AND_REMOVED_IF_NULL

If it is not identifier, then the update behavior applies. The corresponding Login ID will be created, updated or removed as needed.

email_verified, phone_number_verified

UPDATED_IF_PRESENT

For example, in the first import, if email_verified is absent, then email is marked as unverified.

All other standard attributes

UPDATED_IF_PRESENT_AND_REMOVED_IF_NULL

In particular, address IS NOT merged with the existing value, but REPLACES the existing address value.

custom_attributes.*

UPDATED_IF_PRESENT_AND_REMOVED_IF_NULL

For each attribute in custom_attributes, the update behavior applies individually. So an absent custom attribute in an upsert does not change the existing value.

roles, groups

UPDATED_IF_PRESENT

If present, the roles and groups of the user will match the value. For example, supposed the user originally has ["role_a", "role_b"]. roles is ["role_a", "role_c"]. role_b is removed and role_c is added.

disabled

UPDATED_IF_PRESENT

Re-importing a record without specifying disabled WILL NOT accidentally alter the disabled state previously set by other means.

password

IGNORED

If it was not provided when the record was first imported, subsequent import CANNOT add it back.

mfa.email

UPDATED_IF_PRESENT_AND_REMOVED_IF_NULL

If provided, the user can perform 2FA with email OTP.

mfa.phone_number

UPDATED_IF_PRESENT_AND_REMOVED_IF_NULL

If provided, the user can perform 2FA with phone OTP.

mfa.password

IGNORED

If it was not provided when the record was first imported, subsequent import CANNOT add it back.

mfa.totp

IGNORED

If it was not provided when the record was first imported, subsequent import CANNOT add it back.

Usage Example

The following is a detailed guide with examples of using the User Import API to bulk import users and check the status of tasks.

The accepts JSON input via an HTTP request body. The following sample JSON document shows the expected structure and fields of the input:

upsert: This is an optional boolean that is false by default. When the value for this field is set to true and a user already exists with the same identity, the user's data is updated based on the for each attribute.

Admin API JWT token
endpoint that initiates an import
update behavior
Import Users using User Import API