Appearance
Orders and commerce
The commerce records describe the business side of a print job: who ordered it, what was quoted, what was sold, invoiced and shipped. They connect to production through order lines and the jobs created from them.
text
CustomerState ── ContactState, AddressState
│
EstimateState ── EstimateLineState (the quote)
│ convertEstimateToOrder / acceptEstimateAndCreateJobs
OrderState ───── OrderLineState ── JobState (production)
│
├── InvoiceState ── InvoiceLineState
└── ShipmentState ── ShipmentPackageState ── ShipmentItemStateAmounts are plain numbers (Float) with a separate currency field holding an ISO 4217 code such as "EUR". Dates are ISO 8601 strings.
Customers
A customer (CustomerState) needs only a name. Contacts and addresses are separate records that point at it.
graphql
mutation CreateCustomer {
createCustomer(
input: {
name: "Nordlicht Verlag GmbH"
externalId: "CRM-1001"
email: "<customer-email>"
paymentTermsDays: 30
creditLimit: 25000
creditCurrency: "EUR"
}
) {
customer {
id
}
errors {
path
message
}
}
}graphql
mutation AddContactAndAddress {
createContact(
input: {
customerId: "cus_01M0R2496SFANSZFKWPYW17V0J"
firstName: "Anna"
lastName: "Berger"
email: "<contact-email>"
jobTitle: "Production manager"
isPrimary: true
}
) {
contact {
id
}
errors {
path
message
}
}
createAddress(
input: {
customerId: "cus_01M0R2496SFANSZFKWPYW17V0J"
addressType: BOTH
street1: "Hafenstrasse 12"
postalCode: "20457"
city: "Hamburg"
country: "DE"
isDefault: true
}
) {
address {
id
}
errors {
path
message
}
}
}addressType is BILLING, SHIPPING or BOTH. A customer's credit position is in creditLimit, isCreditHold and creditHoldReason, and customerAccountSummary(customerId:) summarises its account.
Orders
An order (OrderState) needs an orderNumber and a customerId. Its lines (OrderLineState) need a lineNumber, productName, quantity, unitPrice and lineTotal.
graphql
mutation CreateOrder {
createOrder(
input: {
orderNumber: "SO-2026-0815"
customerId: "cus_01M0R2496SFANSZFKWPYW17V0J"
poReference: "PO-7781"
requiredDeliveryDate: "2026-10-20T00:00:00Z"
currency: "EUR"
}
) {
order {
id
status
paymentStatus
}
errors {
path
message
}
}
}graphql
mutation AddOrderLine {
createOrderLine(
input: {
orderId: "ord_01M0R24E5G8H2J4K6M9N1P3Q5R"
lineNumber: 1
productName: "Spring catalogue, A4, 48 pp"
quantity: 5000
unitPrice: 1.84
lineTotal: 9200
}
) {
orderLine {
id
}
errors {
path
message
}
}
}One call for the whole order
createOrderGraph creates an order, its lines and, if you need them, a new customer and billing and shipping addresses in one transaction. Either every record is created or none is. It only creates: to use an existing customer or address, set its ID on order and leave the nested input out.
graphql
mutation ImportWebShopOrder {
createOrderGraph(
input: {
order: { orderNumber: "WEB-55120", status: DRAFT, currency: "EUR" }
customer: { name: "Café Morgenrot", email: "<customer-email>" }
shippingAddress: {
addressType: SHIPPING
street1: "Lindenallee 3"
postalCode: "50968"
city: "Köln"
country: "DE"
}
lines: [
{ lineNumber: 1, productName: "Menu cards, A5", quantity: 500, unitPrice: 0.42, lineTotal: 210 }
]
}
) {
order {
id
orderNumber
}
customer {
id
}
lines {
id
}
jobs {
id
}
errors {
path
message
}
}
}When the order is created with status: CONFIRMED, lines that carry a productTemplateId are then turned into jobs and returned in jobs. This step runs after the transaction: if it fails, the reason is in errors and the order stays.
Order status
OrderState.status is an OrderStatus: DRAFT, CONFIRMED, IN_PRODUCTION, PARTIALLY_SHIPPED, SHIPPED, DELIVERED, COMPLETED, CANCELLED or ON_HOLD. paymentStatus is a PaymentStatus: UNPAID, PARTIALLY_PAID, PAID, OVERDUE, REFUNDED or WRITTEN_OFF.
Set the status with updateOrder(id, input: { status }), or for many orders at once with bulkUpdateOrderStatuses. Shipping updates some statuses for you (see Shipments).
Finding orders
OrderFilterInput filters on orderNumber, status, paymentStatus, customerId and createdAt:
graphql
query OpenOrdersForCustomer {
listOrders(
first: 25
filter: {
customerId: { eq: "cus_01M0R2496SFANSZFKWPYW17V0J" }
status: { in: ["CONFIRMED", "IN_PRODUCTION"] }
}
sort: [{ field: ORDER_DATE, direction: DESC }]
) {
totalCount
edges {
node {
id
orderNumber
status
totalAmount
currency
requiredDeliveryDate
}
}
}
}orderLifecycle(orderId:) returns everything attached to one order in a single call: the order and its lines, the estimate it came from, jobs, invoices and shipments.
graphql
query OrderOverview {
orderLifecycle(orderId: "ord_01M0R24E5G8H2J4K6M9N1P3Q5R") {
order {
orderNumber
status
}
jobs {
id
name
status
}
invoices {
invoiceNumber
status
totalAmount
}
shipments {
shipmentNumber
status
trackingNumber
}
errors {
path
message
}
}
}From order to production
Link an existing job to an order line by setting jobId on the line with updateOrderLine. To create jobs from an order's lines, call createJobsFromOrder, one entry per line:
graphql
mutation JobsFromOrder {
createJobsFromOrder(
input: {
orderId: "ord_01M0R24E5G8H2J4K6M9N1P3Q5R"
jobs: [{ orderLineId: "oln_01M0R24F7J9K3M5N8P1Q4R6S2T", jobName: "Spring catalogue", priority: 5 }]
}
) {
jobs {
id
name
status
}
errors {
path
message
}
}
}Estimates
An estimate (EstimateState) is a quote. Its EstimateStatus is DRAFT, SENT, ACCEPTED, REJECTED, EXPIRED or REVISED. reviseEstimate creates a new revision of an estimate that has not been accepted.
Two mutations turn an estimate into an order. Both refuse an estimate that is rejected, expired or already converted:
convertEstimateToOrdercreates the order and its lines from the estimate.acceptEstimateAndCreateJobsalso creates the jobs, with their components and operations, and returns them all.
graphql
mutation AcceptQuote {
acceptEstimateAndCreateJobs(input: { estimateId: "est_01M0R24G9K2M4N6P8Q1R3S5T7V", orderNumber: "SO-2026-0816" }) {
order {
id
status
}
jobs {
id
name
}
updatedEstimate {
status
}
errors {
path
message
}
}
}Invoices
invoiceOrder creates an invoice (InvoiceState) with its lines from an order:
graphql
mutation InvoiceOrder {
invoiceOrder(
input: { orderId: "ord_01M0R24E5G8H2J4K6M9N1P3Q5R", invoiceNumber: "INV-2026-0311", paymentTerms: "30 days net" }
) {
invoice {
id
status
totalAmount
currency
}
errors {
path
message
}
}
}An invoice has a kind (InvoiceKind: INVOICE, CREDIT_NOTE, PROFORMA) and a status (InvoiceStatus). Payment details (paidAmount, paymentMethod, paymentReference) live on the invoice. You can also create invoices directly with createInvoice.
Shipments
A shipment (ShipmentState) holds packages, and each package holds items that point at a job, component or order line. dispatchShipment creates the shipment, its packages and items in one call:
graphql
mutation Dispatch {
dispatchShipment(
input: {
orderId: "ord_01M0R24E5G8H2J4K6M9N1P3Q5R"
trackingNumber: "00340434161234567890"
packages: [
{
weight: 18.5
items: [{ orderLineId: "oln_01M0R24F7J9K3M5N8P1Q4R6S2T", quantity: 2500, description: "Box 1 of 2" }]
}
]
}
) {
shipment {
id
status
}
errors {
path
message
}
}
}A dispatched shipment starts as PICKED_UP. If its order was CONFIRMED or IN_PRODUCTION, the order moves to PARTIALLY_SHIPPED.
Report carrier progress with updateShipmentTracking. The status must be a valid next step from the current one (ShipmentStatus); when it reaches DELIVERED, the linked order moves to DELIVERED as well.
graphql
mutation Delivered {
updateShipmentTracking(
input: { shipmentId: "shp_01M0R24H2M4N6P8Q1R3S5T7V9W", status: DELIVERED, deliveredAt: "2026-10-19T10:42:00Z" }
) {
shipment {
status
deliveredAt
}
order {
status
}
errors {
path
message
}
}
}