User profile
You have an access_token (see exchange code for token). Now you need
to learn who signed in. The profile is served by the OIDC UserInfo endpoint.
Request
Section titled “Request”Authorization: Bearer ACCESS_TOKENDo not hardcode the address — take it from discovery
(GET /.well-known/openid-configuration, the userinfo_endpoint field).
Response
Section titled “Response”The set of fields (claims) depends on the scopes requested at sign-in: sub is always
present, profile fields come with the profile scope, the email with the email scope. The
example below is the response for openid profile email:
{
"sub": "b3c1…",
"name": "Jane Doe",
"given_name": "Jane",
"family_name": "Doe",
"picture": "https://…",
"email": "user@example.com",
"email_verified": true,
"updated_at": 1717000000
}
| Field | Scope | What it is |
|---|---|---|
sub |
always | the user identifier (pairwise) |
name |
profile |
full name |
given_name / family_name |
profile |
first and last name |
picture |
profile |
avatar URL |
updated_at |
profile |
the moment the profile was last changed (Unix time) |
email / email_verified |
email |
email and whether it is verified — only if an email exists |
Pairwise sub
Section titled “Pairwise sub”sub is the person’s identifier within your integration. It is stable: on the next sign-in
the same person arrives with the same sub, and you recognize them. But at another partner the
same person gets a different sub — you cannot use it as a shared cross-partner key.
Through id_token instead of a request
Section titled “Through id_token instead of a request”The same fields live in id_token (a JWT) that you received together with access_token. Verify
its signature with the keys from JWKS and take the sub claim — then a separate
request to UserInfo is not needed. Both paths yield the same sub.