---
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.

**Developer preview:**

The Shop platform is in early access. Features and APIs might change before general availability.

***

## 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
    refreshToken
    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 tokens server-side. Never expose them to the storefront, browser, Shopify Function, or Checkout UI extension, and never log the access or refresh token. Store refresh tokens encrypted at rest, and scope them per user.

***

## 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, use the `refreshToken`, or 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.

***