Overview

Custom HTML Purchase Order (PO) print templates in Luminous use Mustache-style {{placeholder}} syntax. The variables available are grouped below. Important: cost rule names (e.g., tariff cost rules) are not currently exposed as template placeholders — see the note at the bottom.

To look up every placeholder that is active for your account (including your specific custom field keys), call the placeholder reference API while logged in as an admin:

GET /admin/manage/export-templates/purchase-order-html-placeholders

This returns a live, grouped list with descriptions and examples for your account.


Available placeholder groups

Purchase Order header fields

These go anywhere in your template (header, footer, etc.):

PlaceholderWhat it outputs
{{purchaseOrderNumber}}PO ID number
{{orderDate}}Date/time the PO was created (also: .date, .time, .dateTime)
{{requestedShipDate}}Requested ship date (also: .formatted, .month, .day, .year)
{{arrivalDueDate}}Arrival due date (same sub-keys)
{{notes}}Public notes on the PO
{{paymentTerms}}Payment terms
{{logisticLabel}}Shipping method / carrier
{{status}}PO status
{{alternateIds}}Comma-separated alternate IDs

Company information

PlaceholderWhat it outputs
{{company.name}}Your company name
{{company.logoUrl}}Your company logo URL
{{company.address.fullAddressBlock}}Company address block (HTML)
{{company.address.street1}}, {{company.address.city}}, etc.Individual address components

Supplier contact

PlaceholderWhat it outputs
{{supplierContact.name}}Supplier name
{{supplierContact.company}}Supplier company
{{supplierContact.email}}Supplier email
{{supplierContact.phone}}Supplier phone
{{supplierContact.address.fullAddressBlock}}Full supplier address (HTML)
{{supplierContact.address.street1}}, .city, .state, .zip, .countryIndividual address parts

A {{#supplier.contacts}} loop also exists for iterating multiple contacts with {{name}}, {{email}}, {{phone}}.

Ship-to contact

PlaceholderWhat it outputs
{{shipTo.name}}Ship-to name
{{shipTo.company}}Ship-to company
{{shipTo.address.fullAddressBlock}}Full ship-to address (HTML)
{{shipTo.address.street1}}, .city, .state, .zip, .countryIndividual components

PO-level custom fields

Use these outside the order lines loop to output PO header custom fields:

  • {{orderCustomFields.yourFieldKey}} — value of a specific order custom field
  • {{orderCustomFields}} — all order custom fields as a comma-separated "Label: Value" list
  • {{#orderCustomFields._hasAny}} ... {{/orderCustomFields._hasAny}} — conditional block

See the dynamic key-generation rules in the custom fields article.


Inside the {{#orderLines}} loop

Wrap the following in {{#orderLines}} ... {{/orderLines}} to repeat once per line item:

PlaceholderWhat it outputs
{{sku}}Supplier / source SKU
{{internalSku}} / {{itemNumber}}Your internal Luminous SKU
{{description}}Line description (falls back to SKU description)
{{lineDescription}}Description entered directly on the PO line
{{skuDescription}}Product description from SKU details
{{productName}}Product name
{{quantity}} / {{quantity.formatted}}Ordered quantity
{{unitCost}} / {{unitCost.formatted}}Unit cost (currency)
{{lineTotal}} / {{lineTotal.formatted}}Line total (currency)
{{uom}}Ordered unit of measure (e.g., Pack)
{{baseQuantity}}Quantity in the base unit (e.g., ea)
{{baseUnit}}Base unit of measure name
{{uomConversions.<slug>}}Quantity converted to a specific UOM, keyed by the slugified UOM name (e.g., {{uomConversions.case}}, {{uomConversions.case-pack}}). Sub-keys like .decimals0, .decimals2, .raw are also available.
{{upc}}UPC code
{{downpaymentAmount}}Downpayment amount for this line
{{retailCost}}Retail price from the SKU

SKU / product custom fields inside the loop

Product (SKU) custom fields are available on every line via {{skuCustomFields.yourFieldKey}} (also aliased as {{itemCustomFields.yourFieldKey}}). For a full walkthrough of access patterns, key naming, and the in-template debug helper, see: How do I reference a product custom field inside the order lines loop of a custom PO print template?

Variant attributes inside the loop

Variant attributes (e.g., color, size) are available via {{variantAttributes.yourAttribute}}, or you can loop through all of them with {{#variantAttributes}} {{label}}: {{value}} {{/variantAttributes}}.


Additional fees loop

Use {{#additionalFees}} ... {{/additionalFees}} to iterate custom fee lines. Inside the loop: {{productName}}, {{description}}, {{quantity}}, {{unitPrice}}, {{lineTotal}}, {{discountAmount}}, {{discountPercent}}, {{downpaymentAmount}}, {{downpaymentPercent}}.


Financial totals

PlaceholderWhat it outputs
{{subTotal}}Order subtotal (before shipping)
{{shippingTotal}}Total shipping cost
{{grandTotal}}Grand total
{{totalPaid}}Amount already paid
{{balancePayable}}Remaining balance due
{{totalUnits}}Sum of all line quantities
{{additionalFeesTotal}}Total of all additional fee lines

All currency placeholders also support .formatted, .raw, .currencySymbol, etc. sub-keys.


⚠️ Cost rule names (e.g., tariff cost rules) are not available

There is currently no placeholder that outputs the name or details of a cost rule (such as a tariff cost rule) applied to a PO or its line items. Cost rules are part of the landed-cost calculation system, but that data is not passed into the HTML template view model.

If outputting cost rule names on your printed PO is important to your workflow, please contact Luminous support to request this as a feature enhancement.


Tips

  • Discover your exact placeholder keys — use the live API endpoint GET /admin/manage/export-templates/purchase-order-html-placeholders to get a full list for your account, including all custom field keys.
  • Debug unknown values — temporarily add {{{skuCustomFields._info}}} (triple braces) inside your {{#orderLines}} row to render a table of every available key and value for each line. Remove it before saving your final template.
  • Currency and number formatting — most numeric placeholders support sub-keys such as {{unitCost.formatted}}, {{unitCost.raw}}, {{quantity.decimals0}}, etc.