Selecting data with JSONPath
SHIPM8 templates use JSONPath Plus syntax to navigate data. You can test expressions at jsonpath.com.
A sample data structure
The examples on this page use the following port-call JSON:
{
"Data": [
{
"Ct_portcallfile": {
"eta": "2025-07-22T00:00:00",
"port name": "Amsterdam",
"__AdditionalData": {
"ship": {
"name": "Ocean Star"
},
"customer": {
"name": "Blue Tide Shipping",
"member": true,
"company": ""
},
"cargoRegistration": [
{
"cargo": "Crude Oil",
"quantity": 52000,
"blNumber": "BL-2025-001"
}
]
}
}
}
]
}
Picking out values
Use a dot-separated path inside {{ }} to reach any field:
| What to extract | Expression | Result |
|---|---|---|
| ETA | {{ Data.[0].Ct_portcallfile.eta }} | 2025-07-22T00:00:00 |
| Port name | {{ Data.[0].Ct_portcallfile.['port name'] }} | Amsterdam |
| Ship name | {{ Data.[0].Ct_portcallfile.__AdditionalData.ship.name }} | Ocean Star |
| Customer name | {{ Data.[0].Ct_portcallfile.__AdditionalData.customer.name }} | Blue Tide Shipping |
| Member flag | {{ Data.[0].Ct_portcallfile.__AdditionalData.customer.member }} | True |
| Company (empty) | {{ Data.[0].Ct_portcallfile.__AdditionalData.customer.company }} | (blank) |
| Cargo type | {{ Data.[0].Ct_portcallfile.__AdditionalData.cargoRegistration.[0].cargo }} | Crude Oil |
| Cargo quantity | {{ Data.[0].Ct_portcallfile.__AdditionalData.cargoRegistration.[0].quantity }} | 52000 |
| BL number | {{ Data.[0].Ct_portcallfile.__AdditionalData.cargoRegistration.[0].blNumber }} | BL-2025-001 |
Data types
JSONPath can reach any standard JSON data type. Targeting an object or array directly returns an internal object — always drill down to a scalar field for readable output.
| Type | Example | Result |
|---|---|---|
| String | {{ Data.[0].Ct_portcallfile.__AdditionalData.ship.name }} | Ocean Star |
| Number | {{ Data.[0].Ct_portcallfile.__AdditionalData.cargoRegistration.[0].quantity }} | 52000 |
| Boolean | {{ Data.[0].Ct_portcallfile.__AdditionalData.customer.member }} | True or False |
| Null / empty | {{ Data.[0].Ct_portcallfile.__AdditionalData.customer.company }} | (blank) |
| Object | {{ Data.[0].Ct_portcallfile }} | System.Dynamic.ExpandoObject — use a specific field instead |
| Array item (object) | {{ Data.[0].Ct_portcallfile.__AdditionalData.cargoRegistration.[0] }} | System.Dynamic.ExpandoObject — use .cargo, .quantity, etc. |
Arrays and indexes
Array indexes go in square brackets with a leading dot: .[0], .[1], etc.
✅ Correct:
{{ Data.[0].Ct_portcallfile.__AdditionalData.cargoRegistration.[0].cargo }}
❌ Incorrect:
{{ Data[0].Ct_portcallfile.__AdditionalData.cargoRegistration[0].cargo }} ← won't work
Looping through a list
When a field holds multiple items (e.g. several cargo registrations), loop with {{#each}} instead of hardcoding an index:
{{#each Data.[0].Ct_portcallfile.__AdditionalData.cargoRegistration}}
Cargo: {{ this.cargo }}, Quantity: {{ this.quantity }}, BL: {{ this.blNumber }}
{{/each}}
Inside the loop, this refers to the current item. Do not use a .[0] index inside an #each — the loop already iterates every item automatically.
Field names with spaces or special characters
If a field name contains spaces, wrap it in square brackets with single quotes:
✅ Correct:
{{ Data.[0].Ct_portcallfile.['port name'] }}
❌ Incorrect:
{{ Data.[0].Ct_portcallfile.port name }} ← won't work
The same bracket notation is required for field names containing dashes, dots, or that start with a digit:
✅ Correct:
{{ Data.[0].Ct_portcallfile.['arrival-eta'] }}
{{ Data.[0].Ct_portcallfile.['123status'] }}
Showing a boolean as Yes / No
Booleans render as True / False by default. Use ifEquals to show friendlier text:
{{#ifEquals Data.[0].Ct_portcallfile.__AdditionalData.customer.member true}}
Yes
{{else}}
No
{{/ifEquals}}
Rules to remember
| Rule | Detail |
|---|---|
| Array index syntax | Always .[0], never [0] |
| Spaces in field names | Use ['field name'] bracket notation |
| Special chars / leading digit | Same bracket notation: ['arrival-eta'], ['123id'] |
One expression per {{ }} | You cannot combine two paths in one expression |
No leading $ | The root context is implied; $.Data.[0]... is not needed |
| Case-sensitive | eta and ETA are different fields |
| Missing fields | Return a blank value — no error |