Field Types Reference
Every field type in the FlowOS data model — how values are stored, how to filter by them, and how to write them in workflow expressions.
Scalar Types
stringStringPlain UTF-8 text. Used for names, descriptions, codes, and free-form fields. No length limit unless documented.
Examples: name, title, code, description, resolution
Query: filter[title][ilike]=%outage% — case-insensitive substring match
numberNumber64-bit floating point. Used for counts, durations, costs, scores, and thresholds.
Examples: durationMinutes, score, costAmount, effortHours
Query: filter[durationMinutes][lte]=60 — numeric comparison
booleanBooleantrue or false. Used for flags and toggles.
Examples: isActive, isAutomated, isLocked, mfa_enabled
Query: filter[isActive]=true
dateDate / TimestampISO 8601 UTC timestamp with millisecond precision. Stored as RFC 3339. All dates are UTC — convert to user timezone in the UI.
Examples: createdAt, resolvedAt, dueAt, plannedStartAt
Query: filter[createdAt][gte]=2026-06-01T00:00:00Z
Structured Types
listList (Enum)A field with a fixed set of allowed values defined in the table's field definition. The choices array defines valid values and their display labels.
Examples: status, priority, impact, urgency, environment, recordSource
Query: filter[status]=open OR filter[status][in]=open,investigating
jsonJSON / JSONBArbitrary JSON object or array. Used for configurations, payloads, metadata, and structured data that doesn't need its own table.
Examples: details, configuration, conditions, actions, metadata, payload
Query: filter[metadata.runId][exists]=true — dot-notation for nested keys
referenceReferenceA foreign key pointing to a record in another table. Stored as the target record's ID string. Can be expanded to inline the full record via ?expand=fieldName.
Examples: assignedTo (→ users), groupId (→ groups), ciId (→ cmdb_cis), workflowId (→ workflows)
Query: filter[assignedTo]=usr_01... OR filter[assignedTo.email]=alice@acme.com
multiple: true store an array of IDs. Filter withfilter[field][in]=id1,id2 to match records where any of the IDs is in the array.List Type — Choices Deep Dive
Every list field has a choices array. Standard choices are seeded by the system but can be extended per workspace. The value is what's stored; the label is for display only. One choice may have isDefault: true — it's used when no value is provided on create.
{
"field": "status",
"type": "list",
"choices": [
{ "value": "new", "label": "New", "isDefault": true },
{ "value": "in_progress", "label": "In Progress" },
{ "value": "resolved", "label": "Resolved" },
{ "value": "closed", "label": "Closed" }
]
}The choices table stores workspace-level overrides and additions. You can add custom choices to any list field without changing the schema.
Status Field Patterns
The status field uses one of three standard choice sets depending on the table type. These patterns repeat consistently across all 1,151 tables:
new | in_progress | pending | on_hold | resolved | closed | cancelledtasks, checklists, watchers, communications, risk_registers, security_incidents
draft | ready | running | paused | completed | failed | retiredplaybooks, runbooks, approvals, plans, workflows, jobs, scripts
new | processed | failed | ignoredtimelines, escalations, alerts, notifications, event_links
Reference Type — Expanding & Dot Notation
Reference fields support three query patterns:
# 1. Filter by the referenced record's ID
GET /api/v1/tables/incidents/records?filter[assignedTo]=usr_01...
# 2. Filter by a field on the referenced record (dot notation)
GET /api/v1/tables/incidents/records?filter[assignedTo.email]=alice@acme.com
GET /api/v1/tables/incidents/records?filter[groupId.name]=Platform+Team
# 3. Expand to inline the full referenced record
GET /api/v1/tables/incidents/records?expand=assignedTo,groupIdDot notation traverses up to 3 levels deep: filter[assignedTo.department.name]=Engineering.
JSON Type — Querying Nested Data
JSON fields can be queried using dot notation for nested keys and the [exists] operator:
# Check if a nested key exists
filter[metadata.runId][exists]=true
# Exact match on a nested string value
filter[configuration.region]=us-east-1
# Numeric comparison on nested value
filter[details.retryCount][gte]=3Readonly Fields
Fields marked readonly: true in the schema cannot be set via the API. They are auto-managed by the platform. Attempting to set them in a create or update payload returns a 422 error.
- •
id— ULID assigned at create time. - •
number— Auto-incremented (e.g. INC-0042). Set by sys_counters. - •
tenantId,workspaceId— Set from API token context. - •
createdAt,updatedAt— Auto-managed timestamps. - •
createdBy,updatedBy— Set from the authenticated user. - •
hashedKey— API key hash. Never returned in responses.
Field Validation Rules
| Rule | Behaviour |
|---|---|
| required: true | Field must be present on create. Returns 422 if missing or null. |
| readonly: true | Field is ignored on create/update. Set by the platform. |
| type: list | Value must match one of the defined choices. Returns 422 for unknown values. |
| type: reference | ID must reference an existing record in the target table (same workspace). Returns 422 if not found. |
| multiple: true | Field stores an array. POST an array of values. |
| isDefault: true | Choice used when field is omitted on create. |