Skip to content

Matter Configuration

The matter.json file is the heart of each template. It defines fields, folder structure, and behaviour.

{
"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"
}

Display name shown in the template list. Required.

"name": "Estates"

Optional description shown below the name.

"description": "Deceased estates, probate, and administration"

Optional. Conventionally "2.0" for templates that use workflow stages and the current field schema. Defaults to "1.0" when omitted.

"version": "2.0"

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.

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).

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.

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:

PropertyDescription
titleCard heading
iconSF Symbol name for the card icon
fieldsArray of fields to display

Each field has:

PropertyDescription
labelDisplay label
keyDot-notation key from form data
copyableShow a copy button (optional, default false)
iconSF Symbol for this field (optional)

If no overview is defined, default cards for Matter, Client, Property, and Status are shown.

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.

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”.

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] }
]
}

Optional. Path (relative to the template folder) where the precedent .docx and .xlsx files live. Defaults to "precedents".

"precedents_path": "precedents"

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 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": [ ... ]
}
]
PropertyRequiredDescription
nameYesSection heading shown above the fields
fieldsYesArray of field objects (see Template Fields)
descriptionNoSub-heading shown under the name
workflow_stageNoWhich workflow stage tab this block appears under. Must match a string in workflow_stages exactly.
visible_whenNoCondition expression — hide the block when false. See Conditionals.
collapsedNoIf true, the block starts collapsed in the form

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.

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.

For Estates templates, the matter metadata includes fields for tracking the grant of probate or letters of administration:

Stored PropertyTemplate KeyDescription
grantTypeestate.grant_typeType of grant: Probate, Letters of Administration, etc.
grantNumberestate.grant_numberGrant/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.

Before deploying a new matter.json:

  1. Check JSON syntax — use a JSON validator (or python -m json.tool < matter.json)
  2. Restart Certum Draft — templates are loaded at startup; if your edits aren’t showing, reload the templates from Preferences → Templates
  3. Create a test matter — verify all fields appear in the expected workflow stage tabs
  4. Generate test documents — confirm {{ … }} placeholders resolve and any visible_when blocks behave as expected
  • Check file is named exactly matter.json
  • Validate JSON syntax
  • Confirm blocks is an array ([ ... ]) and not an object
  • Verify the field is inside a block’s fields array (also an array, not an object)
  • Check for missing commas in JSON
  • Ensure type is a valid field type: text, textarea, date, currency, number, phone, email, select, bool, checkbox, radio, or reference (note: bool, not boolean)
  • Confirm workflow_stages is a flat array of strings, not an array of objects ([{"id": "intake"}] silently fails to decode)
  • Confirm each block’s workflow_stage value exactly matches one of the strings in workflow_stages (case-sensitive)
  • Field name in document doesn’t match matter.json — check spelling and dot-notation
  • Field is hidden by a visible_when condition that’s false on this matter
  • Check for typos and case sensitivity