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

# Common Conventions

Plan: B2B Developer

Lesson 4 of 18 · 30 min

## Introduction

There are a few concepts and techniques that are broadly applicable to the B2B GraphQL API and to the examples included in this course. In this section, we'll explore these common conventions.

## GraphQL Variables

Many GraphQL mutations and queries accept arguments, such as the `storeHash`, `email`, and `password` arguments of the `login` mutation.

```graphql showLineNumbers={false}
mutation {
    login(
        loginData: {
            storeHash: {Store Hash},
            email: {Email address},
            password: {Password}
        }
    ) {
        ...
    }
}
```

The values for such arguments are often user-provided input. While argument values can be interpolated directly in the query as shown above, it's often a better practice to utilize GraphQL variables.

Below is an example of the same mutation, but with the query syntax accepting and using variables of the appropriate types:

```graphql showLineNumbers={false}
mutation LogIn(
    $storeHash: String!,
    $email: String!,
    $password: String!
) {
    login(
        loginData: {
            storeHash: $storeHash,
            email: $email,
            password: $password
        }
    ) {
        ...
    }
}
```

When using variables in this way, provide a `variables` dictionary in the JSON request body, alongside the `query` string itself. `variables` should itself be a JSON object of key/value pairs:

```json showLineNumbers={false}
{
    "storeHash": "pki...",
    "email": "user@example.com",
    "password": "MyPassword123..."
}
```

Most API clients, such as Postman, support a dedicated UI for entering both the GraphQL query and the variables JSON.

All examples in this course will utilize GraphQL variables for arguments.

## Cursor Lists and Pagination

All queries that return a list of items utilize the same [Cursor Connections](https://relay.dev/graphql/connections.htm) pattern, linking each item to the next in the list, providing information about whether further results are available, and exposing filtering arguments for pagination.

Observe this simple example of a query for a list of items (company users in this case):

```graphql showLineNumbers={false}
query GetUsers(
    $companyId: Int!
) {
    users(
        companyId: $companyId,
        first: 10
    ) {
        pageInfo {
            hasNextPage
            hasPreviousPage
            startCursor
            endCursor
        }
        totalCount
        edges {
            cursor
            node {
                id
            }
        }
    }
}
```

* The `edges` field contains the actual list of items, each of which has a unique `cursor`.
* The `pageInfo` field contains metadata about the list, including whether there are other results available before or after the cursors represented in the current result set (`hasNextPage` and `hasPreviousPage`), as well as the starting and ending cursors from the current result set (`startCursor` and `endCursor`).
* `totalCount` reports the total number of available results, regardless of how many the current result set includes.
* In addition to `cursor`, each item in the results contains a `node`, which is an object of the unique GraphQL type returned by this particular query/field (`UserType` in this case).
* The `first` argument provided to `users` indicates the number of results that should be fetched in this set (10 in this case).

### Paginating Results

Next or previous "pages" of results can be queried by using standard filter arguments along with the cursor values.

Given the example query above, say that the results included a `hasNextPage` value of TRUE and an `endCursor` value of "abc123". The next set of results can be fetched using the `after` argument.

## Example Request:

```graphql showLineNumbers={false}
query GetUsers(
    $companyId: Int!,
    $after: String
) {
    users(
        companyId: $companyId,
        after: $after,
        first: 10
    ) {
        pageInfo {
            hasNextPage
            hasPreviousPage
            startCursor
            endCursor
        }
        totalCount
        edges {
            cursor
            node {
                id
            }
        }
    }
}
```

## Example Variables:

```json showLineNumbers={false}
{
    "companyId": 1112233,
    "after": "abc123"
}
```

This combination of `first` and `after` effectively translates to "give me the first 10 results after cursor 'abc123'."

In the same way, `hasPreviousPage` will report if there are results `before` the current set, and the value of `startCursor` can then be used with the `before` argument, in combination with `last`.

## Example Request:

```graphql showLineNumbers={false}
query GetUsers(
    $companyId: Int!,
    $before: String
) {
    users(
        companyId: $companyId,
        before: $before,
        last: 10
    ) {
        pageInfo {
            hasNextPage
            hasPreviousPage
            startCursor
            endCursor
        }
        totalCount
        edges {
            cursor
            node {
                id
            }
        }
    }
}
```

Assuming "abc123" was the `first` cursor in the current result set, using the query above with that value would translate to "give me the last 10 results before cursor 'abc123'."

In addition to the standard `first`, `last`, `before`, and `after` arguments from the Cursor Connections specification, all cursor lists in the B2B GraphQL API also support the `offset` argument for a different style of paging.

## Example Request:

```graphql showLineNumbers={false}
query GetUsers(
    $companyId: Int!,
    $offset: Int
) {
    users(
        companyId: $companyId,
        offset: $offset,
        first: 10
    ) {
        ...
    }
}
```

The above query fetches 10 results offset from the first result by the value of `offset`. For example, the second page of results would be fetched by passing in an `offset` of 10 in this case (the first 10 results offset by 10). This pattern also allows for directly fetching the third page of results (`offset` 20), fourth page of results (`offset` 30), and so on, without knowing the specific item cursors.

Again, all cursor lists in the B2B GraphQL API utilize these same pagination arguments.

## Store Hash and Channel ID

Two values that are required or available in many queries or mutations are your store's unique "store hash" and the ID of the BigCommerce channel associated with a specific storefront.

### Store Hash

Many queries or mutations require a `storeHash` argument identifying your store. The easiest way to find your unique store hash is in the BigCommerce control panel, where this value is represented in the URL, formatted like `https://store-{hash}.mybigcommerce.com/manage/...`

![Finding the store hash in the control panel](/_fern-img/cc83011a7bf719c8a46df6ebd20cbb7779a4bf9e9f9d76a629b6a43bc7f4fdf0.webp)

This hash will never change for a particular store, and this value should typically be a static configuration value in your application.

### Channel ID

Some queries include a `channelId` argument that can be used to filter results or a `channelId` field that can be queried as part of those results.

This value is only relevant when Multi-Storefront is enabled for your store and multiple storefronts have B2B Edition enabled. `channelId` identifies the specific storefront channel an entity is associated with. For example, when querying quotes, `channelId` will indicate which storefront channel a quote was created for:

```graphql showLineNumbers={false}
query {
    quotes {
        edges {
            node {
                id
                channelId
            }
        }
    }
}
```

The examples in this course will not specifically focus on multi-storefront scenarios and will not include `channelId`, but you can review the details of any query or mutation in the [GraphQL Playground](https://api-b2b.bigcommerce.com/graphql/playground) to determine if `channelId` is supported.

## Extra Data Fields

B2B Edition supports adding custom "Extra Fields" to several types of entities in the control panel, in order to store information unique to a merchant's own needs and implementation.

The GraphQL API supports querying these extra fields, allowing you to utilize them for whatever purposes make sense in your own implementation.

## Example Request:

```graphql showLineNumbers={false}
query GetInvoices {
    invoices {
        edges {
            node {
                extraFields {
                    fieldName
                    fieldValue
                }
            }
        }
    }
}
```

See the schema/docs in the GraphQL Playground for full details on which types support `extraFields`.

Some B2B entities also include arbitrary fields directly on the entity (for example, `extraInt1`) for custom integrations to utilize. While multiple entities support populating these fields using the REST Management API, currently only orders allow them to be queried from the storefront context using GraphQL.

## Example Request:

```graphql showLineNumbers={false}
query {
    allOrders {
        edges {
            node {
                extraInt1
                extraInt2
                extraInt3
                extraInt4
                extraInt5
                extraStr1
                extraStr2
                extraStr3
                extraStr4
                extraStr5
            }
        }
    }
}
```

## Resources

* [GraphQL Cursor Connections Specification](https://relay.dev/graphql/connections.htm)
* [B2B GraphQL Playground](https://api-b2b.bigcommerce.com/graphql/playground)