Custom fields On this page

Working with Orbit

Custom fields

Extend contacts with typed, discoverable attributes.

Definitions and values

A custom field adds a structured attribute without changing the contact schema. Definitions live in field_definitions; values live in each record's JSONB custom_fields object. Definitions are workspace-specific and apply to contacts, organisations, projects, and tasks. Use fields_list with an optional entity filter to discover the appropriate definitions.

An administrator registers a key and its meaning once. Agents discover it with fields_list, then populate it. Unknown keys and values with the wrong type are rejected. Agents cannot create or change definitions.

Register a field

Run with your application's PHP 8.5 binary:

php artisan orbit:field:define WORKSPACE_UUID preferred_contact_method text \
  --description="How this person prefers to be contacted" --no-interaction

Keys use lowercase letters, digits, and underscores, begin with a letter, and have a maximum length of 64. Supply a description of up to 1,000 characters. --entity=contact is the default. Use --entity=organisation, --entity=project, or --entity=task for other records. The same key can have different definitions on different entity types.

Running the identical command again is safe. Existing definitions cannot be retyped or repurposed; register a new key for a different meaning. Administrator registration is audited without attributing it to an agent.

Supported types

Type Accepted values
text A string of up to 2,048 characters.
number A JSON number, not a numeric string.
boolean JSON true or false, not text or integers.
date A valid YYYY-MM-DD date.
datetime ISO-style date/time with seconds and an explicit Z or offset.
string_list Up to 20 strings, each up to 255 characters.

Each record supports at most 30 populated keys and 16 KiB of custom-field JSON. Null is not a valid field value or a deletion shortcut.

Patch values explicitly

After registering preferred_contact_method, call contacts_update:

{
  "id": "01900000-0000-7000-8000-000000000001",
  "expected_revision": 1,
  "idempotency_key": "contact-preference-001",
  "changes": {"custom_fields": {"preferred_contact_method": "email"}}
}

Only supplied custom-field keys change. Other custom fields remain intact. An empty object does not clear them. To remove a value, use remove_custom_fields on contacts_update:

{
  "id": "01900000-0000-7000-8000-000000000001",
  "expected_revision": 2,
  "idempotency_key": "contact-preference-remove-001",
  "remove_custom_fields": ["preferred_contact_method"]
}

A key cannot be set and removed in one request. All keys must be registered, including explicit removals. Removing a value preserves the definition.

Filter contacts

{"custom_fields": {"preferred_contact_method": "email"}}

Pass this to contacts_search, organisations_search, projects_search, or tasks_search, using a definition registered for that entity. Filters use typed equality and all supplied filters must match. Date/time custom values retain their supplied offset; equality compares the stored representation, not equivalent instants in different offsets. Missing values do not match. Only scalar fields support equality filters; string-list matching, nested queries, arbitrary query operators, and custom aggregations are deferred.

Orbit by
Your relationships, kept in view.

Search guides, concepts, and tool reference.

Explore the docs