How to return full `profile` when updating `user_metadata`?

I’m doing a PATCH request with update:current_user_metadata scope permissions:

curl --request PATCH
–url ‘/api/v2/users/<USER_ID>’
–header 'authorization: Bearer <ACCESS_TOKEN>
–header ‘content-type: application/json’
–data ‘{“user_metadata”: { … }}’


Which returns the changed metadata

{“user_metadata”:{ … }}


I'd prefer it to return the user profile with the scopes `["openid", "name", "email"]` (as you'd get pinging the `/userinfo` endpoint).

Is this possible? Or do I just have to make another call to `/userinfo` after updating the user metadata?

Sorry I screwed up the formatting :wink:

Hi @rob829304

Welcome to the Auth0 Community!

Thanks for letting us know! If you ever have any other questions, let us know!

Kind Regards,
Nik

So am I right in assuming that it’s currently not possible to return the full user profile? It only returns the user_metadata values?

Hi again!

When updating an user through the Management API using the /users endpoint, the response body should include the full JSON of their profile attributes as available in the Auth0 Dashboard:

{
  "created_at": "",
  "email": "",
  "email_verified": false,
  "identities": [
    {
      "connection": "Username-Password-Authentication",
      "provider": "auth0",
      "user_id": "",
      "isSocial": false
    }
  ],
  "name": "",
  "nickname": "",
  "picture": "",
  "updated_at": "2025-05-13T15:37:52.797Z",
  "user_id": "auth0|",
  "user_metadata": {
    "test_data": "test"
  },
  "last_ip": "",
  "last_login": "2025-05-08T18:04:07.054Z",
  "logins_count": 3
}

If you would want to return the scopes of the user after updating their profile, as you have mentioned, I would recommend calling the /userinfo endpoint since that information is included in the access token and not inside the user attributes that are available from the identity stored.

If I can help with anyhting else, let me know!

Kind Regards,
Nik

Thanks Nik, that’s not what I’m seeing though. Perhaps it depends on if you’re doing it as an admin or a user? For example here is my logged in user’s access token (with the idToken extracted):

{
  "iss": "<API_URL>.auth0.com/",
  "sub": "<CURRENT_USER_ID>",
  "aud": [
    "<MANAGEMENT_API_IDENTIFIER>/api/v2/",
    "<API_URL>/userinfo"
  ],
  "iat": 1747320142,
  "exp": 1747327342,
  "scope": "openid email update:current_user_metadata",
  "azp": "<CLIENT_ID>"
}

And the Curl command

curl --request PATCH \
  --url '<YOUR_ENDPOINT_URL>/api/v2/users/<CURRENT_USER_ID>' \
  --header 'authorization: Bearer <ACCESS_TOKEN_WITH_SCOPES_AND_AUDIENCE>' \
  --header 'content-type: application/json' \
  --data '{"user_metadata": {"json": "Changed", "prefs": ["two", "three", "four"]}}'

Returns only

{"user_metadata":{"json":"Changed","prefs":["two","three","four"]}}

That is quite peculiar.

Just for clarification, for the token used in the cURL command, are you using the management API token or the Access token of the logged in user?

I have tried the cURL command on my end using the Management API and I received the expected profile as shown in the previous message.

Kind Regards,
Nik

Hi again Nik,

That’s probably the reason; I’m using the access token (it wasn’t so clear from the documentation what the difference is).

I’m assuming for a SPA app (I’m using Elm) the access token is more secure (for example putting in the scope update:users to generate an access token won’t give them access to this functionality).

Would you discourage using the management API on the frontend?

Thanks,

Rob

Hi,

I would discourage the use of the management api on the frontend since it might make your application open to several security risks. However, you could use the access token in order to return scopes which would allow only specific users to perform specific actions, thus having your application use the stored API token to perform these actions on their behalf.

In our sample SPA applications, we usually have an API audience which is defined in order to perform M2M communication with the Management API to prevent such risks (like storing the your API token inside the application. I would highly recommend following such an approach.

Kind Regards,
Nik

Understood. Right now I’m only using access token with user_metadata and update:current_user_metadata (with Management API audience) so perhaps that’s all I’ll need — it seems pretty secure.

It does seem unsafe to store the Management API token in the SPA app. At least with the access token it’s only on the user’s browser and can only torpedo their own account if it gets hacked!

  1. Could you point me to the bits of the SPA code you’re talking about?
  2. Is the user ID ("sub") always completely random?

I can always admin the management API locally, and if (2) is true the likelyhood of a brute force attack seems quite small.

Hi again!

  1. Could you point me to the bits of the SPA code you’re talking about?

In the case of the React sample application, the audience would be defined in an auth_config.json file where you would declare the values for the Auth0 Domain, Client ID and Audience. These values would then be used by the config.jsfile.

  1. Is the user ID ("sub") always completely random?

The sub value inside the token is not completely random, that would be the user_id of the logged in user available within the Auth0 Dashboard. The user_id is composed of 2 parts:

  1. Type of connection used (database connection/social connection type/enterprise connection type).
  2. Generated user_id when the user first signed up to an application and registered inside the dashboard.

Kind Regards,
Nik

Great stuff, thanks. I’m seeing "sub" in both the JWT access token / /userinfo endpoint return value (it’s a bit confusing this user_id is labelled "sub". Understand the "sub" value isn’t always random, what I was asking is if the part of the user_id after the | pipe is random? I’m assuming the answer is yes.

Sorry if I was not clear enough above. The part after the |, specifically sub| would be the user_id under the Auth0 Dashboard, meaning that the value would be as following:

sub|{auth0_user_id}

In conclusion, that number is not automatically generated, it is the user_id available within the Dashboard. As you have mentioned, that value is also visible inside the user JSON under user_id, however it is translated to sub inside the token.

Hope this helps!

Kind Regards,
Nik

:man_facepalming: I’ll try to be more specific.

“After the point of a user signup (creating a user account via auth0| not a social login) a new user is created with a random string user_id)”.

The string after the | pipe looks random. I’m not sure about the social IDs however, as google-oauth2|<user_id> looks like an incremented ID.

Be good to know if I’ve understood this correctly.

Got it!

Basically, the user_id property is randomly generated in order to be unique within a tenant. A user may have the same user_id property across multiple Auth0 tenants, but consistency is not guaranteed.

Meaning that, as you have stated, the user_id generated on signup is random but guaranteed to be unique.

Kind Regards,
Nik

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.