---
title: Get Shop user information
description: >-
  Read user data from the Shop Users API using an access token obtained through
  the Sign in with Shop flow.
source_url:
  html: 'https://shopify.dev/docs/api/shop/guides/use-cases/user-information'
  md: 'https://shopify.dev/docs/api/shop/guides/use-cases/user-information.md'
---

# Get Shop user information

After a user signs in with Shop, your app can read information about that user. The sign-in flow returns the user's identity claims and a short-lived consent token. You exchange the consent token for a user access token, then use that token to make authenticated, user-scoped requests to the [Shop Users API](https://shopify.dev/docs/api/shop-users/latest). In this guide, you'll turn a completed sign-in into an authenticated session that can read Shop user data.

***

## What you'll learn

In this guide, you'll learn how to:

* Capture the identity claims and consent token that a completed Sign in with Shop flow returns.
* Exchange the consent token for a user access token using the Shop Partners API.
* Use the access token to read user-scoped data from the Shop Users API.

***

## Requirements

* A [Shop app](https://shopify.dev/docs/api/shop/guides/creating-a-client) with a client ID and client secret.
* A [Sign in with Shop](https://shopify.dev/docs/api/shop/guides/use-cases/sign-in) integration that uses the Shop SDK `login` feature, which returns the consent token.
* A trusted server where you can hold your client credentials and the user's tokens.

***

## Step 1: Get user information from the sign-in flow

When a user completes Sign in with Shop through the Shop SDK `login` feature, the flow returns the user's identity claims and a signed `shopConsentToken`. The token is short-lived and represents the user's delegated consent to your app. The `onComplete` event carries this information:

| Field | Description |
| - | - |
| `email` | The user's email address. |
| `emailVerified` | Whether Shop verified the email address. |
| `consentedScopes` | A space-separated list of the scopes the user consented to. |
| `signedIn` | Whether the user signed in, as opposed to only providing their email address. |
| `shopConsentToken` | The consent token to exchange for a user access token. |

## JavaScript

```javascript
const login = await sdk.create('login', {
  attributes: { scope: 'shop_app:oauth' },
  onComplete(event) {
    if (event.signedIn && event.shopConsentToken) {
      // Send the consent token to your server over HTTPS.
      sendToBackend({
        email: event.email,
        consentToken: event.shopConsentToken,
      });
    }
  },
});
```

The consent token comes from the Shop SDK `login` feature. A [third-party identity provider](https://shopify.dev/docs/api/shop/guides/use-cases/external-login-page) integration signs users in and returns identity claims, such as `sub` and `email`, but it doesn't return a `shopConsentToken`. To exchange a consent token and call the Shop Users API, use the Shop SDK `login` feature.

**Handle the consent token like a credential:**

Send the `shopConsentToken` only over HTTPS, exchange it from a trusted server, and don't log it. Don't construct a consent token yourself, and don't accept one from arbitrary input.

***

## Step 2: Exchange the consent token for a user access token

From your server, call the `fetchTokensForUser` mutation on the [Shop Partners API](https://shopify.dev/docs/api/shop-partners/latest), authenticating with your client ID and client secret over HTTP Basic Authentication. The first exchange uses the consent token. Every later exchange uses the `publicId` that the first call returns.

Endpoint: `https://shop.app/api/latest/partners/graphql.json`

## GraphQL Mutation

```graphql
mutation FetchTokensForUser($consentToken: String, $publicId: String) {
  fetchTokensForUser(consentToken: $consentToken, publicId: $publicId) {
    publicId
    accessToken
    expiresIn
    tokenType
    scope
    user {
      sub
      email
      emailVerified
      givenName
      familyName
      name
      avatar
    }
    userErrors {
      field
      message
    }
  }
}
```

The `user` field returns the same user profile claims that the Shop Users API exposes, inline on the mutation response. Each field is gated by the **issued token's** scope: a field whose gating scope wasn't granted resolves to `null`, even if the response selects it. This lets you populate your user record from the mutation response without a follow-up call. The fields and their gating scopes are:

| Field | Gating scope |
| - | - |
| `sub` | Always returned when the token authenticates a user. |
| `email`, `emailVerified` | `email` (also granted by `email:verified` or `user:manage`). |
| `phone`, `phoneVerified` | `phone` (also granted by `phone:verified` or `user:manage`). Available but not selected in the example above — add them to the selection set when you request a `phone` scope. |
| `givenName`, `familyName`, `name` | `name` or `profile`. |
| `avatar` | `avatar` or `profile`. |

If the mutation fails, `user` is `null` and `userErrors` is populated. A non-null `user` does not by itself imply that any specific field resolved — individual fields can still be `null` if the issued token didn't grant the gating scope.

For the first exchange, pass the consent token from Step 1:

## GraphQL Variables

```json
{
  "consentToken": "<shopConsentToken from the Sign in with Shop flow>"
}
```

Persist the returned `publicId` against your own record of the user. After the first exchange, you won't need the consent token again. To mint a fresh access token later, call the same mutation with the stored `publicId` instead:

## GraphQL Variables

```json
{
  "publicId": "<stored publicId for this user>"
}
```

Provide exactly one of `consentToken` or `publicId` per call.

**Protect your tokens:**

Keep your client credentials and the returned access token server-side. Never expose them to the storefront, browser, Shopify Function, or Checkout UI extension, and never log the access token.

***

## Step 3: Read user data from the Shop Users API

With the `accessToken` from Step 2, call the [Shop Users API](https://shopify.dev/docs/api/shop-users/latest). The API is scoped to the authenticated user. Authenticate with `Authorization: Bearer <accessToken>`, not your client credentials.

Endpoint: `https://shop.app/api/latest/users/graphql.json`

### Read user profile fields

Query the `user` field to read the authenticated user's profile claims. The same scope gating that applies to the `user` payload on `fetchTokensForUser` applies here — a field whose gating scope wasn't granted on the access token resolves to `null`.

## GraphQL Query

```graphql
query CurrentUser {
  user {
    sub
    email
    emailVerified
    givenName
    familyName
    name
    avatar
  }
}
```

If your access token doesn't authenticate a user, the `user` query returns an `Unauthorized` error.

### Read app-owned metafields

In addition to the user's profile, your app can read the metafields it owns on that user. Query them with the `metafields` query:

## GraphQL Query

```graphql
query UserMetafields {
  metafields(first: 10) {
    nodes {
      definition {
        namespace
        key
      }
      value
    }
  }
}
```

To read a single metafield by key, use the `metafield` query. The namespace defaults to your app's reserved namespace, so you only need the key:

## GraphQL Query

```graphql
query UserMembership {
  metafield(identifier: {key: "my-membership"}) {
    value
  }
}
```

You can read a user's identity information from either the `user` payload on `fetchTokensForUser` (Step 2) or the `user` query on the Users API (above). Both surfaces return the same fields and apply the same per-field scope gating.

Access tokens expire after the number of seconds in `expiresIn`. When a token expires, call `fetchTokensForUser` again with the stored `publicId` to get a new one.

***

## Next steps

* [Store metafields on Shop users](https://shopify.dev/docs/api/shop/guides/use-cases/metafields) to write the custom data that you read here.
* Review the [Shop Partners API](https://shopify.dev/docs/api/shop-partners/latest) and [Shop Users API](https://shopify.dev/docs/api/shop-users/latest) references.
* Add [Sign in with Shop](https://shopify.dev/docs/api/shop/guides/use-cases/sign-in) to your storefront if you haven't already.

***
