Create a user: Migration guide
This guide outlines the changes introduced in the Create an invited user v2 endpoint (previously known as createOrInviteUser in v1).
Key changes
- Invitation email: The v2 endpoint creates a new user in an invited state and immediately sends them an invitation email to them. There is currently no option to suppress this email via the API v2.
- If you prefer to disable emails entirely (not just invitations), contact us to have all email notifications deactivated for your entire organization.
- Security enhancement: v2 removes the ability to send user credentials (passwords) directly via email. This is a deliberate security enhancement. If you set a user's password programmatically (via the separate Replace the password of a user endpoint), you must find a secure alternative way to communicate it to the user, as the API v2 will not send emails containing credentials.
- Single initial group membership: In v1, you could add users to multiple groups in a single call. This v2 endpoint allows you to add a user to only one group at the time of creation via the
membershipobject. To add a user to additional groups after creation, use the dedicated Add a user's role v2 endpoint.- Multi-step process to activate users: After initial creation in an invited state, achieving a user in an active state, especially one with a pre-set password, now requires multiple steps.
For details on these key changes, refer to the Behavior changes section below.
Documentation links
Here are the links to the API reference for:
Endpoint mapping
Here's the direct correlation between the v1 and v2 endpoint URLs:
- API v1:
/api/v1/users - API v2:
/api/v2/users
Behavior changes
Creating invited users
The main and crucial behavioral change is that the v2 endpoint always creates an invited user and immediately sendsan invitation email to them.
What is an invited user?An invited user is an account that exists in the system but is not yet fully active. This means:
- The user cannot log in or access the platform yet.
- They are non-billable until activated.
- They receive an invitation email with a link to activate their account and set their password.
- Their account requires activation to become fully active, billable, and enable login. Activation can occur:
- Via email: The user clicks the link in the invitation email.
- Programmatically: By calling the Activate a user endpoint.
Important: You can no longer create a fully active user via a single API call, and the user not receiving an invitation email. The Create an invited user call will create the user in the invited state and, by default, send an invitation email.
If your organization has asked us to disable all email notifications, the user will still be created in an invited state, but no email will be sent.
Handling deleted users
If a user already exists with the same email in a deleted state, calling the Create an invited user v2 endpoint will restore them:
- They will receive a new invitation email.
- Their account will enter the invited state.
- Their account also requires activation to become fully active, billable, and enable login.
Initial group assignment
Unlike API v1, where createOrInviteUser allowed assigning a user to multiple groups in a single call, API v2 now only supports assigning a user to a single initial group using the membership object.
To add a user to additional groups after creation, use the separate Add a user's role endpoint.
Achieving v1 outcomes in v2
Achieving certain user states that were previously possible in a single API v1 call may now require a sequence of API v2 calls.
Here's how different API v1 createOrInviteUser outcomes map to API v2 workflows:
API v1
scenario | API v1 outcome and notification | API v2 workflow |
|---|---|---|
|
| Call Create an invited user. |
|
|
You can, however, create and activate a user who will receive an invitation email (no password) with the following steps:
|
|
|
You can, however, create and activate a user with the following steps:
|
|
|
You can, however, create and activate a user who will receive an invitation email (no password) with the following steps:
|
Input changes
This section details the specific alterations to the input requirements between API versions.
API v1 input example
curl --location -g 'https://app.360learning.com/api/v1/users?company={{company}}&apiKey={{apiKey}}' \
--data-urlencode '[email protected]' \
--data-urlencode 'firstName=Paul' \
--data-urlencode 'lastName=Durand' \
--data-urlencode 'phone=0123456789' \
--data-urlencode 'lang=fr' \
--data-urlencode 'job=Tester' \
--data-urlencode 'roles%5B0%5D=learner' \
--data-urlencode 'organization=Org.' \
--data-urlencode 'custom=AZE12345' \
--data-urlencode 'groups%5B0%5D=5694ea540fa69fdd0ec0004f' \
--data-urlencode 'groups%5B1%5D=5ae6f128331332775cfb14be' \
--data-urlencode 'primaryGroupId=5694ea540fa69fdd0ec0004f'API v2 input example
curl --request POST \
--url https://app.360learning.com/api/v2/users \
--header '360-api-version: v2.0' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'authorization: Bearer access_token' \
--data '
{
"membership": {
"role": "learner",
"groupId": "507f1f77bcf86cd799439011"
},
"mail": "[email protected]",
"username": "johnsmith",
"custom": "Half-time worker",
"firstName": "John",
"lastName": "Smith",
"job": "Boss",
"lang": "en",
"organization": "360Learning",
"phone": "+33123456789"
}
'Main input differences
Change type | API v1 | API v2 |
|---|---|---|
Removed |
| This parameter is removed from v2. |
Removed |
| This parameter is removed from v2. |
Removed |
| Now handled by the separate Replace the password of a user endpoint. |
Modified |
|
|
Output changes
The output has completely changed to follow RESTful principles. Instead of returning an acknowledgment of the user creation, we now return the created user object.
API v1 output example
{
"status": "user_created",
"_id": "5be2b954b44a1b6e3526e091"
}API v2 output example
{
"_id": "5be2b954b44a1b6e3526e091",
"mail": "[email protected]",
"username": "johnsmith",
"deleted": true,
"lang": "bg",
"firstName": "John",
"lastName": "Smith",
"job": "Engineer",
"organization": "360Learning",
"phone": "+33123456789",
"custom": "Half-time worker",
"deletedAt": [
"2025-06-06T13:21:38.271Z"
],
"reactivatedAt": [
"2025-06-06T13:21:38.271Z"
],
"lastLoginDate": "2025-06-06T13:21:38.271Z",
"toBeDeactivatedAt": "2025-06-06T13:21:38.271Z"
}Main output differences
As shown in the example above, the response is completely different, so please refer to the Retrieve a user: Migration guide for more information.
Change type | API v1 | API v2 |
|---|---|---|
Removed |
| |
Removed |
| |
Removed |
| |
Removed |
| |
Removed |
| |
Removed |
| |
Removed |
| |
Removed |
| |
Removed |
| |
Added |
| |
Added |
| |
Added |
| |
Added |
| |
Added |
| |
Added |
| |
Added |
| |
Added |
| |
Added |
|
Updated 7 days ago
