Skip to content
Last updated

A Record Type is a sub-category inside an Object. It lets you classify records of the same Object into distinct buckets, each with its own subset of fields, views, and behaviors.

Examples:

  • The People Object might have record types Lead, Vendor, Prospect.
  • The Deals Object might have record types New Business, Renewal, Expansion.

Every Object has at least one record type. One of them is the default and is used when a record is created without specifying a record type.

Record Types belong to Objects, not Tables. Tables do not have categorical subdivisions.

Identity

FieldTypeNotes
idnumberUse as recordTypeId.
namestringInternal identifier within the Object.
display_namestringUser-facing label.
is_defaultbooleanExactly one record type per Object has this set to true.
single_nounstring?Singular noun used in UI copy (e.g."Lead" for the Leads type).
emojistring?Icon-key string from the same allowlist Objects uses (e.g. "repeat", "star", "flag"). Not a Unicode emoji.
icon_colorstring?Color name or hex.
field_idsnumber[]?Subset of the Object's fields to show for records of this type.
viewsarray?Saved views scoped to this record type.

How they interact with fields and views

  • Field membership is record-type-scoped via field_ids. A field on the Object can appear in some record types and not others.
  • Views can be scoped to a record type. Switching record type in the UI swaps the visible columns and the active view.
  • Creating or updating a record can pin it to a specific record type. If you don't, it goes to the default.

Operations

VerbPath
GET/public/v1/objects/{name}/record-types
POST/public/v1/objects/{name}/record-types
PATCH/public/v1/objects/{name}/record-types/{recordTypeId}
DELETE/public/v1/objects/{name}/record-types/{recordTypeId}
POST/public/v1/objects/record-types/{recordTypeId}/views
PATCH/public/v1/objects/record-types/{recordTypeId}/views/{viewId}
DELETE/public/v1/objects/record-types/{recordTypeId}/views/{viewId}

The default record type is protected: you cannot change its name or display_name, and you cannot delete it (both return 400). You can still update its other attributes (assigned columnIds, emoji, color) while it is default.

Who can change record types

POST, PATCH, and DELETE require a USER API key with ADMIN or OWNER role; any other role gets a 403. GET is available to any user who can see the Object. Record types shape the account's CRM model, so they are deliberately not delegated through resource sharing the way Table schemas are.

Because record types are an Object-only feature, these endpoints reject Tables: passing a Table name returns 404 with a pointer to the /tables endpoints.

CLI

frontline object record-type list contacts
frontline object record-type create contacts --data '{"name":"vendor","displayName":"Vendor","fieldIds":[73],"emoji":"tag"}'
frontline object record-type update contacts <id> --data '{"displayName":"Vendor","fieldIds":[73,74]}'
frontline object record-type delete contacts <id>

On create/update, columnIds, fieldIds, and field_ids are equivalent (assign fields to the record type). Aliases display_name, singleNoun, and singular_noun are also accepted.

Record-level security (RLS)

Record-level security (RLS; some legacy references say "FLS") controls who can see and edit individual records within a record type. It is configured per record type, not per object.

When enabled, access is determined by virtual owner columns: User-relation fields on the record type (e.g. a Users column). Users listed in those fields become the virtual owners of the record and gain edit access according to workspace defaults.

This is separate from record sharing (per-record grants to specific users/teams) and from resource sharing (who can access the object schema itself). See the sharing CLI skill for those.

Enabling RLS

When RLS is enabled for the first time on a record type:

  • If workspace default is FULL_ACCESS, it is set to NO_ACCESS automatically.
  • Existing rows without _grants are backfilled to private so list/get/update enforcement applies immediately.

API enforcement (list / get / update)

RLS stateNon-owner USER
OFFNormal record-type permissions; all rows visible
ON + workspace NO_ACCESSOnly own rows (manual/virtual owner) or explicit grants
ON + workspace FULL_ACCESSOpen rows readable/editable by the whole account

Response fields: _recordAccess (record-type CRUD) vs _recordShareAccess (per-record RLS level).

Non-owners cannot get list/read access except via virtual-owner columns, per-record _grants, or an open workspace default. There is no separate ACL grant API on the record type.

Operations

VerbPath
GET/public/v1/objects/{name}/record-types/{recordTypeId}/security
PATCH/public/v1/objects/{name}/record-types/{recordTypeId}/security

Both endpoints require a USER API key with ADMIN or OWNER role.

Response shape

{
    "ok": true,
    "data": {
        "enabled": false,
        "workspace": "FULL_ACCESS",
        "virtual_owner_column_ids": [42],
        "virtual_owner_columns": [{ "id": 42, "name": "Users", "key": "users" }]
    }
}

Request body (PATCH)

All fields are optional (partial update). Unknown keys return 400.

{
    "enabled": true,
    "virtual_owner_column_ids": [42, 55],
    "workspace": "READ_ONLY"
}

Aliases virtualOwnerColumnIds, default_workspace_record_permission, and defaultWorkspaceRecordPermission are also accepted for their respective fields.

workspace values: FULL_ACCESS | READ_ONLY | NO_ACCESS — default access for new records when RLS is enabled.

virtual_owner_column_ids must reference User-relation fields that belong to the record type. Invalid column IDs return 400.

Lazy defaults

If no config has been saved yet, GET returns in-memory defaults (enabled: false, auto-detected Users column if present) without writing to the database. RLS enforcement only activates after an admin saves the config via PATCH.

CLI

frontline object record-type security get people 3
frontline object record-type security update people 3 --data '{"enabled":true,"virtual_owner_column_ids":[42],"workspace":"READ_ONLY"}'

Get field IDs from frontline object get <object> or frontline object field list <object>.