Schema Design

Naming Conventions

Thing Convention Examples
Entity keys snake_case, plural tasks, contacts, inventory_items
Entity names Title Case, plural "Tasks", "Contacts", "Inventory Items"
Field keys snake_case due_date, is_complete, contact_email
Field names Title Case "Due Date", "Completed", "Contact Email"

Best Practices

Use select over text for constrained values

If a field has a known set of valid values (status, priority, category), use select rather than text. This ensures data consistency and enables efficient filtering.

1✓  status: select ["open", "in_progress", "done"]2✗  status: text (free-form — "Open", "In Progress", "DONE" are all different)

Use multi_select for tags

When a record can belong to multiple categories simultaneously, use multi_select:

1tags: multi_select ["frontend", "backend", "design", "devops"]

Mark truly required fields

Only mark a field as required if the record is meaningless without it. Overly strict required fields frustrate users and complicate imports.

Use relation for cross-entity references

When a record in one entity refers to a record in another entity in the same app, use type: relation rather than a plain text field. The stored value is the target record's ULID. Configure related_entity to point at the target entity's key, and optionally display_field to specify which field on that entity to show as a label.

1✓  project_id: relation → related_entity: "projects", display_field: "name"2✗  project_id: text (free-form string — no referential integrity or validation)

Example use case: a "tasks" entity has a project_id relation field pointing to the "projects" entity. Each task record stores the ULID of its parent project. To load the referenced project's data, call sdk.getRecord('projects', record.project_id).

WorkApps validates that the referenced record exists (and is not deleted) when creating or updating a record. Changing a relation field's related_entity target is a breaking schema change and requires a new app version.

Keep entities focused

One entity per concept. Don't combine "tasks" and "comments" into one entity — make two entities and use a relation field in the comments entity to point back to the task.

Set a display_field

Every entity should have a designated display_field — the field shown in lists and referenced in the WorkApps dashboard. Usually this is the main name or title field.

display_field is configured in the WorkApps dashboard when editing an entity: open the Schema Builder, select the entity, and use the Display Field dropdown to choose which field is shown in lists and linked records.

Example Schemas

Task Tracker

Field Key Type Required Notes
Title title text Yes display_field
Description description textarea No
Status status select Yes open, in_progress, done
Priority priority select No low, medium, high, critical
Due Date due_date date No
Assignee Email assignee_email email No

Contact Directory

Field Key Type Required
Name name text Yes
Email email email Yes
Company company text No
Role role text No
Website website url No
Tags tags multi_select No
Notes notes textarea No

Inventory

Field Key Type Required Notes
Name name text Yes display_field
SKU sku text Yes
Category category select Yes
Quantity quantity number Yes min: 0
Unit Price unit_price number No
Low Stock is_low_stock boolean No
Last Restocked last_restocked date No