> This page is for Developer.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.bigcommerce.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.bigcommerce.com/_mcp/server.

# Customer context in the GraphQL Storefront API

Many GraphQL Storefront API requests can carry a **customer context**: the identity of a signed-in shopper. Customer context is separate from the bearer token you use to [authenticate the request](/developer/docs/storefront/guides/graphql-storefront-api/authentication). A storefront token, private token, or customer impersonation token authorizes your application to call the API at all; customer context tells the API *which shopper* the request represents.

Customer context affects requests in two distinct ways:

* **It can change the response.** Many queries return data regardless of whether a customer is signed in, but return *different* data when one is. For example, you can query product data with no customer context, but a signed-in customer who belongs to a price list receives their customer-specific pricing in the same query. The operation works either way; the customer context only changes what comes back.
* **It can be required for the operation to work at all.** Some queries and mutations do nothing, return empty data, or error without a customer context. Many of these are self-evident, such as reading the `customer` object or running `addCustomerAddress`. Others are not: the `registerCompany` mutation, for instance, must be called as a signed-in customer.

If an operation returns empty data or an authentication error when you expected results, confirm that you're sending a customer context. The [Operations that require customer context](#operations-that-require-customer-context) table lists the known cases.

## How customer context is established

You establish customer context differently depending on where your code runs and what kind of authentication token you're using.

### Client-side: the session cookie

On a Stencil storefront, customer context travels in a **session cookie**. The cookie is set automatically when a customer signs in through the [login mutation](/developer/docs/storefront/guides/graphql-storefront-api/authentication#signing-customers-in), and the browser sends it with subsequent GraphQL requests. This is the same session cookie the storefront already tracks for the shopper, so a customer who is signed in to the storefront is automatically in context for client-side GraphQL requests. You don't manage the cookie yourself; the browser and the storefront handle it.

> **Warning**
>
> The session cookie is reliable only on a Stencil storefront, where your GraphQL requests share the storefront's domain. On a separate domain, such as a headless storefront, browser restrictions on cross-domain cookies make it unreliable. For client-side requests from another domain, or for any server-side request, use a customer access token instead.

### Server-side: the customer access token

For server-to-server requests there is no browser session cookie, so you supply customer context explicitly with the `X-Bc-Customer-Access-Token` header. You obtain the token value with a login mutation and send it alongside your private token. The rest of this page covers how to obtain and use a [customer access token](#customer-access-tokens).

### Server-side: a customer ID header

A customer impersonation token allows you to provide customer context a third way: you send the target customer's ID in the `X-Bc-Customer-Id` header, and the token authorizes the request to act as that customer without a customer login. Because a single customer impersonation token can assume the context of *any* customer, it is a highly sensitive credential and must stay server-side. For how to create and use one, see [Customer impersonation tokens](/developer/docs/storefront/guides/graphql-storefront-api/authentication#customer-impersonation-tokens) on the Authentication page.

## Operations that require customer context

The following operations only return meaningful data, or only work at all, when the request carries a customer context.

> **Warning**
>
> This list may not be exhaustive. If you find an operation that requires customer context and isn't listed here, [let us know](/developer/docs/overview/support).

| Operation                                         | Notes                                                                                                                                               |
| ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Query.customer`                                  | The currently signed-in customer and its subfields (addresses, orders, attributes, stored payment instruments, wishlists).                          |
| `Query.company`                                   | B2B company queries for the authenticated customer.                                                                                                 |
| `Mutation.customer.changePassword`                | Changes the signed-in customer's password.                                                                                                          |
| `Mutation.customer.updateCustomer`                | Updates the signed-in customer's account.                                                                                                           |
| `Mutation.customer.addCustomerAddress`            | Manages the signed-in customer's address book.                                                                                                      |
| `Mutation.customer.updateCustomerAddress`         | Manages the signed-in customer's address book.                                                                                                      |
| `Mutation.customer.deleteCustomerAddress`         | Manages the signed-in customer's address book.                                                                                                      |
| `Mutation.customer.updateStoredPaymentInstrument` | Manages the signed-in customer's stored payment instruments.                                                                                        |
| `Mutation.customer.deleteStoredPaymentInstrument` | Manages the signed-in customer's stored payment instruments.                                                                                        |
| `Mutation.company.registerCompany`                | Must run as a signed-in customer.                                                                                                                   |
| `Mutation.company.updateCompanyUser`              | Updates the authenticated company user's account.                                                                                                   |
| `Mutation.wishlist.*`                             | `createWishlist`, `addWishlistItems`, `updateWishlist`, `deleteWishlistItems`, and `deleteWishlists` all act on the signed-in customer's wishlists. |

By contrast, operations that create or recover an account do **not** require an existing customer context, because you use them precisely when no customer is signed in yet: `registerCustomer`, `login`, `loginWithCustomerLoginJwt`, `requestResetPassword`, and `resetPassword`.

## Customer access tokens

A customer access token is unique to an individual user's account because it represents an authenticated storefront session for GraphQL requests. You can obtain and use a customer access token only for server-to-server requests. Therefore, you must use the customer access token alongside a [private token](/developer/docs/storefront/guides/graphql-storefront-api/authentication#private-tokens). A customer access token becomes invalid on all devices when you log out of a single device, and also when the customer signs in again through any sign-in method: each sign-in rotates the session and invalidates every token previously issued for the account. For details, see [Customer session behavior](/developer/docs/storefront/guides/customer-authentication/customer-login#customer-session-behavior).

> **Note**
>
> Do not use this token for client-side requests.

### Obtaining a customer access token

There are two options to obtain a customer access token.

1. Login mutation
2. Login with a JWT

#### Login mutation

Enter your user email and password to use the login mutation. When using the login mutation in a server-to-server context, the mutation will return a customer access token in response to login actions as part of the GraphQL body instead of a cookie header. From there, you can store the customer access token in the presentation layer's session management system and send it with future GraphQL requests. If the login mutation request is from a browser, we will not return the customer access token in the body, and will instead set a cookie.

> **Note**
>
> * Use the [Create a Token](/developer/api-reference/rest/admin/authentication-apis/storefront-api-tokens/create-token) endpoint to generate a storefront bearer token, or the [Create a Private Token](/developer/api-reference/rest/admin/authentication-apis/storefront-api-tokens/private-api-token/create-private-token) endpoint to generate a private token, needed to run the login mutation call.
>
> * If you request a customer access token in wrong communication context, you will receive the following error:
>   ***Customer access token was requested in the body, but it's only returned for server-to-server requests. For browser requests it's set as an httpOnly cookie instead.***
>
> * If you still have issues creating a customer access token, we recommend clearing your cookies to resolve any loading issues.

#### Request

**`Example login mutation: Create a customer access token`**

```graphql title="Example login mutation: Create a customer access token" showLineNumbers={false}
# Creates a customer access token
POST https://{{storeDomain}}/graphql
Authorization: Bearer {Private token}
accept: application/json
content-type: application/json

mutation Login($email: String!, $pass: String!) {
 login(email: $email, password: $pass) {
   result
   customer {
     entityId
     email
   }
   customerAccessToken {
     value
     expiresAt
   }
 }
}
```

**`GraphQL variables`**

```json title="GraphQL variables" showLineNumbers={false}
{
    "email": "user@email.com",
    "pass": "password"
}
```

#### Response

**`Example login mutation: Create a customer access token`**

```json title="Example login mutation: Create a customer access token" showLineNumbers={false}
{
    "data": {
        "login": {
            "result": "success",
            "customer": {
                "entityId": 21,
                "email": "user@email.com"
            },
            "customerAccessToken": {
                "value": "53ea9099d5484cdedddbf8f59a73bc284afefd7943c4dbe578db52435e0c0de7_1721406629",
                "expiresAt": "2024-07-19T16:30:29Z"
            }
        }
    }
}
```

#### Login with a JWT

There are two options for logging in using a JWT.

1. Customer Login API

The Customer Login API enables third-party services to securely authenticate a logged-in customer by accepting a signed JWT from BigCommerce. This allows the third party to verify the customer’s identity before granting access to sensitive information. For more details, see the [Customer Login API](/developer/docs/storefront/guides/customer-authentication/customer-login) article.

2. `loginWithCustomerLoginJwt`

The `loginWithCustomerLoginJwt` mutation allows you to pass a customer JSON web token instead of the user's email and password. A 3rd party signs the JSON web token used. In this scenario, you will generate a JWT that contains key information in the payload for the login to be successful. You will use this JWT in the login mutation to receive a customer access token. For instructions on creating a JWT, see the [Customer Login API](/developer/docs/storefront/guides/customer-authentication/customer-login) article for instructions.

#### Request

**`Example JWT login mutation: Create a customer access token`**

```graphql title="Example JWT login mutation: Create a customer access token" showLineNumbers={false}
# Creates a customer access token
POST https://{{storeDomain}}/graphql
Authorization: Bearer {Private token}
accept: application/json
content-type: application/json

mutation Login($jwt: String!) {
 loginWithCustomerLoginJwt(jwt: $jwt) {
   customer {
     entityId
     email
   }
   customerAccessToken {
     value
     expiresAt
   }
 }
}
```

**`GraphQL variables`**

```json title="GraphQL variables" showLineNumbers={false}
{"jwt": "your_jwt_token"}
```

#### Response

**`Example JWT login mutation: Create a customer access token`**

```json title="Example JWT login mutation: Create a customer access token" showLineNumbers={false}
{
    "data": {
        "loginWithCustomerLoginJwt": {
            "customer": {
                "entityId": 22,
                "email": "user@email.com"
            },
            "customerAccessToken": {
                "value": "ee973d6566a7c691af4602f344d866ecaa45bdcbdf2075d29d5e70fd0716b7c5_1721657159",
                "expiresAt": "2024-07-22T14:05:59Z"
            }
        }
    }
}
```

### Using a customer access token

You can assign the customer access token obtained using one of the mutations described above to the `X-Bc-Customer-Access-Token` header for future queries. You can use this token until it is invalidated or until it expires. The token is invalidated when the customer signs out or signs in again, even if its `expiresAt` value is still in the future. Each sign-in for the customer account issues a new token and invalidates all previously issued tokens for that account.

> **Note**
>
> Requests that carry an invalidated customer access token do not fail. The API processes the request as an anonymous shopper: the `customer` field returns `null`, and customer-specific values, such as customer-group pricing, fall back to guest values. To make such requests return an explicit error instead, send the `X-BC-Error-On-Invalid-Customer-Access-Token` header with a value of `true`. For details, see [Customer session behavior](/developer/docs/storefront/guides/customer-authentication/customer-login#customer-session-behavior).

#### Request

**`Example customer query`**

```graphql title="Example customer query" showLineNumbers={false}
POST https://{{storeDomain}}/graphql
Authorization: Bearer {Private token}
X-Bc-Customer-Access-Token: {Customer access token}
accept: application/json
content-type: application/json

query CustomerAttributes {
  customer {
    firstName
    lastName
    email
    entityId
    customerGroupId
    attributeCount
    attributes {
      shirtSize: attribute(entityId:123) {
        entityId
        value
      }
      favoriteColor: attribute(entityId:456) {
        entityId
        value
      }
    }
  }
}
```

#### Response

**`Example customer query`**

```json title="Example customer query" showLineNumbers={false}
{
    "data": {
        "customer": {
            "firstName": "John",
            "lastName": "Doe",
            "email": "john.doe@example.com",
            "entityId": 21,
            "customerGroupId": 2,
            "attributeCount": 0,
            "attributes": {
                "shirtSize": {
                    "entityId": 123,
                    "value": "medium"
                },
                "favoriteColor": {
                    "entityId": 456,
                    "value": "blue"
                }
            }
        }
    }
}
```

## Further reading

* [Authenticating requests to the GraphQL Storefront API](/developer/docs/storefront/guides/graphql-storefront-api/authentication)
* [Signing customers in](/developer/docs/storefront/guides/graphql-storefront-api/authentication#signing-customers-in)
* [Customer impersonation tokens](/developer/docs/storefront/guides/graphql-storefront-api/authentication#customer-impersonation-tokens)
* [GraphQL API reference](/developer/api-reference/graphql)