Skip to main content
Every object in Twenty ships with a set of system fields that you never declare yourself. They are created automatically by the server when the object is provisioned: id, createdAt, updatedAt, deletedAt, createdBy, updatedBy, position, searchVector Because you don’t declare these fields with defineField(), there’s no universalIdentifier constant for you to import. So how do you reference createdAt as a column in a view?

The problem

Since Twenty 2.19, a system field’s universal identifier is derived deterministically by the server from three inputs: the application universal identifier, the object universal identifier, and the field name. Inventing an id and hardcoding it won’t work: it matches nothing on the server, and the sync rejects the dangling reference:
Dev sync failed: viewField: INVALID_VIEW_DATA: Field metadata not found

The solution

getFieldUniversalIdentifier is available from twenty-sdk 2.21 onward.
Use getFieldUniversalIdentifier to resolve the exact same value the server uses. It takes the three inputs and returns the field’s universal identifier:
import { getFieldUniversalIdentifier } from 'twenty-sdk/define';

const createdAtFieldId = getFieldUniversalIdentifier({
  applicationUniversalIdentifier: APPLICATION_UNIVERSAL_IDENTIFIER,
  objectUniversalIdentifier: MY_OBJECT_UNIVERSAL_IDENTIFIER,
  name: 'createdAt',
});
  • applicationUniversalIdentifier is your app’s identifier, the one you pass to defineApplication().
  • objectUniversalIdentifier is the identifier of the object the field belongs to.
  • name is the system field name, one of the values listed above.

Example: a createdAt column in a view

The typical case is adding a createdAt column to a view of one of your custom objects. Resolve the field id and reference it as any other fieldMetadataUniversalIdentifier:
src/views/example-view.ts
import {
  defineView,
  getFieldUniversalIdentifier,
} from 'twenty-sdk/define';

const APPLICATION_UNIVERSAL_IDENTIFIER =
  '0b04e15c-27b2-4741-9046-b32e07469072';
const MY_OBJECT_UNIVERSAL_IDENTIFIER =
  'c782b61c-70fd-4c88-9cd6-4e61ab8d7591';

export default defineView({
  universalIdentifier: '70f10d44-144a-4da8-8c6f-3ec2422138c0',
  name: 'All records',
  objectUniversalIdentifier: MY_OBJECT_UNIVERSAL_IDENTIFIER,
  icon: 'IconList',
  position: 0,
  fields: [
    {
      universalIdentifier: '75a90bc4-d901-4df4-85e0-af29db5e0104',
      fieldMetadataUniversalIdentifier: getFieldUniversalIdentifier({
        applicationUniversalIdentifier: APPLICATION_UNIVERSAL_IDENTIFIER,
        objectUniversalIdentifier: MY_OBJECT_UNIVERSAL_IDENTIFIER,
        name: 'createdAt',
      }),
      position: 0,
      isVisible: true,
      size: 200,
    },
  ],
});
The same resolved id works anywhere a fieldMetadataUniversalIdentifier is expected: view fields, filters, sorts, groups, and page-layout widgets.
Resolve the id, don’t hardcode it. Because the server derives the value from the application id, the object id and the field name, calling getFieldUniversalIdentifier keeps your reference correct even if those inputs change, and avoids drift if the derivation ever evolves.

Standard Twenty objects

For a standard Twenty object (Person, Company, Opportunity, …), you don’t need to derive anything: the system field identifiers are pre-computed constants you can import directly.
import { STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS } from 'twenty-sdk/define';

// STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.fields.createdAt.universalIdentifier
// STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.person.fields.updatedAt.universalIdentifier
Reach for getFieldUniversalIdentifier when the object is one your app defines with defineObject(), where no such constant exists.
name is a default field, not a system field. It keeps its own hardcoded universal identifier and is not resolved through getFieldUniversalIdentifier. On objects you define, reference the name field by the identifier you gave it in defineObject().