Single
The straightforward case. Pick the template and the column on it the value has to match — usually that template’s id or code column. A reference is matched case-insensitively and trimmed, so ACME matches
acme. Blank cells are skipped: an absent reference is absent, not broken. A
cell that doesn’t match records:
Polymorphic
When a column references different things on different rows — aRelated To id
that points at a customer on some rows and a supplier on others — use the
Polymorphic tab.
Three settings:
- Discriminator — the column on this template whose value says what kind of
thing the row points at. Typically a
TypeorEntitycolumn holdingcustomer/supplier. - Branches — one row per discriminator value, mapping each to the template Vern should check. Add Branch for each.
- Target — the column to search in those templates. Every branch uses the same column name, so name the id column consistently across them.
- The discriminator’s value is in the branch list → the reference is checked against that one template only.
- The discriminator is empty, or holds a value you haven’t mapped → it falls back to OR semantics: the reference passes if it exists in any listed template. This is looser, not stricter. Add a branch for every value your data actually contains, or the unmapped ones are checked more weakly than the rest.
References inside a structured value
Sometimes the thing that must exist isn’t the cell — it’s a field inside it. ARelated Records column holding a list like this references two records, not
one:
- Referenced column — the template and column to match against, as with a single link.
- Which field holds the reference — picked from the column’s own schema, not typed. Only the fields a reference can actually be read from are offered, so an unevaluatable path can’t be authored.
- A second field says which column to match (optional) — for data where each entry carries its own idea of which key it is quoting. Choosing one gives you a key table: each label in the data maps to the target column it resolves against.
contact → Contact ID and listing → Listing Ref means a contact entry is
checked against Contact ID and a listing entry against Listing Ref. A
label that isn’t in the table is a violation, not a pass — which is the whole
point: “use old_id here, not record_id” stops being a note in a document.
What’s checked, and where
A structured reference reports three distinct problems, so you can tell a shape error from a dangling one:
Structured references are checked during an import run and in its preview,
where the agent reports them before you approve. The sheet grid doesn’t re-check
them when you edit a cell afterwards — it reads a link column as a single value.
Plain and polymorphic links are re-checked live in the grid.
Reference paths
The editor writes the path for you, and it is what the API stores. Three forms, and only three:
Anything else is refused when you save, rather than stored as a rule that looks
authored and quietly never runs. A few combinations are also refused for the same
reason:
- A Discriminator can’t be combined with a reference path — a row-level discriminator picks one target for the whole row, while each entry in a list may point somewhere different. Use the key table instead.
- A key path must name a field, not a bare
$[*], and it must sit on the same side of the array as the value path. - A key path requires a key table; a key table requires a key path.
Links and the Validation Rule dropdown
A link rule is enforced whenever it is present, whatever the dropdown says — so a column can be shape-checked and reference-checked at once, which is the usual arrangement for a structured column. Setting the dropdown to Link additionally turns on two things that read it directly:- the grid styles link errors and re-checks a cell as you edit it,
- the nested webhook export sends the referenced record rather than the raw value.
Over the API
Link rules live on the column’slinkRule array, which
PATCH /templates/{slug} accepts and
template reads return. Two cautions:
- A
columnsupdate is a full replacement, andlinkRuleis not carried over for you the wayschemais. Echo the rule back with the column, or the link is removed. - A rule names its target template by internal id, which the public API doesn’t expose. Author links in the dashboard; the API is for preserving and reading them.
Next
- Column options — the rest of the per-column settings.
- Structured values — declaring the shape a reference sits inside.
- Webhooks — what a link does to the exported payload.