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. In this guide, you'll turn a completed sign-in into an authenticated session that can read Shop user data.
The Shop platform is in early access. Features and APIs might change before general availability.
The Shop platform is in early access. Features and APIs might change before general availability.
Anchor to What you'll learnWhat 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.
Anchor to RequirementsRequirements
- A Shop app with a client ID and client secret.
- A Sign in with Shop integration that uses the Shop SDK
loginfeature, which returns the consent token. - A trusted server where you can hold your client credentials and the user's tokens.
Anchor to Step 1: Get user information from the sign-in flowStep 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
The consent token comes from the Shop SDK login feature. A third-party identity provider 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.
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.
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.
Anchor to Step 2: Exchange the consent token for a user access tokenStep 2: Exchange the consent token for a user access token
From your server, call the fetchTokensForUser mutation on the Shop Partners API, 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
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
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
Provide exactly one of consentToken or publicId per call.
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.
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.
Anchor to Step 3: Read user data from the Shop Users APIStep 3: Read user data from the Shop Users API
With the accessToken from Step 2, call the Shop Users API. 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
Anchor to Read user profile fieldsRead 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
If your access token doesn't authenticate a user, the user query returns an Unauthorized error.
Anchor to Read app-owned metafieldsRead 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
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
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.
Anchor to Next stepsNext steps
- Store metafields on Shop users to write the custom data that you read here.
- Review the Shop Partners API and Shop Users API references.
- Add Sign in with Shop to your storefront if you haven't already.