--- title: "Custom Format Templating" slug: "custom-format-templating" updated: 2025-11-26T14:39:24Z published: 2025-11-26T14:39:24Z canonical: "knowledge-base.rossum.ai/custom-format-templating" --- > ## Documentation Index > Fetch the complete documentation index at: https://knowledge-base.rossum.ai/llms.txt > Use this file to discover all available pages before exploring further. # Custom Format Templating Custom format templating extension allows users to create custom files in almost any shape or form. It works by defining a custom template and later calling it on export with the annotation data. ## Installation Custom format templating extension is provided and maintained by Rossum.ai in the form of webhook. To start using it, follow these steps: 1. Login to your Rossum account. 2. Navigate to **Extensions** → **My extensions**. 3. Click on **Create extension**. 4. Fill the following fields: 1. Name: `Custom format templating` 2. Trigger events: `Export` 3. Extension type: `Webhook` 4. URL (see below) 5. In "Advanced settings" select **Token owner** (should have Admin access) 6. In the "Additional notification metadata" enable `Schemas` 7. Click **Create the webhook**. | Environment | Webhook URL | | --- | --- | | EU1 Ireland | [https://elis.custom-format-templating.rossum-ext.app/](https://elis.custom-format-templating.rossum-ext.app/) | | EU2 Frankfurt | [https://shared-eu2.custom-format-templating.rossum-ext.app/](https://shared-eu2.custom-format-templating.rossum-ext.app/) | | US east coast | [https://us.custom-format-templating.rossum-ext.app/](https://us.custom-format-templating.rossum-ext.app/) | | Japan Tokyo | [https://shared-jp.custom-format-templating.rossum-ext.app/](https://shared-jp.custom-format-templating.rossum-ext.app/) | ## Basic usage > [!WARNING] > 🚧 WORK IN PROGRESS 🚧 > > We're still working on this part and would love to hear your thoughts! Feel free to [share your feedback](https://github.com/rossumai/university/discussions) or [submit a pull request](https://github.com/rossumai/university/pulls). Thank you! 🙏 > > Tracking issue: [https://github.com/rossumai/university/issues/382](https://github.com/rossumai/university/issues/382) ## Available configuration options ```json {  "export_configs": [    {      // Optional. Specifies resulting file content encoding. Default: "utf-8".      // Note: Characters that cannot be encoded in the specified encoding will be silently ignored.      "content_encoding": "utf-8",      // Name of the export template used for later reference in the export pipeline.      "export_reference_key": "example_invoice_template",      // In-line template of the file to be exported. You can either use this in-line version or      // use `file_content_template_multiline` for multiple lines instead.      "file_content_template": "…",      // Multiline template of the file to be exported. You can either use this multipline version      // or use `file_content_template` for in-line templates instead.      "file_content_template_multiline": [        // Rows of the template. Each row is a new line (no need for "\n" separators).        "…",        "…"      ]    }    // …  ] } ``` In the template definitions (`file_content_template or file_content_template_multiline`) you can reference any field from annotation object by using dot syntax (for example `{{field.document_id}})`. It is also possible to access the annotation payload like so: `{{payload['document']['original_file_name']}}`. This way, you can create a link to the annotation directly in the template, for example: `https://example.rossum.app/document/{{payload['annotation']['id']}}` . > [!WARNING] > ⚠️ WARNING ⚠️ > > Maximum five export configs can be defined per annotation export. ## Obtaining generated files Outputs from the **Custom format templating** webhook are not available anywhere in the UI. Instead, they are stored as a "[document relation](https://elis.rossum.ai/api/docs/#document-relation)". To get the actual document content, you need to call two API endpoints. First, you need to get the relevant relation: ```bash curl 'https://elis.rossum.ai/api/v1/document_relations?type=export&annotation=1234567&key=export_annotation_to_csv' \ --header 'Authorization: Bearer XYZ' ``` You can omit the `key` to get all available relations for given annotation. The response will look something like this: ```json {  "pagination": { "total": 1, "total_pages": 1, "next": null, "previous": null },  "results": [    {      "id": 1234567,      "type": "export",      "key": "export_annotation_to_csv",      "annotation": "https://elis.rossum.ai/api/v1/annotations/1234567",      "documents": ["https://elis.rossum.ai/api/v1/documents/1234567"],      "url": "https://elis.rossum.ai/api/v1/document_relations/1234567"    }  ] } ``` To get the actual generated document content, you need to call the following API endpoint (see the highlighted document URL above): ```bash curl 'https://elis.rossum.ai/api/v1/documents/1234567/content' \ --header 'Authorization: Bearer XYZ' ``` Note that you do not need to know these technical details. This extension is typically to be used in combination with [REST API Export extension](/help/docs/rest-api-export) which knows how to work with it. ## Configuration examples ### Original document (base64) ```json {  "export_configs": [    {      "export_reference_key": "export_original_file",      "file_content_template": "{{file.original_file|b64encode}}"    }  ] } ``` ### Custom CSV Define CSV header fields as well as the actual datapoints to be exported: ```json {  "export_configs": [    {      "export_reference_key": "export_annotation_to_csv",      "file_content_template": "Document ID,Document Type,Quantity\n{{field.document_id}},{{field.document_type}},{{field.line_items[0].item_quantity}}"    }  ] } ``` Alternatively, it is possible to leverage `file_content_template_multiline` for better readability: ```json {  "export_configs": [    {      "export_reference_key": "export_annotation_to_csv",      "file_content_template_multiline": [        "Document ID,Document Type,Quantity",        "{{field.document_id}},{{field.document_type}},{{field.line_items[0].item_quantity}}"      ],      "content_encoding": "utf-8"    }  ] } ``` Both of the configurations should generate something like this: ```plaintext Document ID,Document Type,Quantity 123456,tax_invoice,750 ``` Is also possible to iterate line items: ```json {  "export_configs": [    {      "export_reference_key": "export_annotation_to_csv",      "file_content_template_multiline": [        "Document ID,Document Type,Item Description,Item Quantity",        "{% for item in field.line_items %}{{field.document_id}},{{field.document_type}},{{item.item_description}},{{item.item_quantity}}\n{% endfor %}"      ],      "content_encoding": "utf-8"    }  ] } ``` The generated CSV would now contain all the line items, for example: ```plaintext Document ID,Document Type,Item Description,Item Quantity 123456,tax_invoice,AWS services #1,750 123456,tax_invoice,AWS services #2,750 123456,tax_invoice,AWS services #3,750 ``` Learn how to get the generated file in [**Obtaining generated files**](/help/docs/custom-format-templating#obtaining-generated-files) section. ### Custom XML Similarly to other formats, custom XML can be defined using the following template (notice the `|upper` and `|default` [filters](https://jinja.palletsprojects.com/en/stable/templates/#filters)): ```json {  "export_configs": [    {      "export_reference_key": "export_annotation_to_xml",      "content_encoding": "utf-8",      "file_content_template_multiline": [        "",        "  ",        "    
",        "      {{ field.document_id }}",        "      {{ field.document_type }}",        "      {{ field.language }}",        "      {{ field.date_issue }}",        "      {{ field.date_due }}",        "      {{ field.currency | upper }}",        "      {{ field.amount_total }}",        "      {{ field.amount_total_tax | default(0,true) }}",        "    
",        "  
",        "
"      ]    }  ] } ``` > [!TIP] > 💡 TIP > > If the fields may include any of the following chars (`>`, `<`, `&`, or `"`) you **SHOULD** escape it unless the variable contains well-formed and trusted HTML/XML like so: `{ field.name|e }` > > > > You can learn more about this (and other) filter(s) here: [https://jinja.palletsprojects.com/en/stable/templates/#working-with-manual-escaping](https://jinja.palletsprojects.com/en/stable/templates/#working-with-manual-escaping) ### Custom JSON Creates custom JSON templates with some header fields and line items (iteration over the line items is highlighted). ```json {  "export_configs": [    {      "export_reference_key": "export_annotation_to_json",      "content_encoding": "utf-8",      "file_content_template_multiline": [        "{",        "  \"document_id\": \"{{ field.document_id }}\",",        "  \"document_type\": \"{{ field.document_type }}\",",        "  \"line_items\": [",        "    {% for item in field.line_items %}{",        "      \"code\": \"{{ item.item_code }}\",",        "      \"description\": \"{{ item.item_description }}\",",        "      \"quantity\": {{ item.item_quantity }},",        "      \"amount\": {{ item.item_amount }},",        "    }{% if not loop.last %},{% endif %}",        "  {% endfor %}]",        "}"      ]    }  ] } ``` ### Custom TXT (The Tree) This is example of the Jinja2 language capabilities. The following example is a small Jinja program that generates simple ASCII art representation of a tree. The tree height is a parameter which can be changed, see line 15 in the example config. ```json {  "export_configs": [    {      "export_reference_key": "export_tree_ascii_art",      "content_encoding": "utf-8",      "file_content_template_multiline": [        "{%- macro draw_tree(height) -%}",        "{%- set width = height * 2 - 1 %}",        "{%- for level in range(1, height + 1) -%}",        "{%- set padding = (width - (level * 2 - 1)) // 2 %}",        "{{ ' ' * padding }}{{ '*' * (level * 2 - 1) }}{{ ' ' * padding }}",        "{%- endfor %}",        "{{ ' ' * ((width - 1) // 2) }}|{{ ' ' * ((width - 1) // 2) }}",        "{%- endmacro %}",        "{{ draw_tree(5) }}",        ""      ]    }  ] } ``` Result is a generated TXT file representing a tree with crown height of 5 rows: ```plaintext    *   ***  ***** ******* *********    | ``` > [!WARNING] > 💬 YOUR FEEDBACK MATTERS! > > Help us keep this page accurate and useful. Select **Yes** or **No** below, then use the feedback form to propose a correction, ask for clarification, or request a new article.