---
title: "Partner Order XML: Minimum Specification"
sidebarTitle: Partner Order XML Spec
description: Describes the folder layout and minimum XML schema that's needed by pfRouter to import third-party partner orders to the Photo Finale platform via hotfolder harvesting.
---

> **For AI agents:** the complete documentation index is at [llms.txt](https://docs.photofinale.com/llms.txt). Append `.md` to any page URL for its markdown version.

A partner order is a folder containing one order XML file in the Photo Finale `apm_order` format plus every image file the XML references. pfRouter watches one or more hotfolders; each subfolder of a hotfolder is one order.

```text
<hotfolder>\
    POS-000123\                 one order per subfolder (folder name is not significant)
        POS-000123.xml          exactly one *.xml file
        IMG_0001.jpg            images referenced by <image path="...">, relative to the folder
        IMG_0002.jpg
```

pfRouter writes a `.pfrouter-partner.json` state file into the folder while processing it. Do not create or modify that file.

## Writing an order folder

- If possible write every image before the XML, however pfRouter only processes a folder when the XML parses and every referenced image exists and can be opened exclusively.
- An incomplete folder is rechecked with exponential backoff. After 48 hours it is moved to `_error` with a `reason.txt`.
- An invalid order (bad XML, missing required values, unknown product or store) is moved to `_error` with a `reason.txt` and is not retried.

## Required and optional values

| XML | Required | Rules | Stored as |
| --- | --- | --- | --- |
| `apm_order/@external_id` | **Yes** | 1–32 characters; longer is rejected | `[Order].ExternalId` |
| `apm_order/@vendor` | **Yes** | Name of the system that produced the order | `[Order].AuxData` `Vendor` |
| `customer/@fname`, `@lname`, `@email` | At least one | | Customer and bill-to name / email |
| `customer/@phone`, `@company`, `@address1`, `@address2`, `@city`, `@state`, `@zip`, `@country` | No | | Bill-to |
| `shipment/@fulfillment_type` | **Yes** | `pickup` or `mail` (see Delivery) | Pickup or ship |
| `shipment/order_item` | **Yes**, at least one | | Order line item |
| `order_item/@product` | **Yes** | The dealer's product code: matched first on the product's `fulfillment_id` property, then on its `ProductID` | Product, category, supplier |
| `order_item/@quantity` | **Yes** | 1 or more | Quantity |
| `order_item/@price`, `@line_item_total` | No | Stored as given; no pricing or discounts are applied | Unit price, line total |
| `order_item/image/@path` | **Yes** for products that take photos | File name relative to the order folder; the file must exist. Images should be in jpeg or png format. | Order photo |
| `image/@crop_x`, `@crop_y`, `@crop_width`, `@crop_height`, `@fit_to_paper`, `@borders`, `@border_color` | No | Pixel crop rectangle in the source image | Photo crop / options |
| `items_total`, `tax_total`, `shipping_total`, `grand_total` (on `apm_order`) | No | Stored as given | Order totals |

## Delivery

`shipment/@fulfillment_type` is the only delivery switch. All other delivery attributes in the `apm_order` schema (`retailer/@in_store_pickup`, `pickup_location_id` and the other `pickup_location_*` details, `shipment/@delivery_method`, `fulfillment_id`, the `store` element) are ignored.

| `fulfillment_type` | Also required | Rules |
| --- | --- | --- |
| `pickup` | `retailer/@pickup_location_store_number` | Must match the store number of one of the dealer's active stores |
| `mail` | On `shipment`: `fname`, `lname`, `address1`, `city`, `state`, `zip`, `country`, `delivery_type` (`company`, `phone`, `email` optional) | `delivery_type` is `budget`, `standard`, `expedited` or `express`, and the dealer must have an active shipping method of that type |

## Multi-page products (books, calendars, cards)

Pages are supplied **pre-rendered**: one `<image>` per page under the `order_item`, in page order. No template or project data is used.

## Sample

```xml
<apm_order external_id="POS-000123" vendor="Acme POS">
  <customer fname="Pat" lname="Smith" email="pat@example.com" phone="555-0100"/>
  <retailer pickup_location_store_number="0042"/>
  <shipment fulfillment_type="pickup">
    <order_item product="4X6-MATTE" quantity="2" price="0.29" line_item_total="0.58">
      <image path="IMG_0001.jpg"/>
    </order_item>
    <order_item product="8X10" quantity="1" price="3.99" line_item_total="3.99">
      <image path="IMG_0002.jpg" crop_x="0" crop_y="150" crop_width="2400" crop_height="3000"/>
    </order_item>
  </shipment>
</apm_order>
```

A mail order replaces the `retailer` element and the `shipment` attributes with:

```xml
  <shipment fulfillment_type="mail" delivery_type="standard"
            fname="Pat" lname="Smith" address1="12 Main St" city="Springfield" state="IL" zip="62701" country="US">
```
