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.
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:
- Set
"pdf": truein yourfile_configsentry - Name the file with a
.pdfextension - 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.