For the complete documentation index, see llms.txt. This page is also available as Markdown.

GraphQL API

Fetch nested OMS data in a single request with the read-only GraphQL API. Endpoint, authentication, response envelope, and the query cost limits.

The GraphQL API is a read-only query layer over the HotWax Commerce OMS data model. A single request can return an order, its line items, its ship groups, each ship group's origin address and shipping method, and the bill-to customer, instead of the five or six REST calls the same screen needs today.

It is modeled on the Shopify Admin GraphQL API: a curated schema, cursor-based pagination, a query: search string, and a query cost budget. Field names are the OMS data model names you already know from the REST APIs, and IDs are raw entity keys.

What it is not

  • It does not write. There are no mutations. Every create, update, and cancel stays on the existing REST APIs.

  • It is not entity access. Only the objects and edges declared in the schema can be reached. If a field is not in the schema reference, it cannot be queried, and there is no way to reach it by nesting.

  • It is not a search engine. Filtering is exact-match on a fixed set of declared keys. Full-text search, facets, and relevance ranking stay on the existing Solr-backed APIs.

Endpoint

Method
Path
Authentication

POST

https://<instance>.hotwax.io/rest/s1/graphql

Bearer token required

GET

https://<instance>.hotwax.io/rest/s1/graphql/sdl

None

The POST endpoint executes queries. The GET /sdl endpoint returns the schema definition language (SDL) for the exact schema that instance is running, and needs no token, so you can point tooling at it before you have credentials. See Keeping the reference current.

Authentication

The POST endpoint uses the same Bearer token as every other HotWax API. See Authentication for how to generate one.

Authorization: Bearer <token>
Content-Type: application/json

Access is granted per user group on the /graphql REST path. If your integration user is authenticated but receives an authorization failure, its user group has not been granted access to the GraphQL artifact group yet.

Request body

query is required. variables and operationName are optional.

Response envelope

Every response carries up to three top-level keys.

Key
Meaning

data

The result tree, shaped exactly like the query. null when the query was refused.

errors

Present only when something went wrong. Each entry has a message and an extensions.code.

extensions

Always present on an executed query. Carries cost, including the live rate-limit state.

Value formats

GraphQL type
Serialized as
Example

ID, String

JSON string

"10001"

Int

JSON number

2

Decimal

JSON string

"129.00"

DateTime

ISO-8601 string

"2026-05-14T09:32:00Z"

Money and quantities are Decimal and arrive as strings, so no precision is lost in transit. Parse them with a decimal-safe library rather than casting to a float.

Error codes

Errors carry a stable extensions.code you can branch on. All of these are decided before the query touches the database, so a refused query costs nothing and changes nothing.

Code
Meaning
Fix

FIRST_REQUIRED

A connection was requested without first: or last:

Add a page size

FIRST_TOO_LARGE

A page size above the maximum of 100

Request at most 100 and page

COST_EXCEEDED

The query's estimated cost is over the budget of 1000

Reduce nested page sizes, or select fewer nested collections

DEPTH_EXCEEDED

More than 6 levels of object nesting

Split into two queries

FIELD_NOT_FILTERABLE

A query: key that is not declared for that root

Use a declared search key

OPERATOR_NOT_ALLOWED

A comparator the key does not accept

Use an accepted comparator

THROTTLED

The caller's cost budget is exhausted

Back off and retry

MALFORMED_QUERY

A query: term that is not key:value

Fix the search string

DEADLINE_EXCEEDED

The request ran past its wall-clock budget

Narrow the query

Limits

Two independent limits protect the OMS: a per-query ceiling and a per-caller rate limit. Both are denominated in the same cost number.

Limit
Default
Effect

Maximum query cost

1000

A single query above this is refused with COST_EXCEEDED

Maximum page size

100

first: and last: above this are refused, on root and nested collections

Maximum nesting depth

6

Object nesting only; edges and node do not count

Rate limit bucket

1000 credits

Refills at 50 credits per second

Cost is estimated from the shape of the query, not from how many rows come back:

  • A scalar field costs 1.

  • A single object costs 1 + the cost of its selection.

  • A collection costs its page size × (1 + the cost of one node). Nested collections therefore multiply.

  • An aggregate field such as orderItemCount costs 5.

  • Filtering on a key that is not index-backed, such as statusId or orderDate, adds 50.

The practical rule: ask for the page size you actually need. Requesting first: 10 on ship groups and first: 20 on each ship group's items costs over 1300 and is refused; first: 5 and first: 10 returns the same screen's worth of data for 431. Query examples works through the arithmetic.

Rate limiting

Each caller has a credit bucket. Every executed query debits its cost; the bucket refills continuously. A query that the bucket cannot cover is refused with THROTTLED and is not charged, so a throttled caller never falls further behind.

Every response reports the live bucket, so a client can pace itself instead of guessing:

To recover 500 credits at a restoreRate of 50, wait 10 seconds. Integrations that page through large result sets should read currentlyAvailable after each page and pause when it runs low, rather than retrying blindly.

Limits can be raised for a specific integration user, so a nightly bulk sync does not have to run inside the interactive default. Raise that with your HotWax contact rather than working around the limit with many small queries.

When to use GraphQL instead of REST

Use GraphQL when
Use the REST APIs when

You need a parent and its children together

You need one flat collection

You are making several dependent calls and joining them in your own code

You are writing data

You want to page deeply through a large result set with stable cursors

You need text search, facets, or relevance

You want only a few fields from a wide object

You need an object or field the schema does not expose

Next steps

Last updated

Was this helpful?