Skip to main content
A domain has a single, portable representation: a JSON definition holding the domain’s labels, its variables, and its activities. This is the form a domain takes when you export, import, or copy it, and it is the complete shape of everything a domain is made of. This page is the reference for that structure — every field, its type, and its allowed values. If you are authoring by hand you rarely write this JSON directly; you build the domain up from activities, equations, and variables, and TrueMath holds the definition for you. The structure here is what those pieces add up to, and what you produce when you generate a domain programmatically.
This is the definition shape — what a domain is. It is related to, but not the same as, the read shapes the API returns from GET /v1/domains/:id/activities: the definition relates activities to variables by key, while the read endpoints relate them by variable_id and carry server-side fields such as identity and version. Use this page for the portable definition; use Domains (API) for what a calculation or read endpoint returns.

Top-level structure

A definition is an object with four members:
Variables and activities relate to one another by key, not by position or by id — see How variables and activities relate.
What an author assigns, and what TrueMath assigns. A variable’s key is the only identifier you choose — the human-readable name you write in equations and input (loan_amount, interest_rate). Everything else is assigned by TrueMath, not author-chosen: every id (a UUID), each activity key (act_ followed by hex), and the domain’s key (dm_ followed by hex). All are stable for the life of the domain.
Generating a new domain. Omit every system-assigned identifier: leave out each id and each activity key, and give the domain object only a title and description. Supply just the author content — variable keys, labels, default_values, unit_options, and display configuration, plus each activity’s equation and variable_refs. You can also omit definition_schema_version. TrueMath assigns the identifiers on import. The id and activity key fields shown throughout this page appear in a definition exported from an existing domain, where TrueMath has already assigned them.

The domain object

The definition carries no identifier in the domain object — only its title and description. A domain’s identity is assigned and managed by TrueMath and is not part of the definition body. Importing a definition applies it to the domain you import it into, overriding that domain’s current contents; see Managing a domain.

Variables

Each entry in variables describes one variable: its key, its labels, its default, and how it is displayed.

Kinds

A variable’s kind says what its value is. How the value is read on input, how it is shown, and which vocabulary its format is drawn from all follow from it. It is one of:

Unit options

unit_options is a list of suggested units for the variable, in order, the first being its primary unit. It is a suggestion, not a restriction: a calculation can use any unit TrueMath recognizes whatever the list says. See Unit options.
The field is absent, not an empty array, when a variable has no unit options. Each entry is a canonical unit code from the unit catalog; an alias you write is canonicalized on save, so "feet" is stored as "ft". The list sits at the top level of the variable, beside kind, and only a number or no_separator variable can have one. For table, each entry of display_metadata.table.columns[] has its own, under the same rules. Publishing refuses a list on a kind that cannot have one, a list with a unit TrueMath does not recognize, and a list with the same unit twice. Nothing connects a list to default_value: a variable can default to 30 yr and offer only ["mo"]. See Unit options.

display_metadata

display_metadata holds the variable’s display configuration under a single key naming its structural type. Every scalar kind — number, percent, no_separator, and the four time kinds — nests under number; the others nest under table, bar_chart, or pie_chart.

Scalar variables — number

For number, percent, no_separator, duration, date, datetime, and time:
For number, percent, and no_separator that vocabulary is a decimal count: decimals_0 through decimals_9 for a fixed number of decimal places, or decimals_float for the value’s natural precision (at most 10 decimal places). For the four date and time kinds the same slot holds a format token matching the kind — date_med for a date, duration_hms for a duration. A token from the wrong vocabulary is rejected on save. See Choosing a format for the full list.
For those four kinds a default_value is stored as a combined "value unit" string in seconds — "1784592000 s" — or as the literal word today or now. You author it in the form you would write by hand; see Setting a default.

Table variables — table

Columns carry no unit field: each cell carries its own unit with its value — see Tables as a stored value. A column’s unit_options is not a unit either, and a cell can hold any unit whatever that list says.

Bar chart variables — bar_chart

A chart is a presentation of a table; the variable’s value stays a table and display_metadata.bar_chart configures how it is drawn.

Pie chart variables — pie_chart

Activities

Each entry in activities describes one activity: its equation, the variables it uses in order, and which of them it may solve for.

How variables and activities relate

Within a definition, activities and variables are connected by key:
  • An activity’s equation references variables by their key. Reusing the same key across activities refers to the same variable. This is how activities compose into a domain; see How activities compose.
  • An activity’s variable_refs names the same variables by key, in order, and marks which of them the activity may solve for.
Every key in equation and in variable_refs must match the key of an entry in variables. The id fields identify existing elements; they are not how activities point at variables. On import, a definition that does not match these rules is filled in rather than rejected:
  • A variable in variable_refs that the equation does not use stays part of the activity. The equation does not read it.
  • A key the equation uses but variable_refs omits is added after the listed entries, with calculable set to false.
  • An activity with no variable_refs, or with an empty array, takes its variables from the equation, in the order they first appear. With no variable_refs provided, only a variable written alone on one side of the equation is marked calculable.
  • A key with no entry in variables becomes a blank number variable, unless the domain you import into already has a variable with that key.
The read endpoint GET /v1/domains/:id/activities returns each activity’s variable_refs in the same order, but names each variable by variable_id instead of variable_key. Use the key-based shape on this page when generating or reading a portable definition.

Complete example

A self-contained excerpt of a mortgage domain — scalar variables, a table, a bar chart, and a pie chart, with the activities that drive them. Every key referenced in an equation or variable_refs array is defined below as a variable: