Matter Configuration
The matter.json file is the heart of each template. It defines fields, folder structure, and behaviour.
Basic Structure
Section titled “Basic Structure”{ "name": "Template Name", "description": "Template description", "version": "2.0", "workflow_stages": ["Intake", "..."], "blocks": [ { "name": "Block Name", "workflow_stage": "Intake", "fields": [ ... ] } ], "hidden_fields": [ ... ], "overview": [ ... ], "folders": [ "Correspondence", "Working Documents", ... ], "precedents_path": "precedents"}Top-Level Properties
Section titled “Top-Level Properties”Display name shown in the template list. Required.
"name": "Estates"description
Section titled “description”Optional description shown below the name.
"description": "Deceased estates, probate, and administration"version
Section titled “version”Optional. Conventionally "2.0" for templates that use workflow stages and the current field schema, or "2.1" if the template uses the address field type. Defaults to "1.0" when omitted.
"version": "2.1"features
Section titled “features”Optional. Declares which workspace features this matter type uses, so Certum Draft shows the matching sections without guessing from the template’s name. An array of strings:
| Value | What it turns on |
|---|---|
"settlement" | The Settlement workspace (adjustments ledger, settlement statements) |
"institutions" | The Institutions register (banks, super funds, insurers to notify) |
"estate_distribution" | The Estate section (net estate, per-beneficiary entitlements) |
"document_intake" | Reading dropped documents (death certificates, statements, ID) into the matter |
"features": ["institutions", "estate_distribution", "document_intake"]When features is omitted, Certum Draft falls back to the matter-type name (e.g. anything containing “Estate” gets the institutions and estate sections), so older packs keep working — but declare it explicitly on new templates.
folders
Section titled “folders”Folders created automatically when a new matter is made. Optional — if omitted, the firm-wide default folder list from Preferences is used.
"folders": [ "Correspondence", "Working Documents", "Accounts", "Safe Custody"]Use / in a path to create nested folders. Each path creates all parent folders automatically.
workflow_stages
Section titled “workflow_stages”Defines the tabbed stages that organise the matter form. Each stage becomes a tab in the Matter Workspace.
"workflow_stages": ["Intake", "Compliance", "Pre-Exchange", "Post-Exchange", "Settlement"]Each block in the template specifies which stage it belongs to via the workflow_stage property. The value must match one of the strings in workflow_stages exactly (case-sensitive).
AML/Compliance Stage
Section titled “AML/Compliance Stage”For matter types that require Anti-Money Laundering and compliance checks (Purchase, Sale, and Estates), add a “Compliance” stage as the second stage:
"workflow_stages": ["Intake", "Compliance", "Pre-Exchange", ...]Place AML verification blocks, client identification fields, and risk assessment fields in blocks with "workflow_stage": "Compliance". This stage only appears for templates that include it — Wills and Advice templates typically omit it.
overview
Section titled “overview”Define custom overview cards for the Matter Workspace Overview tab. When specified, these replace the default cards.
"overview": [ { "title": "Property", "icon": "house.fill", "fields": [ { "label": "Address", "key": "property.address", "copyable": true }, { "label": "Title Ref", "key": "property.title_reference" }, { "label": "Strata", "key": "property.is_strata", "icon": "building.2" } ] }, { "title": "Settlement", "icon": "calendar", "fields": [ { "label": "Exchange Date", "key": "matter.exchange_date" }, { "label": "Settlement Date", "key": "matter.settlement_date" }, { "label": "Purchase Price", "key": "purchase.price", "copyable": true } ] }]Each card has:
| Property | Description |
|---|---|
title | Card heading |
icon | SF Symbol name for the card icon |
fields | Array of fields to display |
Each field has:
| Property | Description |
|---|---|
label | Display label |
key | Dot-notation key from form data |
copyable | Show a copy button (optional, default false) |
icon | SF Symbol for this field (optional) |
If no overview is defined, default cards for Matter, Client, Property, and Status are shown.
hidden_fields
Section titled “hidden_fields”Computed or system-managed fields that don’t appear in the form but are available to templates. Same schema as a field inside a block — each entry needs key, type, and usually computed_from. Common uses: inverse booleans, derived display fields, legacy aliases.
"hidden_fields": [ { "key": "property.not_strata", "type": "bool", "computed_from": "!property.is_strata" }, { "key": "client.given_names", "type": "text", "help_text": "Legacy alias for client.given_name" }]See Conditionals for why inverse booleans like property.not_strata are now considered a legacy pattern — prefer not property.is_strata directly in templates.
scales
Section titled “scales”Named fee schedules referenced by computed_from: "scale(...)" formulas (e.g. probate filing-fee ladders). Each scale is an object mapping a name to a list of tiers.
"scales": { "probate_filing_fee": { "description": "NSW Supreme Court probate filing fee", "tiers": [ { "up_to": 100000, "base": 793, "per_thousand": 0, "excess_over": 0 }, { "up_to": 250000, "base": 1077, "per_thousand": 0, "excess_over": 0 } ] }}A null (or omitted) up_to on the final tier means “infinity”.
calendar
Section titled “calendar”Phase 1 critical-dates engine. Declarative rules for matter-specific key dates (cooling-off expiry, settlement, etc.) plus notification offsets. Only NSW public holidays are supported in the current release.
"calendar": { "jurisdiction": "NSW", "timezone": "Australia/Sydney", "dates": [ { "id": "cooling_off_expires", "title": "Cooling-off expires", "kind": "derived", "expose_as": "cooling_off.last_day", "derive": { "op": "add_business_days", "source_field": "transaction.exchange_date", "days": 5, "holiday_set": "nsw_public_holidays" } } ], "notifications": [ { "id": "cooling_off_t-1", "date_id": "cooling_off_expires", "offset_days": [-1, 0] } ]}The derive.op selects the date maths:
| Op | What it does | Key properties |
|---|---|---|
add_days | Adds calendar days to the source date | source_field, days |
add_business_days | Adds business days, skipping weekends and NSW public holidays | source_field, days, holiday_set |
add_months | Adds whole months to the source date | source_field, months |
latest_of | Resolves to the latest of several earlier rules’ dates — for statutory windows defined as “the later of X and Y” | date_ids |
Notes on the properties:
monthssays what it means foradd_months(e.g."months": 12for the family-provision limitation). Older packs put the month count indays; that still works, but prefermonthsso a 12-month rule doesn’t read as 12 days.latest_oftakesdate_ids— theids of earlier rules in thedatesarray — and refuses to compute until every referenced date resolves. A partial answer would understate a legal waiting period, so the entry simply waits rather than guessing.source_field_days(with optionaldefault_days) lets a form field override the day count for contract-specific periods.
precedents_path
Section titled “precedents_path”Optional. Path (relative to the template folder) where the precedent .docx and .xlsx files live. Defaults to "precedents".
"precedents_path": "precedents"icon and accent_color
Section titled “icon and accent_color”Optional cosmetic overrides for the template list. icon is an SF Symbol name; accent_color is a named colour (e.g. "purple", "teal", "amber").
Blocks
Section titled “Blocks”Blocks organise fields into logical sections. blocks is an array of block objects (not an object keyed by block name).
"blocks": [ { "name": "Client Details", "workflow_stage": "Intake", "fields": [ { "key": "client.surname", "label": "Surname", "type": "text", "required": true }, { "key": "client.given_name", "label": "Given Name(s)", "type": "text", "required": true } ] }, { "name": "Estate Information", "workflow_stage": "Intake", "collapsed": true, "visible_when": "matter.has_estate == true", "fields": [ ... ] }]Block Properties
Section titled “Block Properties”| Property | Required | Description |
|---|---|---|
name | Yes | Section heading shown above the fields |
fields | Yes | Array of field objects (see Template Fields) |
description | No | Sub-heading shown under the name |
workflow_stage | No | Which workflow stage tab this block appears under. Must match a string in workflow_stages exactly. |
visible_when | No | Condition expression — hide the block when false. See Conditionals. |
collapsed | No | If true, the block starts collapsed in the form |
settlement_workspace | No | On conveyancing templates, true/false overrides whether the block appears in the Settlement workspace |
Complete Example
Section titled “Complete Example”Here’s a trimmed matter.json for an Estates template:
{ "name": "Estates", "description": "Deceased estates, probate, and administration", "version": "2.0", "workflow_stages": ["Intake", "Probate Application", "Asset Collection", "Distribution"], "folders": [ "Correspondence", "Working Documents", "Court Documents", "Accounts", "Safe Custody" ], "blocks": [ { "name": "Client Details", "workflow_stage": "Intake", "fields": [ { "key": "client.title", "label": "Title", "type": "select", "options": ["Mr", "Mrs", "Ms", "Dr"] }, { "key": "client.given_name", "label": "Given Name(s)", "type": "text", "required": true }, { "key": "client.surname", "label": "Surname", "type": "text", "required": true }, { "key": "client.full_name", "label": "Full Name", "type": "text", "computed_from": "{client.title} {client.given_name} {client.surname}" }, { "key": "client.street_address", "label": "Street Address", "type": "text" }, { "key": "client.email", "label": "Email", "type": "email" } ] }, { "name": "Estate Information", "workflow_stage": "Intake", "fields": [ { "key": "deceased.given_name", "label": "Deceased Given Name(s)", "type": "text", "required": true }, { "key": "deceased.surname", "label": "Deceased Surname", "type": "text", "required": true }, { "key": "deceased.date_of_death", "label": "Date of Death", "type": "date", "required": true }, { "key": "estate.has_will", "label": "Deceased Left a Will", "type": "bool", "default_value": "false" }, { "key": "estate.date_of_will", "label": "Date of Will", "type": "date", "visible_when": "estate.has_will == true" } ] } ], "hidden_fields": [ { "key": "deceased.full_name", "type": "text", "computed_from": "{deceased.given_name} {deceased.surname}" } ], "precedents_path": "precedents"}See Template Fields for every field type and option, and Conditionals for the syntax of visible_when and computed_from.
Institutions
Section titled “Institutions”Matters can reference financial institutions (banks, lenders, insurers). The MatterMetadata supports an institutions array for storing institution details such as incoming/outgoing mortgagees, insurance companies, or settlement agents.
Certum Draft includes a bundled institution catalog with over 1,500 entries. Users search and select from this catalog when filling in institution fields, ensuring consistent naming and accurate BSB/contact details.
Estate Grant Fields
Section titled “Estate Grant Fields”For Estates templates, the matter metadata includes fields for tracking the grant of probate or letters of administration:
| Stored Property | Template Key | Description |
|---|---|---|
grantType | estate.grant_type | Type of grant: Probate, Letters of Administration, etc. |
grantNumber | estate.grant_number | Grant/filing number assigned by the court |
grantIssuedAt | (not in template context) | Date the grant was issued — stored on the matter, used in the workspace UI, but not currently projected into the template render context. |
These are stored on the MatterMetadata. The grant type and number are projected into the template context with the keys shown above.
Validation
Section titled “Validation”Before deploying a new matter.json:
- Check JSON syntax — use a JSON validator (or
python -m json.tool < matter.json) - Restart Certum Draft — templates are loaded at startup; if your edits aren’t showing, confirm the Templates Root in Settings → Paths points at the folder you edited
- Create a test matter — verify all fields appear in the expected workflow stage tabs
- Generate test documents — confirm
{{ … }}placeholders resolve and anyvisible_whenblocks behave as expected
Common Issues
Section titled “Common Issues”Template doesn’t appear
Section titled “Template doesn’t appear”- Check file is named exactly
matter.json - Validate JSON syntax
- Confirm
blocksis an array ([ ... ]) and not an object
Fields don’t show
Section titled “Fields don’t show”- Verify the field is inside a block’s
fieldsarray (also an array, not an object) - Check for missing commas in JSON
- Ensure
typeis a valid field type:text,textarea,date,currency,number,phone,email,select,bool,checkbox,radio,reference, oraddress(note:bool, notboolean)
An entire workflow stage tab is empty
Section titled “An entire workflow stage tab is empty”- Confirm
workflow_stagesis a flat array of strings, not an array of objects ([{"id": "intake"}]silently fails to decode) - Confirm each block’s
workflow_stagevalue exactly matches one of the strings inworkflow_stages(case-sensitive)
Placeholder shows [MISSING: …]
Section titled “Placeholder shows [MISSING: …]”- Field name in document doesn’t match
matter.json— check spelling and dot-notation - Field is hidden by a
visible_whencondition that’s false on this matter - Check for typos and case sensitivity