> ## Documentation Index
> Fetch the complete documentation index at: https://developer.jtl-software.com/llms.txt
> Use this file to discover all available pages before exploring further.

# GraphQL Conventions

> The naming, structure, and response conventions the JTL GraphQL schema follows, so you can construct a valid query directly from the reference.

The JTL GraphQL schema follows consistent naming, response, and pagination patterns. Once you understand these conventions, you can explore the [Schema Reference](/api-reference/graphql-playground) and build queries directly from the available types and fields.

This guide walks through the conventions you'll see across the GraphQL API. For authentication, request headers, and reusable client configuration, see [Using Platform APIs](/guides/cloud-apps/using-platform-apis#graphql-api).

## Operation Naming

Query and mutation root fields use **PascalCase** with a verb prefix that describes what the operation does. Most operations follow these naming patterns:

| Operation         | Pattern                            | Example                            |
| ----------------- | ---------------------------------- | ---------------------------------- |
| List a resource   | `Query<Entity>`                    | `QueryItems`, `QueryCompanies`     |
| Fetch one by ID   | `Get<Entity>ById`                  | `GetSalesOrderById`, `GetItemById` |
| Create a resource | `Create<Entity>`                   | `CreateCategory`, `CreateItem`     |
| Modify a resource | `Update<Entity>`, `Change<Entity>` | `UpdateCategory`, `ChangeItem`     |

Verbs extend beyond these four where an operation does something more specific. Items are modified with `ChangeItem` rather than `UpdateItem`, suppliers are attached with `AddItemSupplier`, and operations like `CalculateSalesOrder`, `ReleaseProductionOrder`, and `ListTaxClassesWithTaxRates` name the action they perform. Treat the table as the shape to expect, and check the [Schema Reference](/api-reference/graphql-playground) for the exact verb on any specific operation.

A query that lists items begins at the `QueryItems` root field:

```graphql theme={null}
query GetItems {
  QueryItems(first: 10) {
    nodes {
      id
      sku
      name
    }
    totalCount
  }
}
```

## Selection Sets

Every field that returns an object requires a selection set: the nested fields you want back from it.

A field that returns a scalar (a string, number, boolean, or ID) can be queried directly and requires no further nesting. If a field returns an object, you must specify which fields you want from that object. `QueryItems` returns a list object, so the query expands into `nodes`, and each node expands into the fields you want returned:

```graphql theme={null}
query GetItems {
  QueryItems(first: 10) {
    nodes {
      id
      name
    }
    totalCount
  }
}
```

GraphQL lets you request only the fields you need. Listing fewer fields returns a smaller payload; listing more returns more detail in the same request. The operation string is the only thing that changes.

## List Responses

List queries return a connection object with a consistent shape across every resource.

| Field        | Type    | Description                                                  |
| ------------ | ------- | ------------------------------------------------------------ |
| `nodes`      | array   | The records on the current page                              |
| `pageInfo`   | object  | Pagination metadata, including `hasNextPage` and `endCursor` |
| `totalCount` | integer | Total number of matching records across all pages            |

The actual records are returned in the nodes array:

```graphql theme={null}
query GetItems {
  QueryItems(first: 20) {
    nodes {
      id
      sku
      name
    }
    pageInfo {
      hasNextPage
      endCursor
    }
    totalCount
  }
}
```

## Pagination

To fetch large result sets, list queries use cursor-based pagination. You control pagination through query arguments and use the values returned in `pageInfo` to request the next or previous page.

Pass `first` to control how many records are returned. The first request typically omits `after`.

To fetch the next page, take the value of `pageInfo.endCursor` from the previous response and pass it as the `after` argument. Repeat this process until `pageInfo.hasNextPage` is false.

To page backward, use `last` and `before` instead, and use `pageInfo.startCursor` and `pageInfo.hasPreviousPage` to navigate earlier pages.

```graphql theme={null}
query GetItems($first: Int, $after: String) {
  QueryItems(first: $first, after: $after) {
    nodes {
      id
      name
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
```

For the full pagination loop with code samples, see [Pagination](/guides/essentials/common-patterns/pagination).

## Arguments

Operations accept arguments for paging, sorting, and filtering, supplied as GraphQL variables.

Most list queries accept the same paging, sorting, and filtering arguments:

| Argument | Purpose                                                     |
| -------- | ----------------------------------------------------------- |
| `first`  | Page size when paging forward                               |
| `after`  | Cursor marking where the next page begins                   |
| `last`   | Page size when paging backward                              |
| `before` | Cursor marking where the previous page ends                 |
| `order`  | Sort order, as an array of `{ field: ASC \| DESC }` objects |
| `where`  | Filter conditions, using a structured input type            |

Some queries take additional arguments of their own. `QueryItems` and `QueryCustomers`, for example, also accept `searchTerm`, `searchOperator`, and `searchField` for text search. The reference lists the full argument set on each operation.

Sort with `order` and filter with `where`:

```graphql theme={null}
query GetItems($first: Int, $order: [ItemListItemSortInput!], $where: ItemListItemFilterInput) {
  QueryItems(first: $first, order: $order, where: $where) {
    nodes {
      id
      name
    }
    totalCount
  }
}
```

```json theme={null}
{
  "first": 20,
  "order": [{ "name": "ASC" }],
  "where": { "name": { "contains": "T-shirt" } }
}
```

The operators available in a `where` filter depend on the field type.

String fields typically support operators such as `eq`, `neq`, `contains`, `startsWith`, and `in`. Numeric and date fields typically support comparison operators such as `eq`, `gt`, `gte`, `lt`, `lte`, and `in`.

Each field uses a filter type that defines which operators are available. For example, string fields use `StringOperationFilterInput`. Refer to the [Schema Reference](/api-reference/graphql-playground) to see the operators supported by a specific field.

## Input Types

Mutations take their data as a single structured input object rather than loose arguments.

Input type names follow the operation they belong to and end in `Input`, such as `CreateCategoryCommandRequestInput`. A mutation declares the input as a variable, then passes it through:

```graphql theme={null}
mutation CreateCategory($request: CreateCategoryCommandRequestInput) {
  CreateCategory(request: $request) {
    categoryId
  }
}
```

```json theme={null}
{
  "request": {
    "name": "Summer Collection",
    "sortNumber": 1,
    "parentId": null
  }
}
```

The reference lists every field on an input type, which fields are required, and their types. Structure your variables object to match the input type definition shown in the schema.

## Reading the Schema Reference

The schema reference is generated from the live API, so the types and fields you see there reflect the conventions described above.

When you open a type in the [Schema Reference](/api-reference/graphql-playground), apply these conventions to read it:

* Root fields under `Query` are the entry points for reads; root fields under `Mutation` are the entry points for writes. Their names follow the patterns in [Operation Naming](#operation-naming).
* A field's type tells you whether you can request it directly or need to select additional fields from it. Scalar types (`String`, `Int`, `Boolean`, `ID`, and enums) can be requested directly. Object types require a selection set.
* List queries return a connection type carrying `nodes`, `pageInfo`, and `totalCount`.
* A field marked with `!` is non-null. On an input type, a non-null field is required in your variables.
* Arguments and input fields appear alongside each operation, with their own types and required markers.

The [GraphQL Playground](/api-reference/graphql-playground) supports autocomplete and inline schema docs, so you can confirm field names and types as you build a query.

## What's Next

<CardGroup cols={2}>
  <Card title="Using Platform APIs" icon="plug" href="/guides/cloud-apps/using-platform-apis">
    Wire GraphQL into your backend with headers, authentication, and a
    reusable client.
  </Card>

  <Card title="GraphQL Playground" icon="share-2" href="/api-reference/graphql-playground">
    Explore the schema interactively with autocomplete and inline docs.
  </Card>

  <Card title="Pagination" icon="list" href="/guides/essentials/common-patterns/pagination">
    The full cursor-based pagination pattern with code samples.
  </Card>

  <Card title="Error Handling" icon="triangle-alert" href="/guides/essentials/common-patterns/error-handling">
    Error formats, the `errors` array, and retry strategies.
  </Card>
</CardGroup>
