We're software that helps growing brands & retailers grow and scale. Sync, sell and ship your products and inventory on online marketplaces and storefronts faster, easier and more accurately.

Learn more now

Templates: Custom Export Formats with Twig

What Are Templates?

By default, automations export data as CSV files. But many integrations require different formats -- a vendor needs an XML feed, a supplier's API expects a JSON payload, or your accounting team wants an HTML invoice as a PDF attachment. Templates let you define the exact output format using the Twig templating language.

With a template, you have full control over the structure and content of the exported data. Instead of a flat CSV, you can produce XML documents, JSON API payloads, HTML pages, EDI transactions, or any other text-based format.

Twig Template Basics

SureDone uses the Twig templating engine. If you have worked with Jinja2 (Python), Liquid (Shopify), or Mustache, Twig will feel familiar. The core syntax is:

Output a variable:


{{ data["field_name"] }}

Control logic:


{% if data["stock"] > 0 %}
  In Stock
{% else %}
  Out of Stock
{% endif %}

Loops:


{% for item in data["items"] %}
  {{ item["sku"] }} - {{ item["title"] }}
{% endfor %}

Comments:


{# This is a comment and will not appear in the output #}

All field data mapped in field_map and field_run is available through the data variable.

Setting Up a Template

Add the template key to your file_configs entry with the Twig template as its value:


"file_configs": [
  {
    "template": "<order><id>{{ data['oid'] }}</id><sku>{{ data['sku'] }}</sku></order>",
    "field_run": {
      "oid": "oid",
      "sku": "sku"
    }
  }
]

The template string replaces the normal CSV output. The engine renders the template for each item or order (or for all items at once, depending on payload_multi), replacing {{ data['field'] }} with the actual values.

Tip: For readability in your JSON config, keep short templates inline. For longer templates, consider managing them in a separate file and pasting the rendered output into the config, since JSON does not support multi-line strings.

Available Variables

Inside a template, the data variable is an object containing all fields mapped in field_map and field_run. For order exports, additional nested objects are available:

Variable Description
data["field_name"] Any field from field_map or field_run
data["order"] Order-level fields (oid, status, total, etc.)
data["shipping"] Shipping address fields
data["billing"] Billing address fields
data["cart"] Cart items array for order exports
data["itemdetails"] Product details for the current line item
data.quantity Quantity for the current line item

SureDone also provides helper functions in templates:

Function Description
sd_option("option_name") Read a value from your SureDone account settings
sd_siteinfo("key", false) Read site information (business name, URL, logo, etc.)
sd_currency(false) Get the currency symbol
sd_statename("ST") Convert state abbreviation to full name
sd_countryname("US") Convert country code to full name
json_decode(value, true) Parse a JSON string into an object
is_image(url) Check if a URL points to an image

payload_multi: One vs. Many

The payload_multi setting controls how the template is rendered relative to the data:

For exports (default: false):

Setting Behavior
payload_multi: false (default) One template render per item/order. Each item generates its own output
payload_multi: true One template render for all items/orders combined in a single output

When payload_multi is false, the engine renders the template once for each matching item or order. This is the right choice when each item needs its own API call, email, or file.

When payload_multi is true, all items are passed to the template together and you use a loop to iterate over them. This is the right choice when you need a single file containing all items.

For imports (default: true):

Setting Behavior
payload_multi: true (default) Normal import -- process all items from the file
payload_multi: false Make a separate external API call for each item, using the template as the request body

Template with HTTP Connections

When the connection type is http and a template is defined, the rendered template becomes the HTTP request body. This lets you send custom API payloads for each item or order:


{
  "connection": {
    "type": "http",
    "address": "https://api.vendor.com/v1/order",
    "method": "POST",
    "headers": {
      "Content-Type": "application/json"
    }
  },
  "file_configs": [
    {
      "template": "{\"po_number\": {{ data['oid'] }}, \"items\": [{\"sku\": \"{{ data['sku'] }}\", \"qty\": {{ data['quantity'] }}}], \"ship_to\": {\"name\": \"{{ data['shippingfirstname'] }} {{ data['shippinglastname'] }}\", \"address\": \"{{ data['shippingstreet1'] }}\", \"city\": \"{{ data['shippingcity'] }}\", \"state\": \"{{ data['shippingstateprovince'] }}\", \"zip\": {{ data['shippingpostalcode'] }}}}",
      "field_run": {
        "oid": "oid",
        "sku": "sku",
        "quantity": "quantity",
        "shippingfirstname": "shippingfirstname",
        "shippinglastname": "shippinglastname",
        "shippingstreet1": "shippingstreet1",
        "shippingcity": "shippingcity",
        "shippingstateprovince": "shippingstateprovince",
        "shippingpostalcode": "shippingpostalcode"
      },
      "order_payload_line_item": true
    }
  ]
}

For each order, the engine renders the JSON template with that order's data and sends it as a POST request to the vendor API.

PDF Generation

Templates can produce PDF files when combined with "pdf": true. Write your template as HTML, and the engine converts the rendered HTML to a PDF document. This is ideal for invoices, packing slips, and purchase orders.

To enable PDF output:

  1. Set "pdf": true in your file_configs entry
  2. Name the file with a .pdf extension
  3. Write your template as valid HTML

{
  "connection": {
    "type": "email",
    "address": "accounting@example.com",
    "subject": "Invoice for Order {{ oid }}",
    "send_as_attachment": true
  },
  "file_configs": [
    {
      "pdf": true,
      "name": "Invoice-{{DATE}}.pdf",
      "template": "<html><head><title>Invoice</title></head><body><h1>Invoice</h1><p>Order: {{ data['oid'] }}</p><table><tr><th>SKU</th><th>Item</th><th>Qty</th><th>Price</th></tr><tr><td>{{ data['sku'] }}</td><td>{{ data['title'] }}</td><td>{{ data['quantity'] }}</td><td>${{ data['price'] }}</td></tr></table><p><strong>Total: ${{ data['total'] }}</strong></p></body></html>",
      "field_run": {
        "oid": "oid",
        "sku": "sku",
        "title": "title",
        "quantity": "quantity",
        "price": "price",
        "total": "total"
      }
    }
  ]
}

The engine renders the HTML template, converts it to a PDF, and emails it as an attachment. You can use inline CSS for styling -- the PDF renderer supports basic CSS for fonts, colors, borders, tables, and layout.

Common Template Patterns

XML Export


"template": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Product><SKU>{{ data['guid'] }}</SKU><Title>{{ data['title'] }}</Title><Price>{{ data['price'] }}</Price><Stock>{{ data['stock'] }}</Stock></Product>"

JSON API Payload


"template": "{\"product\": {\"sku\": \"{{ data['guid'] }}\", \"name\": \"{{ data['title'] }}\", \"price\": {{ data['price'] }}, \"inventory\": {{ data['stock'] }}}}"

HTML Email Notification


"template": "<html><body><div>Hello,<br/><br/>The following order has been REJECTED.<br/><br/>Order: <a href=\"https://app.suredone.com/#!/orders/edit/{{ data['oid'] }}\">{{ data['order'] }}</a></div></body></html>"

Order with Line Items

When using order_payload_line_item, each line item in an order gets its own template render. Access item-specific data through data.itemdetails.product and order-level data through data["order"]:


{
  "order_payload_line_item": true,
  "template": "<html><body><h2>Order {{ data['order']['oid'] }}</h2><p>Item: {{ data.itemdetails.product.title }}</p><p>Quantity: {{ data.quantity }}</p><p>Cost: ${{ data.itemdetails.product.cost }}</p><p>Line Total: ${{ data.quantity * data.itemdetails.product.cost }}</p></body></html>"
}

With order_payload_line_filter set to true, only line items matching the search criteria are rendered. Items from the same order that do not match the search are excluded.

Template Variables

In addition to data fields and built-in functions, templates can use these special variables:

Variable Description
{{trigger_value}} The value returned from the trigger chain in the connection config
{{RESPONSE}} The raw response body from the external connection
{{HMAC}} An HMAC hash generated from the connection's hmac configuration
{{DATE}} Current date (formatted per date_format)
{{NOW}} / {{TIME}} Current date and time (formatted per time_format)

These are replaced before the Twig engine processes the template, so they are available as literal values in your template logic.

Tips

Start simple. Begin with a minimal template that outputs one or two fields. Verify the output is correct, then add complexity incrementally.

Use field_run for template-only fields. If you need a field in the template but do not want it in a CSV export, map it in field_run instead of field_map. It will be available in data but excluded from the bulk file.

Test with email. During development, send template output via email (connection.type: "email") so you can visually inspect the result without making API calls to a vendor.

Escape special characters. In JSON configs, remember to escape double quotes inside template strings with \". For complex templates, consider using the SureDone UI editor which handles escaping automatically.

Use order_payload_line_item for per-item detail. When exporting orders where you need a separate section or file for each line item (common for drop-ship purchase orders), enable this flag alongside your template.