> ## Documentation Index
> Fetch the complete documentation index at: https://docs-staging-quickstart-revamp.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Learn how to use user metadata to change a user's picture field and how to change the default picture for all users.

# Change User Pictures

Auth0 normalizes common profile properties in the User Profile, this includes the `name`, `picture` field and more. The picture field is populated by either the social provider profile picture or the Gravatar image associated with the user's email address.

By default, all database users will have a placeholder image with their initials. When you authenticate the user, this picture field is referred to as `user.picture`.

## Use the Management API

The `user.picture` attribute is not directly editable when 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. To edit this attribute, you must configure your connection sync with Auth0 so that user attributes will be updated from the identity provider only on user profile creation. To learn more, read [Configure Identity Provider Connection for User Profile Updates](/docs/manage-users/user-accounts/user-profiles/configure-connection-sync-with-auth0). Root attributes will then be available to be edited individually or by bulk import using 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>. To learn more, read [Bulk User Imports](/docs/manage-users/user-migration/bulk-user-imports).

Alternatively, you can use metadata to store the picture attribute for users. For example, if your app provides a way to upload profile pictures, once the picture is uploaded, you can set the URL to the picture in the `user.user_metadata.picture`:

<CodeGroup>
  ```bash cURL lines
  curl --request PATCH \
    --url 'https://{yourDomain}/api/v2/users/USER_ID' \
    --header 'authorization: Bearer MGMT_API_ACCESS_TOKEN' \
    --header 'content-type: application/json' \
    --data '{"user_metadata": {"picture": "https://example.com/some-image.png"}}'
  ```

  ```csharp C# lines
  var client = new RestClient("https://{yourDomain}/api/v2/users/USER_ID");
  var request = new RestRequest(Method.PATCH);
  request.AddHeader("authorization", "Bearer MGMT_API_ACCESS_TOKEN");
  request.AddHeader("content-type", "application/json");
  request.AddParameter("application/json", "{\"user_metadata\": {\"picture\": \"https://example.com/some-image.png\"}}", ParameterType.RequestBody);
  IRestResponse response = client.Execute(request);
  ```

  ```go Go lines expandable
  package main

  import (
  	"fmt"
  	"strings"
  	"net/http"
  	"io/ioutil"
  )

  func main() {

  	url := "https://{yourDomain}/api/v2/users/USER_ID"

  	payload := strings.NewReader("{\"user_metadata\": {\"picture\": \"https://example.com/some-image.png\"}}")

  	req, _ := http.NewRequest("PATCH", url, payload)

  	req.Header.Add("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
  	req.Header.Add("content-type", "application/json")

  	res, _ := http.DefaultClient.Do(req)

  	defer res.Body.Close()
  	body, _ := ioutil.ReadAll(res.Body)

  	fmt.Println(res)
  	fmt.Println(string(body))

  }
  ```

  ```java Java lines
  HttpResponse<String> response = Unirest.patch("https://{yourDomain}/api/v2/users/USER_ID")
    .header("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
    .header("content-type", "application/json")
    .body("{\"user_metadata\": {\"picture\": \"https://example.com/some-image.png\"}}")
    .asString();
  ```

  ```javascript Node.JS lines
  var axios = require("axios").default;

  var options = {
    method: 'PATCH',
    url: 'https://{yourDomain}/api/v2/users/USER_ID',
    headers: {
      authorization: 'Bearer MGMT_API_ACCESS_TOKEN',
      'content-type': 'application/json'
    },
    data: {user_metadata: {picture: 'https://example.com/some-image.png'}}
  };

  axios.request(options).then(function (response) {
    console.log(response.data);
  }).catch(function (error) {
    console.error(error);
  });
  ```

  ```obj-c Obj-C lines expandable
  #import <Foundation/Foundation.h>

  NSDictionary *headers = @{ @"authorization": @"Bearer MGMT_API_ACCESS_TOKEN",
                             @"content-type": @"application/json" };
  NSDictionary *parameters = @{ @"user_metadata": @{ @"picture": @"https://example.com/some-image.png" } };

  NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];

  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://{yourDomain}/api/v2/users/USER_ID"]
                                                         cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                     timeoutInterval:10.0];
  [request setHTTPMethod:@"PATCH"];
  [request setAllHTTPHeaderFields:headers];
  [request setHTTPBody:postData];

  NSURLSession *session = [NSURLSession sharedSession];
  NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                              completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                  if (error) {
                                                      NSLog(@"%@", error);
                                                  } else {
                                                      NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                                      NSLog(@"%@", httpResponse);
                                                  }
                                              }];
  [dataTask resume];
  ```

  ```php PHP lines expandable
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://{yourDomain}/api/v2/users/USER_ID",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "PATCH",
    CURLOPT_POSTFIELDS => "{\"user_metadata\": {\"picture\": \"https://example.com/some-image.png\"}}",
    CURLOPT_HTTPHEADER => [
      "authorization: Bearer MGMT_API_ACCESS_TOKEN",
      "content-type: application/json"
    ],
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);

  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```python Python lines
  import http.client

  conn = http.client.HTTPSConnection("")

  payload = "{\"user_metadata\": {\"picture\": \"https://example.com/some-image.png\"}}"

  headers = {
      'authorization': "Bearer MGMT_API_ACCESS_TOKEN",
      'content-type': "application/json"
      }

  conn.request("PATCH", "/{yourDomain}/api/v2/users/USER_ID", payload, headers)

  res = conn.getresponse()
  data = res.read()

  print(data.decode("utf-8"))
  ```

  ```ruby Ruby lines
  require 'uri'
  require 'net/http'
  require 'openssl'

  url = URI("https://{yourDomain}/api/v2/users/USER_ID")

  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  request = Net::HTTP::Patch.new(url)
  request["authorization"] = 'Bearer MGMT_API_ACCESS_TOKEN'
  request["content-type"] = 'application/json'
  request.body = "{\"user_metadata\": {\"picture\": \"https://example.com/some-image.png\"}}"

  response = http.request(request)
  puts response.read_body
  ```

  ```swift Swift lines expandable
  import Foundation

  let headers = [
    "authorization": "Bearer MGMT_API_ACCESS_TOKEN",
    "content-type": "application/json"
  ]
  let parameters = ["user_metadata": ["picture": "https://example.com/some-image.png"]] as [String : Any]

  let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

  let request = NSMutableURLRequest(url: NSURL(string: "https://{yourDomain}/api/v2/users/USER_ID")! as URL,
                                          cachePolicy: .useProtocolCachePolicy,
                                      timeoutInterval: 10.0)
  request.httpMethod = "PATCH"
  request.allHTTPHeaderFields = headers
  request.httpBody = postData as Data

  let session = URLSession.shared
  let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  })

  dataTask.resume()
  ```
</CodeGroup>

## Use Actions

To ensure that the picture from the `user_metadata` is returned in the <Tooltip tip="ID Token: Credential meant for the client itself, rather than for accessing a resource." cta="View Glossary" href="/docs/glossary?term=ID+Token">ID Token</Tooltip>, we'll need to [create a new Action](/docs/customize/actions/write-your-first-action) to check whether the `event.user.user_metadata.picture` attribute is present, and if so, replace the `user.picture` attribute with that value. This ensures that the picture from the `user_metadata` is returned in the `picture` claim of the ID Token.

1. Navigate to [Auth0 Dashboard > Actions > Library](https://manage.auth0.com/#/actions/library), and select **Build Custom**.

2. Enter a descriptive **Name** for your Action (for example, `Change user pictures`), select the `Login / Post Login` trigger because you’ll be adding the Action to the Login flow, then select **Create**.

3. Locate the Actions Code Editor, copy the following JavaScript code into it, and select **Save Draft** to save your changes:

   ```js lines
   exports.onExecutePostLogin = async (event, api) => {
     const { picture } = event.user.user_metadata;
     if (picture) {
       // Return the persisted user_metadata.picture in the ID token
       api.idToken.setCustomClaim("picture", picture)
     }
   };
   ```

4. From the Actions Code Editor sidebar, select Test (play icon), then select **Run** to [test your code](/docs/customize/actions/test-actions).

5. When you’re ready for the Action to go live, select **Deploy**.

Finally, add the Action you created to the [Login Flow](https://manage.auth0.com/#/actions/flows/login/). To learn how to attach Actions to Flows, read the "Attach the Action to a flow" section in [Write Your First Action](/docs/customize/actions/write-your-first-action).

## Change default picture for all users

To change the default picture for all users who have not set a profile picture, you can use an Action. For example:

```js lines
exports.onExecutePostLogin = async (event, api) => {
  const DEFAULT_PROFILE_IMAGE = '{yourDefaultImageUrl}';
  api.idToken.setCustomClaim("picture", {defaultProfileImage});
};
```

In this Action, the custom picture is returned in the ID Token and overrides any `picture` property that may come from an external identity provider login, such as Google.

## Limitations

The Auth0 data store is limited and to prevent your application's data from exceeding the limits, we recommend that you use an external database to store user pictures. This allows you to keep your Auth0 data store small and to use a more efficient external database to hold the additional data. To learn more, read [User Data Storage](/docs/secure/security-guidance/data-security/user-data-storage).

## Learn more

* [User Profile Structure](/docs/manage-users/user-accounts/user-profiles/user-profile-structure)
* [User Profile Root Attributes](/docs/manage-users/user-accounts/user-profiles/root-attributes)
* [Understand How Metadata Works in User Profiles](/docs/manage-users/user-accounts/metadata)
* [Manage Metadata Using the Management API](/docs/manage-users/user-accounts/metadata/manage-metadata-api)
* [Manage Metadata with Rules](/docs/manage-users/user-accounts/metadata/manage-metadata-rules)
* [Bulk User Imports](/docs/manage-users/user-migration/bulk-user-imports)
