> ## Documentation Index
> Fetch the complete documentation index at: https://auth0.com/llms.txt
> Use this file to discover all available pages before exploring further.

> Learn how to manage with app metadata, user metadata, and client metadata using Rules.

# Manage Metadata with Rules

<Warning>
  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](/docs/customize/actions/actions-overview).

  To help with your migration, we offer guides that will help you [migrate from Rules to Actions](/docs/customize/actions/migrate/migrate-from-rules-to-actions) and [migrate from Hooks to Actions](/docs/customize/actions/migrate/migrate-from-hooks-to-actions). We also have a dedicated [Move to Actions](https://auth0.com/extensibility/movetoactions) page that highlights feature comparisons, [an Actions demo](https://www.youtube.com/watch?v=UesFSY1klrI), 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](https://auth0.com/blog/preparing-for-rules-and-hooks-end-of-life/).
</Warning>

You can read, update, and delete metadata using [Auth0 Rules](/docs/customize/rules). In the following sections, we will refer to this example where the user and their information is represented by the following JSON snippet:

```json lines theme={null}
{
  "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 <Tooltip tip="Management API: A product to allow customers to perform administrative tasks." cta="View Glossary" href="/docs/glossary?term=Management+API">Management API</Tooltip>. You can also search for profile-related information in `user_metadata`, such as:

* `name`
* `nickname`
* `given_name`
* `family_name`

By default, user profile attributes provided by <Tooltip tip="Identity Provider (IdP): Service that stores and manages digital identities." cta="View Glossary" href="/docs/glossary?term=identity+providers">identity providers</Tooltip> other than Auth0 (such as Google, Facebook, or X) are not directly editable because they are updated from the identity provider each time the user logs in. Fore more information on attributes from identity providers, read [Configure Identity Provider Connection for User Profile Updates](/docs/manage-users/user-accounts/user-profiles/configure-connection-sync-with-auth0).

To be able to edit the `name`, `nickname`, `given_name`, `family_name`, or `picture` root attributes on the normalized user profile, you must [configure your connection sync with Auth0](/docs/manage-users/user-accounts/user-profiles/configure-connection-sync-with-auth0) so that user attributes will be updated from the identity provider only on user profile creation. These root attributes will then be available to be edited individually or by bulk imports

As an example, assume the following metadata is stored for a user with the email address `jane.doe@example.com`:

```json lines theme={null}
{
    "email": "jane.doe@example.com",
    "user_metadata": {
        "hobby": "surfing"
    },
    "app_metadata": {
        "plan": "full"
    }
}
```

Using the example metadata above, you can refer to specific items from the dataset in [Auth0 Rules](/docs/customize/rules) or via a call to the [Management API](/docs/manage-users/user-accounts/metadata) as follows:

```js lines theme={null}
console.log(user.email); // "jane.doe@example.com"
console.log(user.user_metadata.hobby); // "surfing"
console.log(user.app_metadata.plan); // "full"
```

Any valid JSON snippet can be used as metadata, but note that `user.app_metadata` is `Undefined` by default.

To read the available metadata, you will need to access the correct user property.

### Read app metadata

You can make a decision based on the user's roles:

```javascript lines theme={null}
function(user, context, callback){
  user.app_metadata = user.app_metadata || {};
  if (user.app_metadata.roles.indexOf('writer')){
    // code to be executed
  }
  ...
}
```

### Read user metadata

You can base decisions on specific preferences, such as a color preference:

```javascript lines theme={null}
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.

```javascript lines theme={null}
function(user, context, callback){
  context.clientMetadata = context.clientMetadata || {};
  if (context.clientMetadata.usersuppliedkey1 === 'black'){
    // this code would not be executed for the user
  }
  ...
}
```

## Update metadata

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Use Rules to map SAML attributes that Auth0 receives from the IdP into `user_metadata` or `app_metadata`.
</Callout>

### Update app metadata

To add an administrative role to the user:

```javascript lines theme={null}
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);
    });
}
```

This results in the following JSON representation of the user profile details:

```json lines theme={null}
{
  "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's `fontSize` preference to the user profile:

```javascript lines theme={null}
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);
    });
}
```

This results in the following JSON representation of the user profile details:

```json lines theme={null}
{
  "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 the `app_metadata` and `user_metadata` in the same rule:

```javascript lines expandable theme={null}
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);
    });
}
```

This results in the following JSON representation of the user profile details:

```json lines theme={null}
{
  "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 to `null`.

#### Delete user's roles example

To delete the user's roles, use the following sample rule:

```javascript lines theme={null}
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);
    });
}
```

This results in the following JSON representation of the user profile:

```json lines theme={null}
{
  "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 the `writer` role from the user profile:

```javascript lines theme={null}
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);
    });
}
```

This results in the following JSON representation of the user profile:

```json lines theme={null}
{
  "user_id": "google-oauth2|1234",
  "email": "john.doe@gmail.com",
  "app_metadata": {
    "roles": [ ]
  },
  "user_metadata": {
    "preferences": {
      "color": "blue"
    }
  }
}
```

Note that the `roles` property still exists but does not contain any value.

### Delete user metadata properties and values

To delete the user's color preference:

```javascript lines theme={null}
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);
  });
}
```

This results in the following JSON representation of the user profile details:

```json lines theme={null}
{
  "user_id": "jdoe",
  "email": "john.doe@example.com",
  "app_metadata": {
    "roles": [ "writer" ]
  },
  "user_metadata": {
    "preferences": { }
  }
}
```

## Learn more

* [Use the Management API from within Rules](/docs/customize/rules/use-management-api)
* [Context Object Properties in Rules](/docs/customize/rules/context-object)
* [Auth0 Rules](/docs/customize/rules)
