--- title: Session Token API description: >- The Session Token API lets you authenticate requests from your extension to your app's backend using a signed JSON Web Token (JWT). Use this API to get a token that your backend can verify using your app's shared secret, confirming the request came from a legitimate Shopify extension. api_version: 2026-04 api_name: customer-account-ui-extensions source_url: html: >- https://shopify.dev/docs/api/customer-account-ui-extensions/latest/target-apis/platform-apis/session-token-api md: >- https://shopify.dev/docs/api/customer-account-ui-extensions/latest/target-apis/platform-apis/session-token-api.md --- # Session Token API The Session Token API lets you authenticate requests from your extension to your app's backend using a signed [JSON Web Token (JWT)](https://jwt.io/introduction). Use this API to get a token that your backend can verify using your app's shared secret, confirming the request came from a legitimate Shopify extension. ### Use cases * **Authenticate backend requests**: Pass a session token as a Bearer token in API calls to your app's backend so you can verify the request came from your extension. * **Identify the customer**: Read the optional `sub` claim in the token to get the customer's GID when they're signed in and your app has [access to protected customer data](https://shopify.dev/docs/apps/store/data-protection/protected-customer-data). * **Verify the shop**: Use the `dest` claim to confirm which shop the request is associated with, ensuring your backend responds with the correct data. ### Support Targets (24) ### Supported targets * [customer-account.​footer.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/footer#footer-render-after-) * [customer-account.​order-index.​announcement.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/order-actions#order-index-announcement-) * [customer-account.​order-index.​block.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/order-actions#order-index-block-) * [customer-account.​order-status.​announcement.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/order-status#order-status-announcement-) * [customer-account.​order-status.​block.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/order-status#order-status-block-) * [customer-account.​order-status.​cart-line-item.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/order-status#cart-line-item-render-after-) * [customer-account.​order-status.​cart-line-list.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/order-status#cart-line-list-render-after-) * [customer-account.​order-status.​customer-information.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/order-status#customer-information-render-after-) * [customer-account.​order-status.​fulfillment-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/fulfillment-status#fulfillment-status-targets) * [customer-account.​order-status.​payment-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/payments-and-returns#payments-and-returns-targets) * [customer-account.​order-status.​return-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/payments-and-returns#return-details-render-after-) * [customer-account.​order-status.​unfulfilled-items.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/fulfillment-status#unfulfilled-items-render-after-) * [customer-account.​order.​action.​menu-item.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/order-actions#order-action-menu-item-) * [customer-account.​order.​action.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/order-actions#order-action-) * [customer-account.​order.​page.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/full-page#order-specific-full-page-) * [customer-account.​page.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/full-page#customer-account-full-page-) * [customer-account.​profile.​addresses.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/profile-page-default#profile-page-default-targets-) * [customer-account.​profile.​announcement.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/profile-page-default#profile-announcement-) * [customer-account.​profile.​block.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/profile-page-default#profile-block-) * [customer-account.​profile.​company-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/profile-page-b2b#profile-page-b2b-targets-) * [customer-account.​profile.​company-location-addresses.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/profile-page-b2b#company-location-addresses-render-after-) * [customer-account.​profile.​company-location-payment.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/profile-page-b2b#company-location-payment-render-after-) * [customer-account.​profile.​company-location-staff.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/targets/profile-page-b2b#company-location-staff-render-after-) * customer-account.​profile.​payment.​render-after ### Properties The [`shopify` global object](https://shopify.dev/docs/api/customer-account-ui-extensions/latest#target-apis-define-what-your-extension-does) provides session token functionality for customer account extensions. Access the following properties on `shopify` to retrieve signed tokens for authenticating requests to your app's backend. * **sessionToken** **SessionToken** **required** Authenticates requests between your extension and your app backend. Call `get()` to retrieve a signed JWT containing the customer ID, shop domain, and expiration time, then verify it server-side. For more information, refer to the [Session Token API](https://shopify.dev/docs/api/customer-account-ui-extensions/latest/target-apis/platform-apis/session-token-api). ### SessionToken Authenticates requests between your extension and your app backend. Use session tokens to verify the identity of the buyer and the shop context when making server-side API calls. The token is a signed JWT that contains claims such as the customer ID, shop domain, and expiration. The \`sub\` claim in the decoded token is present only when the buyer is logged in and the app has permission to read customer accounts. Absent for anonymous buyers. * get Requests a session token that hasn't expired. You should call this method every time you need to make a request to your backend in order to get a valid token. This method returns cached tokens when possible, so you don't need to worry about storing these tokens yourself. ```ts () => Promise ``` Examples ### Examples * #### ##### Description Retrieve a session token and pass it as a Bearer token to authenticate a request to your app's backend. This example uses \`shopify.sessionToken.get()\` to obtain the token and includes it in the \`Authorization\` header of a fetch call. ##### jsx ```tsx import '@shopify/ui-extensions/preact'; import {render} from 'preact'; import {useEffect} from 'preact/hooks'; export default async () => { render(, document.body); }; function Extension() { useEffect(() => { async function queryApi() { // Request a new (or cached) session token from Shopify const token = await shopify.sessionToken.get(); console.log('sessionToken.get()', token); const apiResponse = await fetchWithToken( token, ); // Use your response console.log('API response', apiResponse); } function fetchWithToken(token) { const result = fetch( 'https://myapp.com/api/session-token', { headers: { Authorization: `Bearer ${token}`, }, }, ); return result; } queryApi(); }, []); return ( See console for API response ); } ``` * #### ##### Description Review the structure of a decoded session token to understand the available claims. This example shows the JSON payload including the \`dest\`, \`aud\`, \`exp\`, and optional \`sub\` claims. ##### Session token claims ```json { // Shopify URL "dest": "store-name.myshopify.com", // The Client ID of your app "aud": "", // When the token expires. Set at 5 minutes. "exp": 1679954053, // When the token was actived "nbf": 1679953753, // When the token was issued "iat": 1679953753, // A unique identifier (a nonce) to prevent replay attacks "jti": "6c992878-dbaf-48d1-bb9d-6d9b59814fd1", // Optional claim present when a customer is logged in and your app has permissions to read customer data "sub": "gid://shopify/Customer/" } ``` * #### ##### Description Send the session token to your app backend to identify the signed-in customer. Your backend decodes and verifies the token, then returns the customer ID. This requires \[access to protected customer data]\(/docs/apps/store/data-protection/protected-customer-data). ##### jsx ```jsx import '@shopify/ui-extensions/preact'; import {render} from 'preact'; import {useEffect, useState} from 'preact/hooks'; export default async () => { render(, document.body); }; function Extension() { const [customerId, setCustomerId] = useState(null); useEffect(() => { async function identify() { const token = await shopify.sessionToken.get(); const response = await fetch( 'https://my-app.com/api/customer', { headers: { Authorization: `Bearer ${token}`, }, }, ); const {customerId} = await response.json(); setCustomerId(customerId); } identify(); }, []); return ( {customerId ? `Customer: ${customerId}` : 'Loading...'} ); } ``` *** ## Best practices * **Request tokens close to usage**: Call `shopify.sessionToken.get()` immediately before making a request rather than storing the token for later, since tokens expire after 5 minutes. * **Verify tokens server-side**: Always validate the token signature, expiration (`exp`), and audience (`aud`) on your backend using your app's shared secret. * **Handle token errors gracefully**: Wrap token retrieval and fetch calls in try-catch blocks so your extension can display a meaningful message if authentication fails. *** ## Limitations * Session tokens expire after 5 minutes. Your backend must handle expired tokens and your extension should request a new token for each request. * The `sub` claim is only present when the customer is signed in and your app has the `read_customers` scope. Don't rely on it being available in all contexts. * Session tokens are signed JWTs intended for your backend only. Don't expose sensitive claims to the customer or use them for client-side authorization decisions. ***