user_metadata and app_metadata in user profiles using a variety of methods depending on your use case.
- Management API
post-loginAction- Lock
- Rules
When you create a new user with the Management API’s Create a User endpoint (
You can set or update an existing user’s metadata with the Update a User endpoint (
When you update an existing user’s metadata, only properties at the root level are merged into the object. All lower-level properties will be replaced.
To delete a metadata key, make a
POST /users), you can set the new user’s metadata by specifying the body parameters for user_metadata and app_metadata.Example: create new user with metadata
Example: create new user with metadata
To create a user with the following profile details:Make the following
{
"email": "jane.doe@example.com",
"user_metadata": {
"hobby": "surfing"
},
"app_metadata": {
"plan": "full"
}
}
POST call to the /post_users endpoint to create the user and set the property values:Using the Auth0 CLI? If you haven’t already, set up and authenticate your CLI session before running this command.
PATCH /users/{id}) by similarly specifying the body parameters for user_metadata and app_metadta.Example: update an existing user's metadata
Example: update an existing user's metadata
Assuming you created a user with the following metadata values:To update You would make the following
{
"email": "jane.doe@example.com",
"user_metadata": {
"hobby": "surfing"
},
"app_metadata": {
"plan": "full"
}
}
user_metadata and add the user’s home address as a second-level property:{
"addresses": {
"home": "123 Main Street, Anytown, ST 12345"
}
}
PATCH call:The user’s profile will now appear as follows:{
"email": "jane.doe@example.com",
"user_metadata": {
"hobby": "surfing",
"addresses": {
"home": "123 Main Street, Anytown, ST 12345"
}
},
"app_metadata": {
"plan": "full"
}
}
Example: update metadata sub-properties
Example: update metadata sub-properties
For example, to add a user’s work address as an additional inner property, you would have to include the complete contents of the Therefore, the corresponding
addresses property. Since the addresses object is a root-level property, it will be merged into the final JSON object representing the user, but its sub-properties will not.{
"user_metadata": {
"addresses": {
"home": "123 Main Street, Anytown, ST 12345",
"work": "100 Industrial Way, Anytown, ST 12345"
}
}
}
PATCH call to the API would be:PATCH call and set the metadata key’s value to null (for example, { "user_metadata": {"color": null}}).To delete user or app metadata entirely, make a PATCH call and set the metadata itself to an empty object (for example, { "user_metadata": {} }).You can configure a Here, we added a check at the start of the Action to see if we have already performed the expensive task for this user. If the metadata field exists, then we return from the function.At the end of the Action, we call In the event of a Redirect invoked with
post-login trigger to modify user_metadata and app_metadata as part of a user’s login flow.Post-login triggers are useful for tasks such as storing application-specific data on the user profile, capturing user operation logs, mapping attributes to the metadata field, or caching expensive operation values on the User profile for re-used in future logins.The post-login api object provides common operations that can be performed in this trigger. To manage user metadata, we want to use the api.user.setAppMetadata and api.user.setUserMetadata methods. For example, to guard against some behavior running more than once for a specific user, consider an Action that looks like this:exports.onExecutePostLogin = async (event, api) => {
if (event.user.app_metadata.didAnExpensiveTask) {
console.log(`Skipping the expensive task because it already occurred for ${event.user.email}.`);
return;
}
// do and expensive task
api.user.setAppMetadata("didAnExpensiveTask", true);
};
api.user.setAppMetadata to signal that we would like to store some metadata on the user object. At the end of each trigger’s execution, Actions will update the user profile as a single operation. If several calls are made to setUserMetadata actions, even if they are made in different actions as part of the same flow, Actions will only update the user profile a single time—at the end of the trigger’s execution.Multiple
setUserMetadata or setAppMetadata calls will be batched together into a single user profile update at the end of the trigger’s execution, even if they are made by different Actions.api.redirect.sendUserTo(), any pending user or app metadata updates will be applied to the user profile before the user is redirected to the external site.You can use the Lock library to define, add, read, and update the You can use
user_metadata. You can read the user’s user_metadata properties the same way you would read any other user profile property. For example, the following code snippet retrieves the value associated with user_metadata.hobby and assigns it to an element on the page:// Use the accessToken acquired upon authentication to call getUserInfo
lock.getUserInfo(accessToken, function(error, profile) {
if (!error) {
document.getElementById('hobby').textContent = profile.user_metadata.hobby;
}
});
additionalSignUpFields to add custom fields to user sign-up forms. When a user adds data in a custom field, Auth0 stores entered values in that user’s user_metadata. To learn more about adding user_metadata on signup, read Additional Signup Fields.The End of Life (EOL) date of Rules and Hooks will be November 18, 2026, and they are no longer available to new tenants created as of October 16, 2023. Existing tenants with active Hooks will retain Hooks product access through end of life.We highly recommend that you use Actions to extend Auth0. With Actions, you have access to rich type information, inline documentation, and public
npm packages, and can connect external integrations that enhance your overall extensibility experience. To learn more about what Actions offer, read Understand How Auth0 Actions Work.To help with your migration, we offer guides that will help you migrate from Rules to Actions and migrate from Hooks to Actions. We also have a dedicated Move to Actions page that highlights feature comparisons, an Actions demo, and other resources to help you on your migration journey.To read more about the Rules and Hooks deprecation, read our blog post: Preparing for Rules and Hooks End of Life.{
"user_id": "jdoe",
"email": "john.doe@example.com",
"app_metadata": {
"roles": [ "writer" ]
},
"user_metadata": {
"preferences": {
"color": "blue"
}
}
}
Read metadata
You can read metadata using rules with the . You can also search for profile-related information inuser_metadata, such as:namenicknamegiven_namefamily_name
jane.doe@example.com:{
"email": "jane.doe@example.com",
"user_metadata": {
"hobby": "surfing"
},
"app_metadata": {
"plan": "full"
}
}
console.log(user.email); // "jane.doe@example.com"
console.log(user.user_metadata.hobby); // "surfing"
console.log(user.app_metadata.plan); // "full"
user.app_metadata is Undefined by default.Example: conditional on metadata
Example: conditional on metadata
You can make a decision based on the user’s roles:You can base decisions on specific preferences, such as a color preference:
function(user, context, callback){
user.app_metadata = user.app_metadata || {};
if (user.app_metadata.roles.indexOf('writer')){
// code to be executed
}
}
function(user, context, callback){
user.user_metadata = user.user_metadata || {};
if (user.user_metadata.preferences.color === 'black'){
// code to be executed
}
...
}
Read application metadata (clientMetadata)
Application metadata (clientMetadata) is an optional, top-level property of the context object. Existing applications will have no value for this property.function(user, context, callback){
context.clientMetadata = context.clientMetadata || {};
if (context.clientMetadata.usersuppliedkey1 === 'black'){
// this code would not be executed for the user
}
...
}
Update metadata
You can use Rules to map SAML attributes that Auth0 receives from the IdP intouser_metadata or app_metadata.Update app metadata
To add an administrative role to the user:function(user, context, callback){
user.app_metadata = user.app_metadata || {};
// update the app_metadata that will be part of the response
user.app_metadata.roles = user.app_metadata.roles || [];
user.app_metadata.roles.push('administrator');
// persist the app_metadata update
auth0.users.updateAppMetadata(user.user_id, user.app_metadata)
.then(function(){
callback(null, user, context);
})
.catch(function(err){
callback(err);
});
}
{
"user_id": "jdoe",
"email": "john.doe@example.com",
"app_metadata": {
"roles": [ "writer", "administrator" ]
},
"user_metadata": {
"preferences": {
"color": "blue"
}
}
}
Update user metadata
To add the user’sfontSize preference to the user profile:function(user, context, callback){
user.user_metadata = user.user_metadata || {};
// update the user_metadata that will be part of the response
user.user_metadata.preferences = user.user_metadata.preferences || {};
user.user_metadata.preferences.fontSize = 12;
// persist the user_metadata update
auth0.users.updateUserMetadata(user.user_id, user.user_metadata)
.then(function(){
callback(null, user, context);
})
.catch(function(err){
callback(err);
});
}
{
"user_id": "jdoe",
"email": "john.doe@example.com",
"app_metadata": {
"roles": [ "writer" ]
},
"user_metadata": {
"preferences": {
"color": "blue",
"fontSize": 12
}
}
}
Update app and user metadata simultaneously
To reduce the rule’s processing time, you may update both theapp_metadata and user_metadata in the same rule:function(user, context, callback){
var q = require('q');
user.app_metadata = user.app_metadata || {};
user.user_metadata = user.user_metadata || {};
// update the user_metadata that will be part of the response
user.user_metadata.preferences = user.user_metadata.preferences || {};
user.user_metadata.preferences.fontSize = 12;
// update the app_metadata that will be part of the response
user.app_metadata.roles = user.app_metadata.roles || [];
user.app_metadata.roles.push('admin');
// persist the app_metadata update
var appMetadataPromise = auth0.users.updateAppMetadata(user.user_id, user.app_metadata);
// persist the user_metadata update
var userMetadataPromise = auth0.users.updateUserMetadata(user.user_id, user.user_metadata);
// using q library to wait for all promises to complete
q.all([userMetadataPromise, appMetadataPromise])
.then(function(){
callback(null, user, context);
})
.catch(function(err){
callback(err);
});
}
{
"user_id": "jdoe",
"email": "john.doe@example.com",
"app_metadata": {
"roles": [ "writer", "admin" ]
},
"user_metadata": {
"preferences": {
"color": "blue",
"fontSize": 12
}
}
}
Delete metadata
Delete app metadata properties and values
To delete a property, set the property’s value tonull.Delete user’s roles example
To delete the user’s roles, use the following sample rule:function(user, context, callback){
user.app_metadata = user.app_metadata || {};
// update the app_metadata that will be part of the response
user.app_metadata.roles = null;
// persist the app_metadata update
auth0.users.updateAppMetadata(user.user_id, user.app_metadata)
.then(function(){
callback(null, user, context);
})
.catch(function(err){
callback(err);
});
}
{
"user_id": "jdoe",
"email": "john.doe@example.com",
"app_metadata": { },
"user_metadata": {
"preferences": {
"color": "blue"
}
}
}
Delete single property value example
To delete a single value of a property, remove that specific value. For example, to remove thewriter role from the user profile:function(user, context, callback){
user.app_metadata = user.app_metadata || {};
user.app_metadata.roles = user.app_metadata.roles || [];
var index = user.app_metadata.roles.indexOf('writer');
if (index !== -1){
// update the app_metadata that will be part of the response
user.app_metadata.roles.splice(index, 1);
}
// persist the app_metadata update
auth0.users.updateAppMetadata(user.user_id, user.app_metadata)
.then(function(){
callback(null, user, context);
})
.catch(function(err){
callback(err);
});
}
{
"user_id": "google-oauth2|1234",
"email": "john.doe@gmail.com",
"app_metadata": {
"roles": [ ]
},
"user_metadata": {
"preferences": {
"color": "blue"
}
}
}
roles property still exists but does not contain any value.Delete user metadata properties and values
To delete the user’s color preference:function(user, context, callback){
user.user_metadata = user.user_metadata || {};
// update the user_metadata that will be part of the response
user.user_metadata.preferences = user.user_metadata.preferences || {};
delete user.user_metadata.preferences.color;
// persist the user_metadata update
auth0.users.updateUserMetadata(user.user_id, user.user_metadata)
.then(function(){
callback(null, user, context);
})
.catch(function(err){
callback(err);
});
}
{
"user_id": "jdoe",
"email": "john.doe@example.com",
"app_metadata": {
"roles": [ "writer" ]
},
"user_metadata": {
"preferences": { }
}
}