Liquid objects

An export template reads from two lists. An order template gets orders; a customer template gets customers. Loop over the list and read each entry’s properties with a dot:

Liquid
{% for order in orders %}{{ order.shippingAddressSnapshot.postcode }}, {{ order.shippingAddressSnapshot.country }}{% endfor %}
Text
AB12 3CD, United Kingdom

The Preview column on each table below is exactly what Preview Sample writes for that property, and a test in the app checks every row against what an export really contains. A property that does not exist writes nothing and raises no error, so a misspelling shows only as a gap.

Types

TypeWhat it is
TextWritten as it is. Empty when there is nothing, never null
NumberMoney, rates and quantities. Compare without quotes: item.qty == 6
True/falsetrue or false. Use it in an if on its own
ObjectHas properties of its own: order.shippingAddressSnapshot.city
ListLoop over it with for, count it with size, or take one entry by position: order.lineItems.0

Numbers are written as the app holds them, not as money. A whole amount keeps one decimal place (168.0, not 168.00). Add | round: 2 to write money with two decimals; see Liquid filters. Rates are decimals: 0.2, not 20.

Liquid
{% for order in orders %}{{ order.subtotal }} {{ order.grandTotal }} {{ order.lineItems.0.qty }} {{ order.lineItems.0.tax_rate }}{% endfor %}
Text
168.0 196.32 6 0.2

A position counts from 0. order.lineItems.0 is the first line:

Liquid
{% for order in orders %}{{ order.lineItems.0.sku }} then {{ order.lineItems.1.sku }}{% endfor %}
Text
WH001 then GN002

Square brackets (lineItems[0]) are not supported, and a position past the end wraps round to the start rather than writing nothing.

orders

A list of the orders in this export. Each is an order.

order

Every figure is a snapshot taken when the order was placed. A later catalogue or price change never rewrites an order that has been taken.

PropertyTypePreviewNotes
orderIdTextORD-0001Begins with the Order Prefix set in Business Rules
exportStatusTextPendingPending, or Hold - Credit Review for an order over the customer’s credit limit
customerIdTextACC-1042The account code, or a NEW- code for a customer created on the tablet
customerCompanyNameSnapshotTextKestrel Wine BarThe name as it was when the order was taken
dateCreatedText2026-08-09 14:32:00Always year, month, day, then the time
requestedDateText2026-08-16 00:00:00The delivery date asked for. Empty if none
orderTaxCodeTextT1A tax code set for the whole order. Empty if none
currencyCodeTextGBP
subtotalNumber168.0The lines before discount and tax
promotionDiscountNumber8.4Discount on the whole order
appliedPromotionCodeTextSUMMER10Empty if no promotion applied
taxTotalNumber32.72Tax on the goods and on the delivery charge
grandTotalNumber196.32What the customer pays, delivery included
carriageCodeTextSTDThe delivery method’s code: what your ERP matches on
carriageTotalNumber4.0What was charged for delivery, before tax
carriageMethodTextStandard 3-5 daysThe delivery method’s name as the customer was quoted it
carriageQuotedNumber6.95What the method would have charged, present only when a rep agreed a different charge. Empty otherwise
carriageWaivedByText(empty)The promotion code that made delivery free. Empty otherwise
repIdTextUSER_3F2A8B1CThe rep who took the order
repNameTextTom Wilson
orderNotesTextLeave with the cellar door, ask for the duty managerDelivery instructions. May contain commas and quotes: escape it
signaturePathText(empty)Where the signature is stored on the tablet. Your ERP cannot open it
customDataJsonText(empty)Whatever your own process put there
poNumberText(empty)The customer’s PO number from checkout, empty if none was given
billingAddressSnapshotObjectAn order address
shippingAddressSnapshotObjectAn order address: where the order is going
lineItemsListEach entry a line item
isLastOrderTrue/falsetrueTrue on the last order in the file

line item

Each entry in order.lineItems. Prices are what this customer was charged, after their price list, any volume break and any sale.

PropertyTypePreviewNotes
skuTextWH001
barcodeText5060123400010
titleTextGlenvalle 12yr Single Malt 70clMay contain quotes and ampersands: escape it
brandTextGlenvalle
mpnTextGLV-12-70Manufacturer’s part number
qtyNumber6
unit_priceNumber21.0Price per unit actually charged, before tax
price_labelTextTradeWhich price applied: a price list name, Sale, Volume Tier or Standard
tax_codeTextT1
tax_rateNumber0.2A decimal: 0.2 is 20%
line_subtotalNumber126.0unit_price times qty
line_discountNumber6.3This line’s share of the order discount
line_taxNumber23.94Tax on what the customer actually pays for this line
line_totalNumber143.64line_subtotal, less line_discount, plus line_tax
moqNumber6Minimum order quantity
order_multipleNumber6The quantity must be a multiple of this
primary_imageText(empty)Where the product’s image is stored on the tablet
isLastTrue/falsefalseTrue on the last line of the order

order address

billingAddressSnapshot and shippingAddressSnapshot on an order. Snapshots: changing a customer’s address later never rewrites an order already taken.

PropertyTypePreviewNotes
nameTextKestrel Wine Bar
line1Text1 Sample Street
line2Text(empty)
cityTextAnytown
countyText(empty)
postcodeTextAB12 3CD
countryTextUnited KingdomAs it is held on the customer: compare against exactly that

customers

A list of the customers created or changed on a tablet that your ERP has not yet seen. Each is a customer.

customer

A customer created on a tablet often has properties with nothing in them at all, where Preview’s sample customer has empty text. Both write nothing, but upcase, downcase and capitalize fail on a missing value; put default: "" before them. See Liquid filters.

PropertyTypePreviewNotes
accountIdTextNEW-3F2A8B1CBegins NEW- when a rep created the customer offline. Echo it back as OriginalAccountId on your next customer import
companyNameTextThe Anchor Hotel & Bar, LtdEscape it
contactNameTextNiamh O'Brien
emailTextorders@anchorhotel.example
phoneText(empty)
mobileText(empty)
websiteText(empty)
vatRegistrationTextIE1234567X
eoriNumberText(empty)
taxCodeTextEXPORT
priceListIdTextTrade
currencyCodeTextEUR
creditLimitNumber5000.0
creditBalanceNumber1250.0The account balance. Used by the shipped templates
currentBalanceNumber1250.0The same figure under its other name
accountStatusTextActive
carriageCodeTextSTDThe customer’s usual delivery method
internalNotesTextDelivery before 11am only
billingAddressObjectAn order address’s properties: where the invoice goes
shippingAddressesListEach entry a customer address
isLastCustomerTrue/falsetrueTrue on the last customer in the file

These are in every real export but not in Preview Sample, so Preview writes nothing for them (and join on tags is an error there):

PropertyTypeNotes
tagsListThe customer’s tags, as text. Use join
assignedUserIdTextThe rep the customer is assigned to
customDataJsonTextWhatever your own process put there
shippingAddressesJsonTextThe delivery addresses as one piece of JSON. Use shippingAddresses instead

customer address

Each entry in customer.shippingAddresses.

PropertyTypePreviewNotes
nameTextThe Anchor Hotel & Bar, Ltd
line1Text4 Sample Quay
line2Text(empty)
cityTextAnytown
countyTextCo. Dublin
postcodeTextA12 B345
countryTextIreland
isDefaultTrue/falsetrueThe address a rep is offered first

Preview’s sample addresses also carry an isLast, but a real export does not, so a separator written on it never appears in the real file. Use forloop.last:

Liquid
{% for customer in customers %}{% for address in customer.shippingAddresses %}{{ address.line1 }}{% if address.isDefault %} (default){% endif %}{% unless forloop.last %}; {% endunless %}{% endfor %}{% endfor %}
Text
4 Sample Quay (default); Unit 7, Sample Trade Park