Skip to main content

GraphQL Overview

The GraphQL API provides a typed alternative to the REST API.

GraphQL is a data query and manipulation language that allows specifying what data is to be retrieved ("declarative data fetching") or modified.

It is available at:

POST/gql/v1
  • Authentication: add Authorization: Bearer <token> header for all data operations
  • Introspection: allowed without authentication (schema fetch only)

Headers​

All secured operations require the Authorization header:

{
"Authorization": "Bearer YOUR_ACCESS_TOKEN"
}

Take a look at the authentication guide for details on obtaining an access token.

Quick start (cURL)​

curl -X POST https://api.axro.com/gql/v1 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"query": "query { products(page:1, limit:5) { totalPages products { productNumber brand stock } } }"
}'

Queries​

products​

List products with filtering and pagination.

All arguments are optional.

NameTypeRequiredDescription
formatstring❌Response format: 'json' (default) or 'xml' (BMEcat 2005 format)
product_numberstring❌Filter by single or comma-separated AXRO product numbers (e.g., 'CANL055BK' or 'CANL055BK,CANL056WH')
oemstring❌Filter by single or comma-separated OEM numbers (e.g., '3016C002' or '3016C002,CF540A')
eanstring❌Filter by single or comma-separated EAN numbers (e.g., '4549292124699' or '4549292124699,4549292124706')
brandstring❌Filter by single or comma-separated brand names (e.g., 'HP,Canon,Epson')
categorystring❌Filter by single or comma-separated category IDs (e.g., '50593,50638')
pagestring❌Page number for pagination (default: 1)
limitstring❌Number of items per page (default: 100)

Example Request​

query {
products(page: 1, limit: 10, brand: "HP") {
totalPages
products {
productNumber
ean
brand
stock
price { fromQuantity toQuantity price }
title { enGb deDe }
category { id en de }
categories { id en de }
attributes { id name attributes { id title value } }
modifiedAt
}
}
}

Example Response​

{
"data": {
"products": {
"totalPages": 120,
"products": [
{
"productNumber": "CANT7260C",
"brand": "Canon",
"oemNumber": "6944B002",
"stock": 0,
"price": [],
"title": {
"enGb": "Canon Toner C-EXV45 / 6944B002 Cyan (6944B002/6944B002AA)",
"deDe": "Canon Toner C-EXV45 / 6944B002 Cyan (6944B002/6944B002AA)"
},
"category": {
"id": 51158,
"de": "Kopiertoner",
"en": "Copy toner"
},
"categories": [
{
"id": 51158,
"de": "Kopiertoner",
"en": "Copy toner"
},
{
"id": 23,
"de": "Tinten & Toner",
"en": "Inks & Toner"
}
],
"attributes": [
{
"id": 37,
"name": "Packaging Data",
"attributes": [
{
"id": 519,
"title": "Type of packaging",
"value": "Box"
}
]
},
{
"id": 35,
"name": "Weight and Dimensions",
"attributes": [
{
"id": 203,
"title": "Weight",
"value": "4.5 kg"
},
{
"id": 225,
"title": "Depth",
"value": "430 mm"
}
]
}
],
"modifiedAt": "2025-09-29 20:46:01+00:00"
}
]
}
}
}

IMPORTANT Deprecation notice: Field category in the response will be removed in future versions. Use categories instead! It holds the same categories, and category is simply the first entry of that list.

Product attributes​

attributes mirrors the REST products endpoint: every entry is an attribute group (id, name) holding its own attributes (id, title, value). Groups are sorted by name, attributes by id. Values are always strings, also for numeric data, and a product without technical data returns an empty list.

productStocks​

Bulk stock lookup for many products at once.

  • Input: items (max 5000) where each element contains exactly one identifier:
    • productNumber
    • ean
    • oem
    • fsku
  • You can mix identifier types in the same request.
  • Output is returned in the same order as input.
  • Per-row failures are returned via error (other rows still succeed).

Example Request​

query {
productStocks(items: [
{ productNumber: "CANL055BK" }
{ ean: "4549292124699" }
{ oem: "3016C002" }
{ fsku: "FSKU-999" }
]) {
product
stock
error
}
}

Example Response​

{
"data": {
"productStocks": [
{ "product": "CANL055BK", "stock": 42, "error": null },
{ "product": "4549292124699", "stock": 10, "error": null },
{ "product": "3016C002", "stock": 7, "error": null },
{ "product": "FSKU-999", "stock": 0, "error": "fsku_not_found" }
]
}
}

Error codes:

  • not_found
  • fsku_not_found

categories​

List all available categories.

Example Request​

query {
categories {
id
de
en
}
}

Example Response​

{
"data": {
"categories": [
{
"id": 83104,
"de": "SD-Karten",
"en": "SD cards"
},
{
"id": 83170,
"de": "Autorennbahnen",
"en": "Car racetracks"
}
]
}
}

brands​

List available brands for the current user (after applying visibility rules).

Example Request​

query {
brands {
brands
}
}

Example Response​

{
"data": {
"brands": {
"brands": [
"Acer",
"IBM",
"Utax"
]
}
}
}

fskuMappings​

List fSKU → product number mappings for the current user.

Arguments (all optional):

NameTypeRequiredDescription
pageInt❌Page number for pagination (default: 1)
limitInt❌Number of items per page (default: 10000, max: 50000)
qString❌Optional substring filter applied to fsku or productNumber

Example Request​

query {
fskuMappings(page: 1, limit: 100, q: "AXRO") {
mappings {
fsku
productNumber
}
page
limit
total
totalPages
}
}

Example Response​

{
"data": {
"fskuMappings": {
"mappings": [
{ "fsku": "FSKU-999", "productNumber": "AXRO123" }
],
"page": 1,
"limit": 100,
"total": 1,
"totalPages": 1
}
}
}

userInfo​

Basic info about the current user.

Example Request​

query {
userInfo {
email
customer {
company
}
billingAddress {
company
street
zip
city
country
}
}
}

Example Response​

{
"data": {
"userInfo": {
"email": "user@example.com",
"customer": {
"company": "Example Corp"
},
"billingAddress": {
"company": "Example Corp",
"department": "Purchasing",
"street": "123 Example St",
"zip": "10001",
"city": "New York",
"country": "US"
}
}
}
}

billingAddress​

Retrieve the billing address for the current user.

Example Request​

query {
billingAddress {
company
department
street
zip
city
country
}
}

Example Response​

{
"data": {
"billingAddress": {
"company": "Example Corp",
"department": "Accounting",
"street": "456 Bill St",
"zip": "10002",
"city": "New York",
"country": "US"
}
}
}

shippingAddresses​

List shipping addresses for the current user.

Example Request​

query {
shippingAddresses {
id
company
department
street
zip
city
country
phone
email
status
info
}
}

Example Response​

{
"data": {
"shippingAddresses": [
{
"id": "7284adc6-db5f-55c1-9511-4d12b3a356f1",
"company": "Example Corp",
"department": "Logistics",
"street": "123 Shipping Ln",
"zip": "10001",
"city": "New York",
"country": "US",
"email": "logistics@example.com",
"phone": "+15551234",
"status": "WAITING_APPROVAL",
"info": "Please wait for approval."
}
]
}
}

orderList​

List orders for the current customer (via information service).

Arguments (all optional):

NameTypeRequiredDescription
pageInt❌Page number (default: 1)
commissionString❌Filter orders by commission

Response includes:

  • orders: [OrderItem]
  • totalPages: Int
  • error: String (nullable) — present on 400 responses; other errors appear as top-level GraphQL errors

Example Request​

query {
orderList(page: 1, commission: "BR1234") {
totalPages
orders {
orderNumber
date
commission
currency
orderTotal
orderSource
}
}
}

Example Response​

{
"data": {
"orderList": {
"orders": [
{
"orderNumber": "522214",
"date": "2025-08-19",
"commission": "25310133",
"currency": "EUR",
"orderTotal": 247326,
"orderSource": "Webshop"
}
],
"totalPages": 1,
"error": null
}
}
}

orderDetails​

Retrieve order details by order number.

Response includes:

  • orderNumber: String
  • order: OrderDetailMessage
  • error: String (nullable) — present on 400 responses; other errors appear as top-level GraphQL errors

Example Request​

query {
orderDetails(orderNumber: "1234567") {
orderNumber
order {
invoiceNumber
date
commission
currency
orderTotal
orderSource
carrier
shippingAddress {
company
street
zip
city
}
billingAddress {
company
street
zip
city
}
items {
productNumber
orderNumber
oemNumber
quantity
total
},
"error": null
}
}
}

Example Response​

{
"data": {
"orderDetails": {
"orderNumber": "123456",
"order": {
"invoiceNumber": "654321",
"date": "2025-08-19",
"commission": "25310133",
"currency": "EUR",
"orderTotal": 3080,
"orderSource": "online",
"shippingAddress": {
"company": "AXRO GmbH",
"street": "Schnackenburgallee 183-201",
"zip": "22525",
"city": "Hamburg"
},
"billingAddress": {
"company": "AXRO GmbH",
"street": "Schnackenburgallee 183-201",
"zip": "22525",
"city": "Hamburg"
},
"items": [
{
"productNumber": "EPSET20692",
"orderNumber": "123456",
"oemNumber": "c13s020692",
"quantity": 1,
"total": 2785
},
{
"productNumber": "FR_AUTO_MD",
"orderNumber": "123456",
"oemNumber": "FR_AUTO_MD",
"quantity": 1,
"total": 295
}
]
}
}
}
}

shipmentList​

List shipments (tolerant to missing tracking data; empty strings if not available).

Arguments (all optional):

NameTypeRequiredDescription
pageInt❌Page number for pagination (default: 1)
orderNumberString❌Filter shipments by a specific order number
commissionString❌Filter shipments by commission

Response includes:

  • shipments: [ShipmentItem]
  • totalPages: Int
  • error: String (nullable) — present on 400 responses; other errors appear as top-level GraphQL errors

Example Request​

query {
shipmentList(page: 1, orderNumber: "123456", commission: "BR1234") {
totalPages
shipments {
shipmentNumber
company
commission
status
date
shippingDate
trackingUrl
trackingCode
carrier
}
}
}

Example Response​

{
"data": {
"shipmentList": {
"shipments": [
{
"shipmentNumber": "123456",
"company": "AXRO GmbH",
"commission": "25310133",
"status": "OnTheWay",
"date": "20.08.2025",
"shippingDate": "19.08.2025",
"trackingUrl": "https://www.ups.com/track?loc=en_GB&tracknum=1234567890",
"trackingCode": "1234567890",
"carrier": "UPS"
}
],
"totalPages": 1,
"error": null
}
}
}

shipmentDetails​

Retrieve shipment details by shipment number.

Response includes:

  • shipmentNumber: String
  • shipment: ShipmentDetailMessage
  • error: String (nullable) — present on 400 responses; other errors appear as top-level GraphQL errors

Example Request​

query {
shipmentDetails(shipmentNumber: "654321") {
shipmentNumber
shipment {
orderNumbers
invoiceNumber
shipmentNumber
shippingDate
items {
productNumber
orderNumber
oemNumber
commission
quantity
total
}
}
}
}

Example Response​

{
"data": {
"shipmentDetails": {
"shipmentNumber": "654321",
"shipment": {
"orderNumbers": [
"111111"
],
"invoiceNumber": "123456",
"shipmentNumber": "654321",
"shippingDate": "2025-08-19",
"items": [
{
"productNumber": "EPSET20692",
"orderNumber": "111111",
"oemNumber": "c13s020692",
"commission": "25310133",
"quantity": 1,
"total": 2785
},
{
"productNumber": "FR_AUTO_MD",
"orderNumber": "111111",
"oemNumber": "FR_AUTO_MD",
"commission": "25310133",
"quantity": 1,
"total": 295
}
]
},
"error": null
}
}
}

trackingHistory​

Retrieve tracking history by shipment number. The response includes:

  • shipmentNumber: String
  • history: JSON (preserves dynamic keys like tracking codes and state indices)
  • error: String (nullable) — present if the service rejects the request or an error occurs

Example Request​

query {
trackingHistory(shipmentNumber: "567517") {
shipmentNumber
history
}
}

Example Response (success)​

{
"data": {
"trackingHistory": {
"shipmentNumber": "123456",
"history": {
"00340434111111199160": {
"states": {
"0": {
"time": "2025-08-18T13:34:00+02:00",
"event": "Delivered successfully",
"phase": "Delivery",
"location": { "place": "" },
"timezone": "Etc/GMT-2",
"event_key": "H10",
"phase_key": "H",
"carrier_name": "DHL",
"additional_info": []
}
},
"estimatedDeliveryDate": {
"date": "2025-08-18 14:35:00.000000",
"timezone_type": 3,
"timezone": "Europe/Berlin"
},
"delivered": true
}
},
"error": null
}
}
}

Example Response (error)​

{
"data": {
"trackingHistory": {
"shipmentNumber": "123456",
"history": {},
"error": "shipmentNumber does not belong to customerNumber"
}
}
}

Mutations​

shippingCreate​

Create a shipping address or validate without saving.

Arguments:

  • input: { company, department, firstname?, lastname?, street, zip, city, country, phone?, email? }
  • check: Boolean = false — if true, validates/normalizes without saving (no id in response)

Returns:

  • On success: suggestion (check=true) or created ShippingAddressInfo
  • On error: { error: true, status: Int, body: JSON } from the REST layer

Note: this mutation forwards to POST /api/v1/address/shipping/, so phone numbers follow the same normalization rules. Common notations such as 0170 1234567 are rewritten to +491701234567 using country, and a number that does not exist in the numbering plan of its own dialling code is rejected with status 422 in body, with a message naming that country and an example. The address country only decides how a national number without + or 00 is read. The stored value is the normalized one.

NameTypeRequiredDescription
companystring✅Company name (max 35 chars)
departmentstring✅Department name (max 35 chars)
firstnamestring❌Contact first name
lastnamestring❌Contact last name
streetstring✅Street and number (max 35 chars)
zipstring✅ZIP/Postal code
citystring✅City (max 35 chars)
countrystring✅Country code (ISO 3166-1 alpha-2)
phonestring❌Phone number, normalized to E.164 against country
emailstring❌Email address

Example Request (check=false)​

mutation createShipping {
shippingCreate(
input: {
company: "Example Corp
firstname: "John"
lastname: "Doe"
department: "Warehouse"
street: "123 Shipping St"
zip: "10001"
city: "New York"
country: "US"
phone: "+4940123456"
email: "test@example.com"
}
check: false
)
}

Example Response​

{
"data": {
"shippingCreate": {
"id": "95867100-43d3-5416-8729-74722012aef1",
"company": "Example Corp",
"department": "Warehouse",
"firstname": "John",
"lastname": "Doe",
"street": "123 Shipping St",
"zip": "10001",
"city": "New York",
"country": "US",
"phone": "+4940123456",
"email": "test@example.com",
"status": "WAITING_APPROVAL",
"info": "Please wait for approval."
}
}
}

Example Request (check=true)​

mutation createShipping {
shippingCreate(
input: {
company: "Example Corp"
department: "Warehouse"
street: "Ballindamm 40"
zip: ""
city: ""
country: "DE"
}
check: true
)
}

Example Response​

{
"data": {
"shippingCreate": {
"company": "Example Corp",
"department": "Warehouse",
"street": "Ballindamm 40",
"zip": "20095",
"city": "Hamburg",
"country": "DE",
"phone": null,
"email": null,
"status": "CHECK_ONLY",
"info": "Suggested validated/normalized address. Not saved."
}
}
}

shippingUpdate​

Update a shipping address by ID (follows same permission rules as REST).

Arguments:

  • id: String!
  • input: { phone?, email? }

The number is normalized against the country stored on the address, so a national number such as 0170 1234567 is accepted without sending a country.

Note: the GraphQL layer forwards only fields that are not null, so phone: null leaves the stored number unchanged. Send an empty string (phone: "") to remove it. The REST endpoint accepts both.

Example Request​

mutation updateShipping {
shippingUpdate(
id: "95867100-43d3-5416-8729-74722012aef1"
input: {
phone: "+4940123456",
email: "test@example.com"
}
)
}

Example Response​

{
"data": {
"shippingUpdate": {
"id": "95867100-43d3-5416-8729-74722012aef1",
"company": "Example Corp",
"department": "Warehouse",
"firstname": "John",
"lastname": "Doe",
"street": "123 Shipping St",
"zip": "10001",
"city": "New York",
"country": "US",
"phone": "+4940123456",
"email": "test@example.com",
"status": "USABLE",
"info": "Can be used for shipping."
}
}
}

orderCreate​

Create/prepare an order, optionally placing it immediately.

Arguments:

  • order: { shippingAddressId: String!, cart: [{ productNumber?: String, fsku?: String, quantity: Int! }]!, customReference?, additionalInformation? }
  • place: Boolean = false — if true, places the order with ?place=1

Notes:

  • Each cart item must include either productNumber or fsku.
  • If both are provided, productNumber wins.

Example Request​

mutation createOrder {
orderCreate(
order: {
shippingAddressId: "6f0c76f6-5af3-4a47-9a58-6e3f0a361234"
cart: [
{ productNumber: "CANL055BK", quantity: 2 },
{ fsku: "FSKU-999", quantity: 1 }
]
customReference: "PO-1234"
additionalInformation: "Leave at front desk"
}
place: true
)
}

Example Response​

{
"data": {
"orderCreate": {
"shipping_address": {
"id": "ff81b118-1d53-5ebf-b99e-063c60ce9c2e",
"company": "Acme Inc.",
"department": "Office",
"firstname": "John",
"lastname": "Doe",
"street": "123 Main St",
"zip": "10001",
"city": "New York",
"country": "US",
"email": "test@example.com",
"phone": "+15551234"
},
"billing_address": {
"company": "Acme Inc.",
"department": "Accounting",
"street": "123 Main St",
"zip": "10001",
"city": "New York",
"country": "US"
},
"cart": [
{
"product_number": "CANL055BK",
"quantity": 2,
"difference": 0,
"unit_price": 1000,
"uhg_unit": 1200,
"uhg_total": 1200,
"sub_total": 2200
},
{
"product_number": "HP303A",
"quantity": 1,
"difference": 0,
"unit_price": 1000,
"uhg_unit": 1200,
"uhg_total": 1200,
"sub_total": 2200
}
],
"toll": 295,
"freight_costs": 490,
"grand_total": 2985,
"custom_reference": "PO-1234",
"additional_information": "Leave at front desk",
"order_placed": true,
"place_order_url": "Order placed"
}
}
}

Tips​

  • Introspection is allowed without a token, but running real queries and mutations requires Authorization: Bearer <token>.
  • Field names in GraphQL use camelCase (e.g., productNumber, totalPages, enGb, deDe).