This reference documents all available field types for defining Schemas in Ligantic. Schemas define the structure of your data and are the foundation for both Experiences and Flows.
Field Type | Description | Supported Validations |
|---|---|---|
| Text values | required, minLength, maxLength, pattern, minWords, maxWords |
| Numeric values | required, min, max |
| True/false values | required, mustBeChecked, mustNotBeChecked |
| Date and datetime values | required |
| Time duration values | required |
| Recurring event/period rules (RRULE / RFC 5545) | required |
| File attachments | required, minLength, maxLength |
| Rich text content | required, minLength, maxLength, minBlocks, maxBlocks, minWords, maxWords |
| Geographic data | required |
| Nested object structure | required |
| List of values | required, minLength, maxLength |
| Link to other Records | required |
All field types share these base properties:
Property | Type | Required | Default | Description |
|---|---|---|---|---|
|
| Yes | — | Field type identifier |
|
| Yes | — | Display name (min 1 character) |
|
| No |
| Sort order in UI |
|
| No |
| Help text for the field |
|
| No |
| Whether field is required |
|
| No |
| Show in table views |
stringText values with optional display modes and validation.
Property | Type | Required | Default | Description |
|---|---|---|---|---|
|
| Yes | — | Field type identifier |
|
| No |
| Input display mode |
|
| No | — | Placeholder text |
|
| No | — | Options for select display |
|
| No |
| Default value |
|
| No | — | Validation rules |
Mode | Description | Use Case |
|---|---|---|
| Single-line text input | Names, emails, short text |
| Multi-line text input | Descriptions, notes |
| Dropdown selection | Predefined choices |
| Radio button group | Single choice selection |
select options support two formats:
"Option" (label and value are both "Option"){ "label": "Option Label", "value": "option-value" }required — Field must have a valueminLength — Minimum character countmaxLength — Maximum character countpattern — Regex pattern matchminWords — Minimum word countmaxWords — Maximum word count{
"type": "string",
"name": "Email Address",
"display": "text",
"placeholder": "Enter your email",
"validations": [
{
"rules": [
{ "type": "required", "message": "Email is required" },
{
"type": "pattern",
"value": "^[^@]+@[^@]+\\.[^@]+$",
"message": "Invalid email format"
}
]
}
]
}numberNumeric values (integers or decimals).
Property | Type | Required | Default | Description |
|---|---|---|---|---|
|
| Yes | — | Field type identifier |
|
| No |
| Default value |
|
| No | — | Validation rules |
required — Field must have a valuemin — Minimum value (inclusive)max — Maximum value (inclusive){
"type": "number",
"name": "Age",
"default": 18,
"validations": [
{
"rules": [
{ "type": "required" },
{ "type": "min", "value": 0, "message": "Age must be positive" },
{ "type": "max", "value": 150, "message": "Invalid age" }
]
}
]
}In the editor, a number field also accepts arithmetic expressions. Prefix the value with = to evaluate it on blur or Enter, for example, =2 + 3 * 4 commits 14.
+, -, *, /, and x/X for multiplication; parentheses for grouping; unary +/- for signs.=1.5e-2 commits 0.015.% divides the number by 100. In additive contexts the percent is relative to the other operand: =100 + 10% commits 110 and =100 - 10% commits 90. In multiplicative contexts it is an absolute fraction: =100 * 10% commits 10.booleanTrue/false toggle values.
Property | Type | Required | Default | Description |
|---|---|---|---|---|
|
| Yes | — | Field type identifier |
|
| No |
| Default value |
|
| No | — | Validation rules |
required — Field must have a value (true or false, not null)mustBeChecked — Field must be true; intended for consent or terms-and-conditions style checkboxesmustNotBeChecked — Field must be false; intended for flows where a checkbox must remain uncheckedrequired only enforces that the stored value is not null or undefined. Both true and false satisfy this rule.mustBeChecked enforces an explicit true value. false, null, and undefined fail validation.mustNotBeChecked enforces an explicit false value. true, null, and undefined fail validation.mustBeChecked for opt-in consent flows. Leave the field without validations when the checkbox is optional.mustNotBeChecked when the unchecked state is the valid submission requirement.{
"type": "boolean",
"name": "Accept Terms",
"default": false,
"validations": [
{
"rules": [{ "type": "mustBeChecked", "message": "You must accept the terms" }]
}
]
}dateDate and datetime values. Supports per-value timezone storage via IANA timezone identifiers (for example, 2024-05-15T23:20:16+10:00[Australia/Melbourne]), configurable display formats, and timezone display preferences.
When a datetime includes both an offset and an IANA timezone annotation, the annotated timezone is treated as authoritative for wall-clock scheduling. If they conflict, the value is normalised by preserving the provided wall time in the annotated timezone (the offset is adjusted to match the zone).
Property | Type | Required | Default | Description |
|---|---|---|---|---|
|
| Yes | — | Field type identifier |
|
| No |
| Include time component |
|
| No |
| Default value or special value |
|
| No | — | Default display format for this field (see below) |
|
| No | — | Show dates in the stored (source) or viewer's timezone |
|
| No | — | Validation rules |
The defaultFormat property controls how date values are displayed. It uses a discriminated union:
Type | Properties | Description |
|---|---|---|
|
| One of the built-in format presets (see below) |
|
| A custom CLDR/Unicode date format pattern |
Preset | Example Output | Notes |
|---|---|---|
|
| Date only |
|
| Date only |
|
| Date only |
|
| Date only |
|
| Requires |
|
| Requires |
|
| With timezone name |
|
| Full date + time + timezone |
|
| Time only, requires |
Uses CLDR/Unicode date format tokens. When timezoneDisplay resolves a timezone ("source" or "viewer"), custom patterns are rendered in that timezone. If no display timezone can be resolved, formatting falls back to the runtime local timezone. Common tokens:
yyyy — 4-digit year, MM — 2-digit month, dd — 2-digit dayHH — 24-hour, hh — 12-hour, mm — minutes, ss — secondsa — AM/PM, EEEE — full weekday name, MMMM — full month nameExample: "dd/MM/yyyy HH:mm" → 15/01/2024 14:30
When includeTime is true, the timezoneDisplay property controls which timezone is used for rendering:
"source" (default): Display in the timezone stored with the value"viewer": Convert to the viewer's timezone (from user preferences or browser)When displaying a date value, formats are resolved in this order:
defaultFormat — the Schema field's configured default formatValue | Description |
|---|---|
| Current date and time |
| Current date at midnight |
ISO string | Specific date/time value |
"today" uses the calendar date in the viewer's timezone when one is available (for example, Flows that create Records use the triggering user's timezone). Otherwise it uses the runtime's timezone, which is the browser timezone in forms. Date-only fields get a plain date such as 2026-04-08. Fields with includeTime: true get midnight in that timezone with its IANA identifier, such as 2026-04-08T00:00:00+10:00[Australia/Brisbane].
required — Field must have a value{
"type": "date",
"name": "Event Date",
"includeTime": true,
"default": "now",
"defaultFormat": {
"type": "preset",
"preset": "longDateTime"
},
"timezoneDisplay": "viewer",
"validations": [
{
"rules": [{ "type": "required" }]
}
]
}durationTime duration values (ISO 8601 duration format).
Property | Type | Required | Default | Description |
|---|---|---|---|---|
|
| Yes | — | Field type identifier |
|
| No | — | Validation rules |
required — Field must have a value. A zero duration (PT0S) counts as a value and satisfies required.Duration supports no other constraints: there is no minimum, maximum, allowed-unit or precision option.
Durations use ISO 8601 designator format: P[n]Y[n]M[n]W[n]DT[n]H[n]M[n]S
Examples:
PT1H — 1 hourPT30M — 30 minutesP1D — 1 dayP1W — 1 weekP1Y2M3D — 1 year, 2 months, 3 days-PT1H30M — negative 1 hour 30 minutesPT0.5S — half a secondWhat is accepted:
Zero | Yes — |
Negatives | Yes, with a leading |
Weeks | Yes |
Fractional values | Yes, on the smallest unit present, down to nanosecond precision |
Mixed signs | No — |
Only ISO 8601 is accepted. Values such as "90 minutes", "1:30" and a bare number are rejected. The API, CSV import, the editor, and AI-driven Flows accept exactly the same set of values.
Durations are entered through a segmented control with a field per unit — years, months, weeks, days, hours, minutes, seconds — plus a sign toggle that appears when the value is negative or when you engage the control. Negative durations are legal.
Values are stored exactly as authored and are never normalised. A duration entered as PT90M stays PT90M; it is shown as 90 minutes in the control and displayed as 90m, not 1h 30m.
Stepping a field with the arrow keys carries into the next unit — 60s to 1m, 60m to 1h, 24h to 1d, 30d to 1mo, 12mo to 1y. Typing a value directly is never rewritten: type 31 into days and the value stays 31 days.
Display uses compact unit notation, largest unit first, with zero components omitted: 1y 2mo 3d 4h 5m 6s. Negatives take a leading minus (-1h 30m). A zero duration displays as 0s; an unset field displays as empty.
Durations sort and compare by elapsed time, not by the text of the stored value. Calendar units have no fixed length, so comparison uses a fixed conversion: one month counts as 30 days, and one day counts as 24 hours.
Consequences worth knowing:
P1M, P30D and PT720H all compare as equal.P1Y counts as 360 days, so P1Y is less than P365D.eq matches on elapsed time, so filtering a field for P1M also returns Records storing P30D.Equality follows the same rule as ordering, so filtering for eq P1M returns the same Records as gte P1M AND lte P1M.
Records that tie on elapsed time fall back to the stored text for a stable, repeatable order.
The comparison operators eq, ne, gt, gte, lt, lte, in and nin all use this rule. isNull and isNotNull test only for the presence of a value.
CSV export writes the bare ISO 8601 string as stored (P1M, not 1mo), and CSV import accepts the same, so a round trip is lossless. An empty cell imports as unset; an unparseable one is reported as an invalid file rather than being silently guessed at.
In generated JSON Schema — including the tool schemas handed to AI models — a duration field is emitted as a string with format: "duration" and a matching pattern.
{
"type": "duration",
"name": "Meeting Length",
"validations": [
{
"rules": [{ "type": "required" }]
}
]
}recurrenceA recurring event or period, grounded in RRULE / RFC 5545. A recurrence is a rule + a DTSTART anchor + an optional extent (duration). With no extent it is a point event ("deliver every Monday"); with an extent it is a period ("a delivery window each Monday, 09:00–12:00"). This is the RFC 5545 model: a period is an event with a DURATION.
Occurrence expansion is driven by rrule-temporal (Temporal-native), so every generated occurrence is the platform's own Temporal.ZonedDateTime and wall-clock time is preserved across DST — a rule anchored at 09:00[America/Chicago] fires at 09:00 local wall time on every occurrence, including across a spring-forward. The full RFC 5545 grammar is supported, including BYSETPOS ("the 2nd / last Friday").
Property | Type | Required | Default | Description |
|---|---|---|---|---|
|
| Yes | — | Field type identifier |
|
| No |
| Anchor carries a time component. When |
|
| No | — | Validation rules |
required — Field must have a valueThe stored value is a structured, JSON-safe object holding the RFC 5545 recurrence parts, a ZonedDateTime ISO anchor, and an optional ISO-8601 duration extent (reusing the duration representation):
Field | Type | Description |
|---|---|---|
| ZonedDateTime ISO string | The anchor (required). Carries an IANA zone annotation |
|
| Recurrence frequency (required) |
|
| Every |
|
| Stop after |
| UTC ZonedDateTime ISO string | Stop after this instant. Must be UTC when the anchor carries a zone (RFC 5545) |
|
| Weekday tokens: |
|
| Restrict to these months |
|
| Restrict to these days of month (negative = from end) |
|
| Restrict to these days of year |
|
| Restrict to these week numbers |
|
| Select the n-th / last item after the other |
|
| Restrict to these hours |
|
| Restrict to these minutes |
|
| Restrict to these seconds (60 = leap second) |
|
| Week start day (default |
| ZonedDateTime ISO string[] | Explicitly excluded occurrences |
| ZonedDateTime ISO string[] | Additional (one-off) occurrences |
| ISO 8601 duration | The extent — makes the recurrence a period rather than a point |
The RFC 5545 RRULE string is a derived interop form of this value, not the canonical storage. It can be produced with recurrenceToRRuleString (emits the DTSTART;TZID=… + RRULE lines) and parsed with parseRRuleString(rruleString, dtstart) — the dtstart anchor is a required parameter, and RSCALE/SKIP parts (RFC 7529) are rejected rather than silently dropped.
{
"type": "recurrence",
"name": "Delivery Schedule",
"includeTime": true,
"validations": [{ "rules": [{ "type": "required" }] }]
}A value for that field — "every Monday at 09:00 America/Chicago, for a 3-hour window, up to 10 times":
{
"dtstart": "2024-01-01T09:00:00-06:00[America/Chicago]",
"freq": "WEEKLY",
"byDay": ["MO"],
"count": 10,
"duration": "PT3H"
}fileFile attachments with type restrictions.
Property | Type | Required | Default | Description |
|---|---|---|---|---|
|
| Yes | — | Field type identifier |
|
| No |
| Allow multiple files |
|
| No |
| Show media and document previews |
|
| Yes | — | Allowed file type categories |
|
| No |
| Max file size in bytes (5MB default) |
|
| No | — | Validation rules |
Category | Extensions |
|---|---|
| jpg, jpeg, png, gif, webp, svg |
| mp4, webm, mov, avi |
| mp3, wav, ogg, m4a |
| pdf, doc, docx, txt, rtf |
| xls, xlsx, csv |
| ppt, pptx |
| zip, rar, 7z, tar, gz |
| js, ts, py, java, html, css, json |
required — At least one file must be uploadedminLength — Minimum number of uploaded files when multiple: truemaxLength — Maximum number of uploaded files when multiple: truerequired ensures the field is not empty.minLength and maxLength count the number of uploaded files, not the length of file names.multiple: true.maxLength validation group has an activation rule, the editor only disables additional uploads while that activation rule matches the current form values.maxSize continues to apply to each file individually.maxLength is reached, the UI normally blocks further uploads; in rare cases, more files can still be uploaded.When displayMediaPreview is true, supported images, video, audio, DOCX, PDF, and PPTX files are rendered inline. DOCX and PDF files are displayed as paginated document previews; PPTX files are displayed as a scrollable slide preview. In Record tables, document files remain filename links instead of rendering inline; a preview button opens the full document in a modal. The same button appears in the top-left of an inline document preview. PDFs remain file links when the browser does not support canvas rendering. Other file types remain file links with a download action.
{
"type": "file",
"name": "Profile Photo",
"multiple": true,
"displayMediaPreview": true,
"allowedTypes": ["image"],
"maxSize": 10485760,
"validations": [
{
"rules": [
{ "type": "required", "message": "Please upload supporting files" },
{ "type": "minLength", "value": 2, "message": "Upload at least two files" },
{ "type": "maxLength", "value": 5, "message": "Upload no more than five files" }
]
}
]
}contentRich text content, stored as an array of blocks.
Property | Type | Required | Default | Description |
|---|---|---|---|---|
|
| Yes | — | Field type identifier |
|
| No | All blocks | Allowed block types |
|
| No | All marks | Allowed mark types |
|
| No | — | Placeholder text |
|
| No |
| Show floating toolbar on selection |
|
| No | — | Validation rules |
Block | Description |
|---|---|
| Standard paragraph |
| Heading levels |
| Block quote |
| Numbered list |
| Bulleted list |
| List item |
| Code block |
| Hyperlink |
| Embedded image |
| Embedded video |
| Embedded audio |
Mark | Description |
|---|---|
| Bold text |
| Italic text |
| Underlined text |
| Strikethrough text |
| Inline code |
When creating, patching, JSON-patching, or replacing a Record through the API, a content field's value can be either the block array or a plain markdown string. A markdown string is converted to blocks, so the stored value is always a block array. This applies at any depth inside object and array fields.
required — Content must not be emptyminLength — Minimum character countmaxLength — Maximum character countminBlocks — Minimum block countmaxBlocks — Maximum block countminWords — Minimum word countmaxWords — Maximum word count{
"type": "content",
"name": "Article Body",
"allowedBlocks": [
"paragraph",
"heading1",
"heading2",
"block-quote",
"numbered-list",
"bulleted-list",
"image"
],
"allowedMarks": ["bold", "italic", "code"],
"placeholder": "Write your article here...",
"hoveringToolbar": true,
"validations": [
{
"rules": [
{ "type": "required" },
{
"type": "minWords",
"value": 100,
"message": "Article must be at least 100 words"
}
]
}
]
}geojsonGeographic data stored either as raw GeoJSON or, in map editors, as standard geography references.
Property | Type | Required | Default | Description |
|---|---|---|---|---|
|
| Yes | — | Field type identifier |
|
| No | All types | Allowed geometry types |
|
| No | — | Schema for feature properties |
|
| No |
| Display configuration |
|
| No | — | Validation rules |
Type | Description |
|---|---|
| Single coordinate |
| Line of coordinates |
| Closed polygon |
| Multiple points |
| Multiple lines |
| Multiple polygons |
Inputs Display:
{
"display": "inputs"
}Map Display:
{
"display": "map",
"defaultZoom": 13,
"defaultCenter": {
"latitude": 40.7128,
"longitude": -74.006
}
}required — GeoJSON data must be provided{
"type": "geojson",
"name": "Store Location",
"geometryTypes": ["Point"],
"display": {
"display": "map",
"defaultZoom": 15,
"defaultCenter": {
"latitude": 51.5074,
"longitude": -0.1278
}
},
"validations": [
{
"rules": [{ "type": "required" }]
}
]
}When the map editor is used in geography-reference mode, values are stored as:
{
"mode": "geography-reference",
"rows": [
{
"id": "AU",
"label": "Australia",
"sources": [
{
"type": "reference",
"geographySet": "world-country-ne-v1",
"geographyCode": "AU"
}
],
"properties": {
"displayCount": 10,
"detailLevel": "Continental"
}
}
]
}Row-level property data can be supplied either as additional top-level row keys or inside rows[].properties. Both are merged into the rendered feature's GeoJSON properties object. When using the map editor in geography-reference mode, clicking a selected geography keeps the current viewport and exposes inline label editors for the selected rows.
When shaping geography-reference values, you must choose the correct rows[].sources[].geographySet from the identifier level of your data (for example, country codes vs. subdivision codes). For detailed instructions on data shaping and a complete list of available geography sets, see Visualisation — Geography-Reference Data Shaping.
For one row to one shipped geography unit, the minimal reference-source shape is:
{
"id": "US-CA",
"sources": [
{
"type": "reference",
"geographySet": "world-admin1-north-america-ne-v1",
"geographyCode": "US-CA"
}
]
}objectNested object with its own schema structure.
Property | Type | Required | Default | Description |
|---|---|---|---|---|
|
| Yes | — | Field type identifier |
|
| Yes | — | Nested field definitions |
|
| No | — | Validation rules |
required — Object must have valuesWhen an object field contains conditional required rules, Ligantic evaluates property defaults in dependency order. If a property's required condition references another property, the referenced property's default is applied first, including when that dependency is introduced by nested object fields.
{
"type": "object",
"name": "Address",
"showInTable": false,
"properties": {
"street": {
"type": "string",
"name": "Street",
"display": "text"
},
"city": {
"type": "string",
"name": "City",
"display": "text"
},
"country": {
"type": "string",
"name": "Country",
"display": "select",
"options": ["United States", "United Kingdom", "Canada", "Australia"]
},
"postalCode": {
"type": "string",
"name": "Postal Code",
"display": "text"
}
}
}arrayList of values with a defined item schema.
Property | Type | Required | Default | Description |
|---|---|---|---|---|
|
| Yes | — | Field type identifier |
|
| No |
| Array input display mode |
|
| Yes | — | Schema for array items |
|
| No | — | Validation rules |
Note: In Studio, selecting array
display = "checkboxes"auto-configuresitemsto a stringselectschema and shows the options editor at the array level (the nested item schema editor is hidden in this mode). Ifitemsis not a string schema, Studio shows a warning confirmation before applying this conversion.
Note: In Studio, array validation rule selection supports
required,minLength, andmaxLength, including whendisplay = "checkboxes". UseminLengthto require multiple checkbox selections.
required — Array value must be present (can be empty)minLength — Minimum item countmaxLength — Maximum item count{
"type": "array",
"name": "Tags",
"items": {
"type": "string",
"name": "Tag",
"display": "text"
},
"validations": [
{
"rules": [
{
"type": "minLength",
"value": 1,
"message": "At least one tag required"
},
{
"type": "maxLength",
"value": 10,
"message": "Maximum 10 tags allowed"
}
]
}
]
}{
"type": "array",
"name": "Team Members",
"items": {
"type": "object",
"name": "Member",
"properties": {
"name": {
"type": "string",
"name": "Name",
"display": "text"
},
"role": {
"type": "string",
"name": "Role",
"display": "select",
"options": [
{ "label": "Developer", "value": "developer" },
{ "label": "Designer", "value": "designer" },
{ "label": "Manager", "value": "manager" }
]
},
"email": {
"type": "string",
"name": "Email",
"display": "text"
}
}
}
}Validations are organised into groups. Each group has:
condition (optional): when to apply these rules.rules: the rules to apply.{
"type": "string",
"name": "Company Name",
"validations": [
{
"condition": {
"type": "property",
"path": ["isBusinessAccount"],
"operator": "eq",
"value": { "type": "literal", "value": true }
},
"rules": [
{
"type": "required",
"message": "Company name required for business accounts"
}
]
}
]
}relationshipLinks a Record to one or more Records in another Schema. The field's value is the linked Record ID or IDs.
Property | Type | Required | Default | Description |
|---|---|---|---|---|
|
| Yes | — | Field type identifier |
|
| Yes | — | The Schema ID of the related Records |
|
| Yes | — | Whether the field holds one or many references |
|
| No | Source Schema name | Label shown on the target Record's relationship side |
|
| No | — | Template for rendering related Record labels |
"one": The field value is a single Record ID string (or null if empty)."many": The field value is an array of Record ID strings.targetLabel is trimmed; omitted, empty, whitespace-only, or default-equivalent values are omitted so the cardinality-aware default applies.targetLabel for a field that sends the property is an explicit revert — the relationship's label is reset to the cardinality-aware default, discarding any custom label previously set from the field or the relationship editor. A field that omits targetLabel entirely leaves the existing label untouched.eq, ne, in, isNull, and isNotNull.A relationship field can be declared on either side of the relationship. The direction of the relationship does not depend on which Schema declares the field.
Saving the Schema updates only the target-side label, from targetLabel. It does not change the relationship's direction or the label and settings on the other side.
The Schema editor shows the target-side label currently in use, including changes made in the relationship editor.
targetSchemaId replaces the relationship with a new one. Links to the old target are not carried over.Validation | Type | Description |
|---|---|---|
|
| Record must have at least one link |