Skip to main content

Orders

Manage orders across your shops. You can create orders directly or using GTINs (see Finding GTINs).

Location-routed orders​

A franchise location does not own the network storefront. Orders placed on that storefront and routed to the location still show up on the location's API key.

getOrders with no shopId returns those orders, newest first. getOrder returns the line items. The same key cannot update a routed order; edits stay with the shop that took the payment.

query {
getOrders(limit: 20) {
id
orderNumber
customerEmail
dueDate { _seconds _nanoseconds }
fulfillment
grandTotal
shippingCost
totalTax
totalPrice
payout {
stripeFee
riverrFee
netPaid
currency
payoutId
arrivalDate
amount
transferId
}
orderItems {
id
name
quantity
price
mockups { url name placement }
printFiles { url name placement }
}
}
}
FieldDescription
payoutNull until the customer's card payment has been split. Read the order again if a brand-new order has no payout yet.
payout.stripeFeeCard processing fee withheld on this order, in dollars.
payout.riverrFeeRiverr fee withheld on this order, in dollars. Shipping and tax are not charged this fee.
payout.netPaidAmount transferred to this account for the order. Product, shipping, and tax shares are already included, and the two fees above are already subtracted. Sum netPaid across the orders in one bank deposit to match the deposit.
payout.payoutIdStripe payout id (po_…) of the bank deposit this order settled into. Null until Stripe pays that deposit.
payout.arrivalDateDate that deposit lands in the bank, YYYY-MM-DD.
payout.amountTotal dollars of that bank deposit. Repeated on every order in the deposit. Sum netPaid to reconcile the deposit.
payout.transferIdStripe transfer id (tr_…) for this order's share. Present once the split has been transferred, even if the deposit has not landed yet.
orderItems.mockupsCustomer-facing mockup URLs.
orderItems.printFilesProduction file URLs. A line with an uploaded print file or DST uses that. Storefront lines use the print PNG the customizer exported at checkout. Preview images stay on images.
customerEmailCustomer email, the same address as the order email.
dueDateProduction due date. The order email prints this as a calendar date.
fulfillmentpickup or shipping. Same split as the order email.
orderItems.imagesPreview and artwork images stored on the line.

Subscribe to order.created to hear about a routed order as soon as it is assigned to the location. The webhook body is the order id. Fetch this query for items, files, and fees. See Webhooks.

Get Orders​

Retrieve orders with optional filters. Shop filters still apply to shops this key owns. Omit shopId to include orders routed to your location.

query {
getOrders(shopId: "shop_123", shipped: false, limit: 10) {
id
orderNumber
shopId
shipped
cancelled
grandTotal
shippingCost
createdAt {
_seconds
_nanoseconds
}
shippingAddress {
name
address1
city
country
}
}
}

Filter Parameters​

ParameterTypeDescription
shopIdIDFilter by shop
shippedBooleanFilter by shipped status
cancelledBooleanFilter by cancelled status
createdAfterTimestampInputOrders created after this time. Pass { _seconds, _nanoseconds }.
updatedAfterTimestampInputOrders updated after this time. Pass { _seconds, _nanoseconds }. Do not combine with createdAfter.
platformOrderIdStringShopify order id (order.id). Returns that order directly.
orderNumberStringShopify numeric order number, without the #.
limitIntMax number of results

Look up one order with platformOrderId or orderNumber and shopId. Leave the date filters off for that call. getOrder is only the Riverr order id.

Get a Single Order​

getOrder now returns the full orderItems collection (previously the array came back empty). You can also request per-item and per-order cost breakdowns and ShipStation shipping options.

query {
getOrder(id: "order_123") {
id
orderNumber
shipped
cancelled
grandTotal
shippingOptions {
carrierCode
serviceCode
packageCode
}
shippingLabel {
url
carrierName
carrierService
trackingCode
}
cost {
printingCost
fulfillmentCost
shippingCost
discount
totalCost
customerPaid
profit
estimated
currency
}
orderItems {
id
name
price
quantity
images {
url
placement
type
}
cost {
printingCost
fulfillmentCost
totalCost
currency
}
}
}
}

Per-item and per-order cost​

OrderItem.cost and Order.cost are computed on-demand only when selected — they trigger extra Firestore reads, so request them only when needed.

FieldDescription
printingCostDecoration / print cost from the enterprise pricing table for the item's decorationMethod (DTG, DTF, …), falling back to per-placement overlay prices when no table is attached
fulfillmentCostBlank product / PO unit cost × quantity, including supplier upcharge
shippingCostResolved from blank product shippingPriceId and the destination country (Order-level only). null when not calculable.
discountTier discount applied to printing cost (Order-level only)
totalCostprintingCost + fulfillmentCost + shippingCost − discount
customerPaidOrder.grandTotal (Order-level only)
profitcustomerPaid − totalCost (Order-level only)
estimatedtrue until the order has been invoiced (Order-level only)
currencyOrder currency, defaults to USD

Order status & tracking​

Order exposes a derived lifecycle status, fine-grained tags, and inline shipments so you can poll fulfillment without inspecting individual flags.

query {
getOrder(id: "order_123") {
status
statusTags
shipped
cancelled
shipments {
trackingCode
trackingUrl
carrierName
shippedAt { _seconds _nanoseconds }
}
}
}
FieldDescription
statusCoarse, normalized status derived server-side: "production" | "unsynced" | "shipped" | "cancelled". Mirrors Riverr's internal search-index normalization. Precedence (last match wins): cancelled > shipped > unsynced (not fully mapped) > production. Eventually consistent — a brand-new order reads "production" until the mapping pipeline runs.
statusTagsFiner pipeline tags (e.g. "pre-production", "in-production", "routed", "partially-shipped", "shipped", "draft"). Typed as a list for forward-compatibility; internal-only tags are filtered out. Empty until the pipeline has run. Treat as "current state", not history.
shipmentsAll shipments for the order (every parcel). See Tracking & Fulfillment.

Quote an order from GTIN​

quoteOrderFromGtin prices a job against the same enterprise decoration tables used for invoicing — without creating an order. Use it to pull DTG vs DTF (or any other method) print rates, blank cost, and optional shipping before you call createOrderFromGtin.

getBlankProducts does not return print prices. Order.cost after create also reads these tables now, but a quote is the right call when you need the number first.

FieldDescription
printingCostDecoration table rate × quantity
fulfillmentCostBlank / PO unit cost × quantity, including supplier upcharge
shippingCostFrom the blank's shipping table when shippingAddress.country or countryCode is set. Otherwise null.
discountSeller tier discount on printing, if any
totalCostprintingCost + fulfillmentCost + shippingCost − discount
items[].warningsMethod not on the product, unknown placement, or defaulted Front

decorationMethod ids come from getDecorationMethods ("1" DTG, "6" DTF, "3" embroidery, …). Placement ids come from getPlacements ("1" Front, "2" Back, "3" Left Chest).

If you send a method the product does not offer — for example DTF "6" on a DTG-only blank — and the printer uses pricing tables, the query fails. We do not return $0 print and we do not silently substitute another method.

{
"errors": [
{
"message": "Not available — Please contact admin to add this decoration method for this product.",
"path": ["quoteOrderFromGtin"],
"extensions": { "code": "400" }
}
]
}

createOrderFromGtin rejects the same way if you send that method on the line. Use a catalog GTIN that offers the method, or ask the printer admin to attach it on the base product.

Enterprises that turn pricing tables off (Settings → Pricing tables) still quote from per-placement overlay prices. $0 print is allowed there — that is how shops like Candle Builders price.

When placements is omitted we quote Front ("1") and say so in warnings.

query QuoteOrderFromGtin($input: OrderQuoteFromGtinInput!) {
quoteOrderFromGtin(input: $input) {
printingCost
fulfillmentCost
shippingCost
discount
totalCost
currency
items {
gtin
name
style
color
size
quantity
decorationMethod
printingCost
fulfillmentCost
totalCost
placements {
placement
printingCost
}
warnings
}
}
}
{
"input": {
"shippingAddress": {
"country": "US"
},
"orderItems": [
{
"gtin": "00123456789012",
"quantity": 1,
"decorationMethod": "6",
"placements": ["1"]
}
]
}
}

Compare DTG vs DTF by calling the query twice with "1" and "6" on the same GTIN — or on the DTG and DTF catalog GTINs if the printer split them into separate products.

Create an Order​

createOrder and createOrderFromGtin now both return the full orderItems in the mutation response (previously they came back as an empty array). You can optionally pass shippingOptions with ShipStation-aware fields (carrierCode, serviceCode, packageCode); these are persisted on the order document and surfaced back as Order.shippingOptions.

To send a pre-purchased label instead of asking Riverr to buy postage, pass shippingLabel — see Prepaid shipping labels.

mutation {
createOrder(
input: {
orderNumber: "ORD-2001"
shopId: "shop_123"
shippingAddress: {
name: "Jane Smith"
address1: "456 Oak Ave"
city: "Los Angeles"
state: "CA"
zip: "90001"
country: "US"
}
shippingOptions: {
carrierCode: "stamps_com"
serviceCode: "usps_priority"
packageCode: "package"
}
orderItems: [
{
productId: "prod_123"
variantId: "var_456"
quantity: 2
price: 29.99
name: "Custom T-Shirt"
}
]
}
) {
id
orderNumber
grandTotal
shipped
cancelled
shippingOptions {
carrierCode
serviceCode
packageCode
}
orderItems {
id
name
price
quantity
}
}
}

Update an Order​

updateOrder can mark an order shipped or cancelled, replace the shipping address, change the quantity or variant on an existing line (a size swap), or remove a line by sending quantity: 0.

Address and line edits are rejected once the order has been sent to production. The error message is:

You can't make these changes once the order has been sent to production.

errors[].extensions.code is ORDER_IN_PRODUCTION. Do not retry that edit.

ChangeAllowed whileRejected when
shippingAddressThe order is not shipped and no shipping label has been purchased. Batching alone does not block an address change.shipped is true, a label is already on the order (including a prepaid shippingLabel), or the order is partially shipped.
orderItems (quantity, variantId, or quantity: 0 to remove the line)No line is batched and statusTags does not include in-production.Any line is batched, statusTags includes in-production, a label has been purchased, or the order is shipped. Removing the last live line is also rejected. Cancel the order instead.
cancelled / shippedSame as before. These flags do not edit the address or the items.

Orders created with createOrder or createOrderFromGtin stay in Riverr. updateOrder does not call Shopify for those, even when the shop is a Shopify shop.

An order that arrived from Shopify is different. updateOrder writes that change to Shopify in the same call: the new address, the new variant, or quantity: 0 on that line. Riverr then keeps the Shopify result, so a later sync does not put the old line back.

variantId is the Riverr catalog variant id (the same id you pass to createOrder), not the Shopify variant id. It has to be a variant of the same product as that line. Read line ids from getOrder { orderItems { id variantId quantity ignored } }. A Shopify size swap replaces that line, so read the order again for the new line id. A removed line stays on the order with ignored: true and is left out of production.

pre-production in statusTags means the order is still open. in-production means it has been batched and line edits will fail.

mutation {
updateOrder(
id: "order_123"
input: {
shippingAddress: {
name: "Jane Smith"
address1: "456 Oak Ave"
city: "Austin"
state: "TX"
zip: "78701"
country: "US"
countryCode: "US"
}
}
) {
id
shippingAddress {
name
address1
city
state
zip
country
}
}
}
mutation {
updateOrder(
id: "order_123"
input: {
orderItems: [{ id: "order_123_line_1", variantId: "var_large", quantity: 1 }]
}
) {
id
orderItems {
id
variantId
quantity
}
}
}

Remove one line from a multi-item order:

mutation {
updateOrder(
id: "order_123"
input: {
orderItems: [{ id: "order_123_line_2", quantity: 0 }]
}
) {
id
orderItems {
id
quantity
ignored
}
}
}

Marking shipped or cancelled is unchanged:

mutation {
updateOrder(id: "order_123", input: { shipped: true }) {
id
orderNumber
shipped
cancelled
}
}

Create an Order from GTIN​

See Finding GTINs for the full guide on creating orders using GTINs.

orderItems[].images.type is an enum — valid values are printing (the artwork to be printed) and mockup (the visual proof). placement is a string ID; look up the valid IDs for your enterprise via the getPlacements query.

mutation {
createOrderFromGtin(
input: {
orderNumber: "ORD-3001"
shopId: "shop_123"
shippingAddress: {
name: "John Doe"
address1: "123 Main St"
city: "New York"
country: "US"
}
shippingOptions: {
carrierCode: "stamps_com"
serviceCode: "usps_priority"
packageCode: "package"
}
orderItems: [
{
gtin: "00123456789012"
quantity: 1
price: 19.99
images: [
{
url: "https://cdn.example.com/artwork.png"
placement: "1"
type: printing
}
{
url: "https://cdn.example.com/mockup.png"
placement: "1"
type: mockup
}
]
}
]
}
) {
id
orderNumber
shipped
shippingOptions {
carrierCode
serviceCode
packageCode
}
orderItems {
id
name
images {
url
placement
type
}
cost {
printingCost
fulfillmentCost
totalCost
}
}
cost {
printingCost
fulfillmentCost
shippingCost
totalCost
}
}
}

Prepaid shipping labels​

shippingOptions is a request for Riverr to buy a ShipStation service. If you already purchased the label (UPS, USPS, ShipStation, EasyPost, etc.), do not put the label URL on images and do not use shippingOptions for it. Pass a shippingLabel on createOrderFromGtin or createOrder.

At ship time Riverr prints the file you sent and skips buying postage. This is the same path CSV / manual orders use.

FieldRequiredDescription
shippingLabel.urlyesPublic HTTPS URL to a PNG or PDF. PDF URLs should end in .pdf.
shippingLabel.carrierNamerecommendedHuman-readable carrier, e.g. "UPS".
shippingLabel.carrierServicerecommendedService level, e.g. "Ground".
shippingLabel.trackingCoderecommendedTracking number printed on the label.

Hosting rules match artwork URLs: the link must stay publicly fetchable with no auth, cookies, or expiring signed URLs through print, ship, and any reprint. Riverr stores the URL; it does not copy the bytes at create time.

When shippingLabel is set:

  • Leave shippingOptions off (those codes are for a label Riverr would buy).
  • shippingCost can be 0 — you already paid the carrier.
  • After the order ships, order.shipped fires and Shipment carries your trackingCode / carrierName with cost 0. Poll Tracking & Fulfillment or subscribe to order.shipped on Webhooks.

Read the label back on Order.shippingLabel from getOrder / createOrderFromGtin.

Sample payload with a prepaid label​

mutation CreateOrderFromGtin($input: OrderCreateFromGtinInput!) {
createOrderFromGtin(input: $input) {
id
orderNumber
shippingLabel {
url
carrierName
carrierService
trackingCode
}
orderItems {
id
name
images { url placement type }
}
}
}
{
"input": {
"orderNumber": "ORD-3001",
"shopId": "shop_123",
"shippingAddress": {
"name": "John Doe",
"address1": "123 Main St",
"city": "New York",
"state": "NY",
"zip": "10001",
"country": "US"
},
"shippingLabel": {
"url": "https://cdn.example.com/labels/ORD-3001.pdf",
"carrierName": "UPS",
"carrierService": "Ground",
"trackingCode": "1Z999AA10123456784"
},
"orderItems": [
{
"gtin": "00123456789012",
"quantity": 1,
"price": 19.99,
"decorationMethod": "1",
"images": [
{
"url": "https://cdn.example.com/artwork.png",
"placement": "1",
"type": "printing"
},
{
"url": "https://cdn.example.com/mockup.png",
"placement": "1",
"type": "mockup"
}
]
}
]
}
}

url is the field that carries the label. images stay artwork-only (printing or mockup).