Skip to main content

GraphQL API Reference

Unchained Engine exposes its GraphQL API at /graphql, built with GraphQL Yoga.

Explore the full schema

This page only covers the high-traffic operations of a typical storefront flow. The complete schema is self-documenting: open /graphql of your running engine in a browser for the interactive GraphiQL explorer with auto-completion and inline docs, or use standard GraphQL introspection with your tool of choice.

Custom Scalars​

ScalarDescription
JSONArbitrary JSON object
DateTimeISO 8601 date-time string
DateDate value
TimestampMilliseconds since UNIX epoch (integer)
LowerCaseStringString that enforces lowercase
LocaleBCP 47 locale code (e.g., en, de-CH)
PhoneNumberPhone number string

Directives​

@cacheControl​

Controls HTTP caching behavior for fields and types:

directive @cacheControl(maxAge: Int, scope: CacheControlScope) on FIELD_DEFINITION | OBJECT

Scope values: PUBLIC, PRIVATE

Conventions​

  • List queries take limit, offset, and sort: [SortOptionInput!] and have a matching ...Count query (products/productsCount, orders/ordersCount, ...).
  • Cart mutations take an optional orderId. If omitted, they operate on the current user's active cart.
  • Login-style mutations return a LoginMethodResponse (_id, tokenExpires, user) — the session JWT is set as an HTTP-only cookie, see Authentication.

Authentication​

mutation LoginAsGuest {
loginAsGuest {
_id
tokenExpires
}
}
mutation Login {
loginWithPassword(email: "user@example.com", password: "securepassword") {
_id
tokenExpires
}
}

All strategies (email/password, WebAuthn, OIDC, access tokens) are covered in Authentication.

Browse & Search Products​

OperationArgumentsDescription
productproductId: ID, slug: StringGet product by ID or slug
productsqueryString, tags, slugs, limit = 10, offset = 0, includeDrafts = false, sortList published products
productsCounttags, slugs, includeDrafts, queryStringCount products
searchProductsqueryString, filterQuery, assortmentId, orderBy, includeInactive = false, ignoreChildAssortments = falseFaceted search, returns ProductSearchResult
assortmentassortmentId: ID, slug: StringGet assortment (category) by ID or slug
query Search {
searchProducts(queryString: "shirt", filterQuery: [{ key: "color", value: "red" }]) {
filteredProductsCount
filters {
definition {
_id
}
}
products(limit: 10) {
_id
texts {
title
slug
}
... on SimpleProduct {
simulatedPrice {
amount
currencyCode
}
}
}
}
}

texts, media, reviews, and assortmentPaths live on the Product interface; prices (catalogPrice, simulatedPrice) are declared on the concrete types (SimpleProduct, PlanProduct, BundleProduct, TokenizedProduct) and need inline fragments.

Build a Cart​

MutationArgumentsDescription
addCartProductorderId, productId!, quantity = 1, configurationAdd product (creates cart if needed)
addMultipleCartProductsorderId, items!Add multiple products
updateCartItemitemId!, quantity, configurationChange quantity/configuration
removeCartItemitemId: ID!Remove item
emptyCartorderIdRemove all items
addCartDiscountorderId, code!Apply discount code
removeCartDiscountdiscountId: ID!Remove discount
updateCartorderId, billingAddress, contact, meta, paymentProviderId, deliveryProviderIdSet address, contact, providers
updateCartDeliveryShippingorderId, deliveryProviderId!, address, metaConfigure shipping delivery
updateCartDeliveryPickUporderId, deliveryProviderId!, orderPickUpLocationId!, metaConfigure pickup delivery
updateCartPaymentInvoiceorderId, paymentProviderId!, metaConfigure invoice payment
updateCartPaymentGenericorderId, paymentProviderId!, metaConfigure generic (gateway) payment
mutation AddToCart {
addCartProduct(productId: "product-id", quantity: 2) {
_id
quantity
total {
amount
currencyCode
}
}
}
mutation SetCheckoutDetails {
updateCart(
billingAddress: { firstName: "John", lastName: "Doe", addressLine: "Main St 1", postalCode: "8000", city: "Zurich" }
contact: { emailAddress: "user@example.com" }
paymentProviderId: "payment-provider-id"
deliveryProviderId: "delivery-provider-id"
) {
_id
total {
amount
currencyCode
}
}
}

Checkout​

For gateway payments (Stripe, Datatrans, ...), first sign the order payment with the provider — the returned string is the provider-specific payload for the client SDK:

mutation Sign {
signPaymentProviderForCheckout(transactionContext: {})
}

Then check out — the cart becomes an order, charging and delivery are triggered automatically where possible:

mutation Checkout {
checkoutCart(paymentContext: {}) {
_id
orderNumber
status
}
}

checkoutCart(orderId: ID, paymentContext: JSON, deliveryContext: JSON): Order! — the contexts are passed through to the payment/delivery plugins.

Current User & Orders​

query Me {
me {
_id
primaryEmail {
address
}
cart {
_id
items {
_id
quantity
}
total {
amount
currencyCode
}
}
orders(includeCarts: false) {
_id
orderNumber
status
}
}
}

Administrators can list all orders with orders(limit, offset, includeCarts, queryString, status, sort, paymentProviderIds, deliveryProviderIds, dateRange) and fetch a single one with order(orderId: ID!).