---
title: "Discovering entity fields (*.field.list)"
description: "Ask the portal which fields an entity has, what type each one is, and whether it can be filtered, sorted or written — instead of guessing them or downloading the whole OpenAPI document. Also states the v3 camelCase field-name rule."
canonical_url: "https://bitrix24.github.io/b24jssdk/docs/working-with-the-rest-api/discovering-entity-fields"
last_updated: "2026-09-14"
---
# Discovering entity fields (*.field.list)

> Ask the portal which fields an entity has, what type each one is, and whether it can be filtered, sorted or written — instead of guessing them or downloading the whole OpenAPI document. Also states the v3 camelCase field-name rule.

## Overview

Most `restApi:v3` entities publish a pair of metadata methods:

- `<entity>.field.list` — every field the entity has, as a list of descriptors;
- `<entity>.field.get` — one field, by `name`.

This is a large part of the v3 surface: **91 of the 245 methods** a measured cloud portal
publishes belong to this family — 37%. Every module has it: `rest` 22, `main` 18, `note` 10,
`bizprocdesigner` 9, `humanresources` 8, `tasks` 8, `mail` 6, `vibecodeconnector` 6,
`call` 2, `timeman` 2.

> [!NOTE]
> [Discovering v3 methods](https://bitrix24.github.io/b24jssdk/raw/docs/working-with-the-rest-api/discovering-v3-methods.md) answers
> **which methods exist** on a portal, with one document you fetch once and cache.
> This page answers **which fields this one entity has** — a small, cheap call you can make
> per entity, which also carries per-field flags the OpenAPI document does not.

## Calling it through the SDK

An ordinary v3 call — no special helper:

```ts
const response = await $b24.actions.v3.call.make<{
  items: Array<{ name: string, type: string, sortable: boolean, filterable: boolean }>
}>({ method: 'tasks.task.field.list' })

const fields = response.getData()?.result?.items ?? []
const sortable = fields.filter(field => field.sortable).map(field => field.name)
```

The rows arrive under **`result.items`**. `<entity>.field.get` answers with a single
descriptor under **`result.item`** instead:

```ts
const response = await $b24.actions.v3.call.make<{
  item: { name: string, type: string, sortable: boolean }
}>({ method: 'tasks.task.field.get', params: { name: 'title' } })
```

Both accept an optional `select`, which narrows the **descriptor** keys — pass
`select: ['name', 'sortable']` and each row comes back with those two keys only.

## What a descriptor holds

| Key | What it means |
| --- | --- |
| `name` | The field name to use in `select`, `filter` and `order`. |
| `type` | `string`{className="language-ts-type shiki shiki-themes material-theme-lighter material-theme material-theme-palenight" language="ts-type" style=""}, `integer`{className="language-ts-type shiki shiki-themes material-theme-lighter material-theme material-theme-palenight" language="ts-type" style=""}, `datetime`{className="language-ts-type shiki shiki-themes material-theme-lighter material-theme material-theme-palenight" language="ts-type" style=""}, … |
| `title` / `description` | Human-readable labels. `description`{className="language-ts-type shiki shiki-themes material-theme-lighter material-theme material-theme-palenight" language="ts-type" style=""} is often `null`{className="language-ts-type shiki shiki-themes material-theme-lighter material-theme material-theme-palenight" language="ts-type" style=""}. |
| `filterable` | Whether the field may appear in `filter` — **and in an aggregate `select`**; see below. |
| `sortable` | Whether it may appear in `order`. |
| `editable` | Whether it may be written. |
| `requiredGroups` | The operations the field is mandatory for, e.g. `['add']`{className="language-ts-type shiki shiki-themes material-theme-lighter material-theme material-theme-palenight" language="ts-type" style=""}. |
| `multiple` / `elementType` | Whether the value is a list, and of what. |
| `validationRules` | Portal-side constraints, when the field declares any. |

**Three of these have no other source.** `filterable`, `editable` and `requiredGroups`
appear nowhere in the OpenAPI document's request schema, so *"can I filter on this?"* and
*"what must I pass to `add`?"* are answerable here and nowhere else.

> [!WARNING]
> **`sortable` and `filterable` are independent — do not infer one from the other.** They
> happen to name the same five fields on `main.eventlog` (`id`, `timestampX`, `auditTypeId`,
> `userId`, `guestId` of thirteen), which makes the coincidence look like a rule. It is not:
> on `tasks.task`, `title` is `sortable: true` and `filterable: false`, and exactly one field
> of ninety-five — `id` — is filterable at all, against nineteen that are sortable. A rich
> `order` alongside a bare `filter` is a normal state for a v3 entity, not a portal fault.
> Under `restApi:v2` the same entity filters on `RESPONSIBLE_ID`, `STATUS` and `GROUP_ID`
> happily; that is a difference between the two APIs, not something to work around.

> [!NOTE]
> **`filterable` also gates aggregation, which the flag's name does not suggest.**
> A field that is selectable and comes back from `list` quite normally is still
> refused by an aggregate `select` unless it is filterable — the portal checks the
> same attribute for both. Measured: the refusal is a **soft** failure
> (`isSuccess`{className="language-ts-type shiki shiki-themes material-theme-lighter material-theme material-theme-palenight" language="ts-type" style=""} `false`{className="language-ts-type shiki shiki-themes material-theme-lighter material-theme material-theme-palenight" language="ts-type" style=""}, not a throw — a 4xx in the
> `restApi:v3` envelope), carrying
> `BITRIX_REST_V3_EXCEPTION_VALIDATION_REQUESTVALIDATIONEXCEPTION` and naming the
> field in `validation[].field`{className="language-ts-type shiki shiki-themes material-theme-lighter material-theme material-theme-palenight" language="ts-type" style=""}. Match on the code and the field:
> the message is localised. Given the ratio above, this is a real constraint on
> what you can ask a v3 entity to count —
> see [Choosing the right method](https://bitrix24.github.io/b24jssdk/raw/docs/working-with-the-rest-api/choosing-the-right-method.md).

`requiredGroups` is `null`{className="language-ts-type shiki shiki-themes material-theme-lighter material-theme material-theme-palenight" language="ts-type" style=""} rather than an empty array when a field is
required by nothing — guard before iterating it.

> [!NOTE]
> **The flag is the source of truth, and the set moves.** Which fields an entity marks
> `filterable` or `sortable` is decided by the Bitrix24 module that owns the entity, and it
> changes from one module version to the next. The reference documentation states the current
> answer per method — `tasks.task.list` on `restApi:v3`, for instance,
> [documents `id` as the only supported filter](https://apidocs.bitrix24.com/api-reference/tasks/tasks-task-list-rest-v3.html){rel="[\"nofollow\"]"}
> — but the portal in front of you is the one that answers your request. Read the flag rather
> than assume, especially in code that has to keep working across portal upgrades.

## Why it is worth the call

A v3 field that is not marked `Filterable` or `Sortable` is refused — the portal does not
quietly ignore the clause. Both refusals were measured, on two entities. Both arrive
**soft**: a 4xx in the `restApi:v3` envelope is not thrown, so check
`isSuccess`{className="language-ts-type shiki shiki-themes material-theme-lighter material-theme material-theme-palenight" language="ts-type" style=""} rather than writing a `try`/`catch` around these.

```ts
// `title` has `filterable: false` — this answers HTTP 400
await $b24.actions.v3.call.make({
  method: 'tasks.task.list',
  params: { filter: [['title', '=', 'x']], select: ['id'] }
})
```

```json
{
  "error": {
    "code": "BITRIX_REST_V3_EXCEPTION_VALIDATION_REQUESTVALIDATIONEXCEPTION",
    "validation": [{ "field": "title", "message": "…requires the `Filterable` attribute…" }]
  }
}
```

Ordering by a field with `sortable: false` answers the same way, naming `Sortable` — measured
on `main.eventlog.list` ordered by `description`, one of the thirteen fields that method
returns:

```json
{
  "error": {
    "code": "BITRIX_REST_V3_EXCEPTION_VALIDATION_REQUESTVALIDATIONEXCEPTION",
    "validation": [{ "field": "description", "message": "…`EventLogDto`…`Sortable`…" }]
  }
}
```

A field being **returned** says nothing about whether it may be filtered or sorted on.

> [!WARNING]
> The `message` is **localised** — a portal answers in the portal's language. Match on
> `error.code` and on `validation[].field`, never on the text.

The useful habit is therefore: **read the fields, then build the request**.

```ts
const meta = await $b24.actions.v3.call.make<{
  items: Array<{ name: string, filterable: boolean, sortable: boolean }>
}>({ method: 'tasks.task.field.list', params: { select: ['name', 'filterable', 'sortable'] } })

const fields = meta.getData()?.result?.items ?? []
const canFilterOn = new Set(fields.filter(field => field.filterable).map(field => field.name))

// On the portal measured, `tasks.task` exposes exactly one filterable field: `id`.
if (canFilterOn.has('deadline')) {
  // …only then send a filter on `deadline`
}
```

## Field names

**`restApi:v3` field names are camelCase.** Measured across two entities and 108
descriptors — `tasks.task` (95) and `main.eventlog` (13) — not one of the 108 starts with an
uppercase letter: `id`, `title`, `creatorId`, `responsibleId`, `startPlan`, `storyPoints`,
`timestampX`, `auditTypeId`.

`restApi:v2` is the opposite: `ID`, `TITLE`, `RESPONSIBLE_ID`.

That is the whole reason for the SDK's paging defaults, and it is a rule rather than a
per-method quirk:

| | Default `idKey` |
| --- | --- |
| `actions.v3.callList` / `fetchList` | `'id'`{className="language-ts-type shiki shiki-themes material-theme-lighter material-theme material-theme-palenight" language="ts-type" style=""} |
| `actions.v2.callList` / `fetchList` | `'ID'`{className="language-ts-type shiki shiki-themes material-theme-lighter material-theme material-theme-palenight" language="ts-type" style=""} |

`cursorIdKey` exists for the methods that spell the id **differently in the request and in
the response**. Under `restApi:v2`, `tasks.task.list` is the known case: it returns a
lowercase `id` but filters on an uppercase `ID`, so a walk left on the defaults reads the
cursor from a field that is not there, never advances, and repeats the first page for ever.

```ts
// restApi:v2 `tasks.task.list` — without `cursorIdKey` the walk never ends
const response = await $b24.actions.v2.callList.make({
  method: 'tasks.task.list',
  params: { select: ['ID', 'TITLE'] },
  idKey: 'id',
  cursorIdKey: 'ID',
  customKeyForResult: 'tasks'
})
```

Under `restApi:v3` the same method needs no override — request and response agree on `id`.

> [!TIP]
> When a walk returns rows but the same ones over and over, this is the first thing to check.
> Ask `<entity>.field.list` what the response calls its id.

## Availability

Near-universal, not universal. On the cloud portal measured, **seven** entities publish a
`.list` with no matching `.field.list` — the four `crm.*.timeline.activity.email` families,
`humanresources.access.permission`, `humanresources.node.communication` and `rest.scope`.
Treat a missing metadata method as ordinary: check `isSuccess` and fall back to the OpenAPI
document or to documented field names.

The counts here are **portal-specific**, like the rest of the v3 surface — the portals
measured published 147, 220 and 245 methods in total. Read them as an order of magnitude,
not a contract.

## Alternatives and Recommendations

- **One entity's fields, with flags** — `<entity>.field.list`. Small, cheap, per entity,
and the only source of `filterable` / `editable` / `requiredGroups`.
- **The whole method surface** —
[`rest.documentation.openapi`](https://bitrix24.github.io/b24jssdk/raw/docs/working-with-the-rest-api/discovering-v3-methods.md).
One document, often 100 KB or more; fetch it once and cache it.
- **Neither** — for `restApi:v2`, the classic `crm.item.fields` / `*.fields` methods still
apply; this family is v3.

## Sitemap

See the full [sitemap](/b24jssdk/sitemap.md) for all pages.
