Create a template
curl --request POST \
--url https://clarus-api.com/api/templates \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-Clarus-Subdomain: <api-key>' \
--data '
{
"data": {
"type": "templates",
"attributes": {
"template_type_id": 1,
"name": "Custom Dispatch Note",
"default": false,
"orientation": "Portrait",
"page_height": 297,
"page_width": 210,
"top": 10,
"bottom": 10,
"left": 10,
"right": 10,
"header_height": 20,
"header_spacing": 5,
"footer_height": 15,
"footer_spacing": 5
}
}
}
'import requests
url = "https://clarus-api.com/api/templates"
payload = { "data": {
"type": "templates",
"attributes": {
"template_type_id": 1,
"name": "Custom Dispatch Note",
"default": False,
"orientation": "Portrait",
"page_height": 297,
"page_width": 210,
"top": 10,
"bottom": 10,
"left": 10,
"right": 10,
"header_height": 20,
"header_spacing": 5,
"footer_height": 15,
"footer_spacing": 5
}
} }
headers = {
"Authorization": "Bearer <token>",
"X-Clarus-Subdomain": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
Authorization: 'Bearer <token>',
'X-Clarus-Subdomain': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
data: {
type: 'templates',
attributes: {
template_type_id: 1,
name: 'Custom Dispatch Note',
default: false,
orientation: 'Portrait',
page_height: 297,
page_width: 210,
top: 10,
bottom: 10,
left: 10,
right: 10,
header_height: 20,
header_spacing: 5,
footer_height: 15,
footer_spacing: 5
}
}
})
};
fetch('https://clarus-api.com/api/templates', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"data": {
"id": 123,
"type": "templates",
"attributes": {
"template_type_id": 1,
"name": "Custom Dispatch Note",
"default": false,
"orientation": "Portrait",
"page_height": 297,
"page_width": 210,
"top": 10,
"bottom": 10,
"left": 10,
"right": 10,
"header_height": 20,
"header_spacing": 5,
"footer_height": 15,
"footer_spacing": 5
}
}
}{
"error": "<string>"
}{
"errors": [
{
"code": 123,
"symbol": "<string>",
"details": "<string>",
"source": "<string>",
"context": {}
}
]
}Templates
Create a template
Create a new Liquid HTML print template for generating documents such as dispatch notes, picking notes, and invoices.
POST
/
api
/
templates
Create a template
curl --request POST \
--url https://clarus-api.com/api/templates \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-Clarus-Subdomain: <api-key>' \
--data '
{
"data": {
"type": "templates",
"attributes": {
"template_type_id": 1,
"name": "Custom Dispatch Note",
"default": false,
"orientation": "Portrait",
"page_height": 297,
"page_width": 210,
"top": 10,
"bottom": 10,
"left": 10,
"right": 10,
"header_height": 20,
"header_spacing": 5,
"footer_height": 15,
"footer_spacing": 5
}
}
}
'import requests
url = "https://clarus-api.com/api/templates"
payload = { "data": {
"type": "templates",
"attributes": {
"template_type_id": 1,
"name": "Custom Dispatch Note",
"default": False,
"orientation": "Portrait",
"page_height": 297,
"page_width": 210,
"top": 10,
"bottom": 10,
"left": 10,
"right": 10,
"header_height": 20,
"header_spacing": 5,
"footer_height": 15,
"footer_spacing": 5
}
} }
headers = {
"Authorization": "Bearer <token>",
"X-Clarus-Subdomain": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
Authorization: 'Bearer <token>',
'X-Clarus-Subdomain': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
data: {
type: 'templates',
attributes: {
template_type_id: 1,
name: 'Custom Dispatch Note',
default: false,
orientation: 'Portrait',
page_height: 297,
page_width: 210,
top: 10,
bottom: 10,
left: 10,
right: 10,
header_height: 20,
header_spacing: 5,
footer_height: 15,
footer_spacing: 5
}
}
})
};
fetch('https://clarus-api.com/api/templates', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"data": {
"id": 123,
"type": "templates",
"attributes": {
"template_type_id": 1,
"name": "Custom Dispatch Note",
"default": false,
"orientation": "Portrait",
"page_height": 297,
"page_width": 210,
"top": 10,
"bottom": 10,
"left": 10,
"right": 10,
"header_height": 20,
"header_spacing": 5,
"footer_height": 15,
"footer_spacing": 5
}
}
}{
"error": "<string>"
}{
"errors": [
{
"code": 123,
"symbol": "<string>",
"details": "<string>",
"source": "<string>",
"context": {}
}
]
}Request Structure
{
"data": {
"type": "templates",
"attributes": {
"template_type_id": 1,
"name": "Custom Dispatch Note",
"default": false,
"print_params": {
"orientation": "Portrait",
"page_height": 297,
"page_width": 210,
"top": 10,
"bottom": 10,
"left": 10,
"right": 10,
"header_height": 20,
"header_spacing": 5,
"footer_height": 15,
"footer_spacing": 5
}
}
}
}
Required Fields
| Field | Type | Description |
|---|---|---|
template_type_id | integer | ID of the template type (see Template Type Discovery below) |
Optional Fields
| Field | Type | Description |
|---|---|---|
name | string | Display name for the template |
default | boolean | Whether this is the default template for its type |
template_header_id | integer | ID of a template to use as header |
template_footer_id | integer | ID of a template to use as footer |
print_params | object | Print layout parameters (see below) |
Print Parameters
All dimensions are in millimeters (mm).| Parameter | Type | Description |
|---|---|---|
orientation | string | Portrait or Landscape |
page_height | number | Page height (e.g., 297 for A4) |
page_width | number | Page width (e.g., 210 for A4) |
top | number | Top margin |
bottom | number | Bottom margin |
left | number | Left margin |
right | number | Right margin |
header_height | number | Height of the header area |
header_spacing | number | Spacing between header and body |
footer_height | number | Height of the footer area |
footer_spacing | number | Spacing between body and footer |
Template Type Discovery
Default template type codes (IDs vary per tenant but codes are consistent):| Code | Description |
|---|---|
dispatch_note | Dispatch note for outbound shipments |
picking_note | Picking instructions for warehouse staff |
commercial_invoice | Commercial invoice for international shipments |
invoice | Billing invoice |
put_away_note | Put-away instructions for received goods |
pre_receipt | Pre-receipt document for expected deliveries |
pre_pick_label | Label printed before picking |
storage_unit_labels | Labels for storage units (pallets, cages, etc.) |
pick_storage_unit_label | Label for storage units created during picking |
Template Types and Liquid Variables
Each template type has access to different variables in Liquid templates. Top-level variables and their key nested properties:dispatch_note
record- the goods out record (reference, created_at, status)lines- goods out lines (product.code, product.description, quantity)carrier- carrier details (name)address- delivery address (address_1 through address_5, postcode, country_code)account- stock account (name, code, address.*)warehouse- warehouse (code, address.*)customer- end customer (name, code)subdomain- tenant info (currency.code, tax_rate.component_rate)sales_order- linked sales order (reference)total_weight- total weight of the shipmentproducts- product list with details
picking_note
goods_out_pick_list- pick list record (reference)tasks- pick tasks (location, product, quantity)carrier- carrier detailsaddress- delivery addressaccount- stock accountwarehouse- warehouse detailscustomer- end customersubdomain- tenant info
commercial_invoice
shipment- shipment record (created_at)packages- packages with dimensions.weight, stocks[].product.code/description/commodity_code/country_of_manufacture, stocks[].quantity, stocks[].dimensions.value/weightaccount- stock account (name, address.*, gb_eori_number)warehouse- warehouse (address.country_code)subdomain- tenant info (currency.code, tax_rate.component_rate)goods_out- outbound order (address.*)
invoice
record- invoice recordaccount- stock accountcompany- company detailslines- invoice lines
put_away_note
goods_in_receipt- receipt recordgoods_in_receipt_lines- receipt lineswarehouse- warehouse detailsaccount- stock accountsupplier- supplier detailscarrier- carrier detailssubdomain- tenant infotasks- put-away tasks
pre_receipt
goods_in_receipt- receipt recordaccount- stock accountwarehouse- warehouse detailscarrier- carrier detailssupplier- supplier detailsinbound_good_kind- type of inbound goodlocation- receiving locationlines- receipt lines
pre_pick_label
goods_out_pick_list- pick list recordgoods_out- outbound orderproduct- product details
storage_unit_labels
stocks_lines[]- stock line records with: reference, product.code, product.description, goods_in_receipt, batch, account, location, confirmed_quantity, custom fields (boolean1-5, datetime1-5, integer1-5, string1-5)
pick_storage_unit_label
record- storage unit recordsubdomain- tenant info (company details)
Liquid Template Syntax
Templates use Liquid syntax:<h1>Dispatch Note: {{ record.reference }}</h1>
<p>Date: {{ record.created_at | date: "%d/%m/%Y" }}</p>
{% for line in lines %}
<tr>
<td>{{ line.product.code }}</td>
<td>{{ line.quantity | times: 1 }}</td>
<td>{{ line.price | plus: 0 }}</td>
</tr>
{% endfor %}
{% if carrier %}
<p>Carrier: {{ carrier.name }}</p>
{% endif %}
Workflow
- Create template - POST /templates with template_type_id and print parameters
- Upload Liquid HTML - POST /templates//attachment with your .html.liquid file
- Test print - PATCH /templates//test to generate a test PDF
- Download test - Use Documents endpoints (POST /documents//download) to retrieve the generated PDF
- Set as default - Optionally PATCH /templates/ with
default: true
Authorizations
OAuth 2.0 authentication. Use the client credentials or authorization code flow to obtain an access token.
FlowAuthorization Code
- Authorization URL
- https://clarus-api.com/oauth/authorize
- Token URL
- https://clarus-api.com/oauth/token
FlowClient Credentials
- Token URL
- https://clarus-api.com/oauth/token
The subdomain/tenant name identifying which tenant's data to access. Required for all API requests.
Body
application/json
Show child attributes
Show child attributes
Response
Template created successfully
Show child attributes
Show child attributes

