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.