
## Company fields

`GET /v1/companies/fields`

Returns the full list of available fields, including user fields (`ufCrm*`).

## Examples

### curl — personal key

```bash
curl "https://vibecode.bitrix24.com/v1/companies/fields" \
  -H "X-Api-Key: YOUR_API_KEY"
```

### curl — OAuth application

```bash
curl "https://vibecode.bitrix24.com/v1/companies/fields" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN"
```

### JavaScript — personal key

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/companies/fields', {
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
  },
})

const { success, data } = await res.json()
```

### JavaScript — OAuth application

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/companies/fields', {
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
  },
})

const { success, data } = await res.json()
```

## Response fields

The `label` and `description` field captions are returned in English, while the ones the platform takes straight from the Bitrix24 account come in the account language. Request headers do not switch the language.

| Field | Type | Description |
|------|-----|---------|
| `success` | boolean | Always `true` on success |
| `data` | object | The company field schema and the operations available for companies. Its keys are in the rows below |
| `data.fields` | object | The company field schema: field name → an object with `type`, `readonly` and `label`. Some fields also carry `description` and extra attributes such as `nullable`, `multiple` and `items`. The standard fields are listed below, and the `ufCrm*` user fields of this Bitrix24 account are added to them |
| `data.relations` | object | The `contact` relation covers all contacts linked to the company and the operations on them. See [Company contacts](/docs/entities/companies/contacts) |
| `data.activities` | object | Company activities: the `list` and `create` operations and the `call`, `meeting`, `email` and `task` activity types. See [Activities of a CRM record](/docs/entities/activities/owner-list) and [Create an activity for a CRM record](/docs/entities/activities/owner-create) |
| `data.aggregatable` | array | Standard fields allowed in the aggregation `groupBy`: `typeId`, `industry`, `revenue`, `assignedById`, `currencyId` |
| `data.batch` | array | Company write operations available in [batch calls](/docs/batch): `create`, `update`, `delete` |
| `data.import` | object | Method, path and maximum batch size for [importing records](/docs/import) |
| `data.include` | array | The names the `include` parameter accepts: `contact`. See [Related data](/docs/includes) |

### Standard company fields

| Field | Type | RO | Description |
|------|-----|:--:|---------|
| `id` | number | yes | Company ID |
| `title` | string | | Name |
| `typeId` | string | | Company type: `CUSTOMER`, `SUPPLIER`, `COMPETITOR`. Values list: `GET /v1/statuses?filter[entityId]=COMPANY_TYPE` |
| `industry` | string | | Industry. List: `GET /v1/statuses?filter[entityId]=INDUSTRY` |
| `revenue` | number | | Annual revenue |
| `currencyId` | string | | Currency. List: `GET /v1/currencies` |
| `phone` | multifield | | Phone. On input (POST/PATCH) accepts `string \| string[] \| object[]`. On output, `phone` is a string with the primary value. Per-type values are in `phoneWork`/`phoneMobile`, and the full list with types is in the `fm[]` array (format `{ id, typeId, valueType, value }`). **Important:** PATCH **only adds** new records — existing `phone` entries are not removed. See [Update company](/docs/entities/companies/update). The UPPER form `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` is **not accepted** — it returns `400 INVALID_MULTIFIELD_SHAPE`. Use camelCase: `[{ "value": "...", "typeId": "WORK" }]`. An object with an `id` field is not accepted by any write operation — `400 MULTIFIELD_ID_NOT_SUPPORTED`, and nothing is written. The same applies to a row with `id` inside the raw `fm[]` array. An object keyed by row ids (`{"11": {…}}`) is not accepted either — same code. An object without `value` — empty or with keys such as `n0`, `0` or `011` — and a number or `true`/`false`, on their own or as an array item, are refused with `400 INVALID_MULTIFIELD_SHAPE`. |
| `email` | multifield | | Email. On input accepts `string \| string[] \| object[]`. On output, `email` is a string with the primary value. Per-type values are in `emailWork`/`emailHome`/`emailMailing`, and the full list is in the `fm[]` array. **Important:** PATCH **only adds** new records — existing `email` entries are not removed. The UPPER form `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` is **not accepted** — it returns `400 INVALID_MULTIFIELD_SHAPE`. Use camelCase: `[{ "value": "...", "typeId": "WORK" }]`. An object with an `id` field is not accepted by any write operation — `400 MULTIFIELD_ID_NOT_SUPPORTED`, and nothing is written. The same applies to a row with `id` inside the raw `fm[]` array. An object keyed by row ids (`{"11": {…}}`) is not accepted either — same code. An object without `value` — empty or with keys such as `n0`, `0` or `011` — and a number or `true`/`false`, on their own or as an array item, are refused with `400 INVALID_MULTIFIELD_SHAPE`. |
| `web` | multifield | | Website. On input accepts `string \| string[] \| object[]`. On output, `web` is a string with the primary value. Per-type values are in `webWork`, and the full list is in the `fm[]` array. **Important:** PATCH **only adds** new records — existing `web` entries are not removed. The UPPER form `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` is **not accepted** — it returns `400 INVALID_MULTIFIELD_SHAPE`. Use camelCase: `[{ "value": "...", "typeId": "WORK" }]`. An object with an `id` field is not accepted by any write operation — `400 MULTIFIELD_ID_NOT_SUPPORTED`, and nothing is written. The same applies to a row with `id` inside the raw `fm[]` array. An object keyed by row ids (`{"11": {…}}`) is not accepted either — same code. An object without `value` — empty or with keys such as `n0`, `0` or `011` — and a number or `true`/`false`, on their own or as an array item, are refused with `400 INVALID_MULTIFIELD_SHAPE`. |
| `hasPhone` | boolean | yes | Whether a phone is set |
| `hasEmail` | boolean | yes | Whether an email is set |
| `hasImol` | boolean | yes | Whether there is an Open Channel contact |
| `comments` | string | | Comment |
| `assignedById` | number | | Responsible person. List: `GET /v1/users` |
| `createdBy` | number | yes | Creator. Lookup: `GET /v1/users` |
| `updatedBy` | number | yes | Modified by. Lookup: `GET /v1/users` |
| `createdTime` | datetime | yes | Creation date |
| `updatedTime` | datetime | yes | Modification date |
| `opened` | boolean | | Available to everyone |
| `leadId` | number | | ID of the source lead |
| `entityTypeId` | number | yes | CRM entity type ID. For a company the value is always `4` |
| `emailWork` | string \| null | yes | Work e-mail from the `email` multifield. Written through `email` |
| `emailHome` | string \| null | yes | Personal e-mail from the `email` multifield. Written through `email` |
| `emailMailing` | string \| null | yes | Mailing e-mail from the `email` multifield. Written through `email` |
| `phoneWork` | string \| null | yes | Work phone from the `phone` multifield. Written through `phone` |
| `phoneMobile` | string \| null | yes | Mobile phone from the `phone` multifield. Written through `phone` |
| `phoneMailing` | string \| null | yes | Mailing phone from the `phone` multifield. Written through `phone` |
| `imol` | string \| null | yes | Open Channel contact from the multifield collection |
| `address` | string \| null | yes | Physical address as a single line. Edited in the company requisites |
| `addressLegal` | string \| null | yes | Legal address as a single line. Edited in the company requisites |
| `searchContent` | string \| null | yes | **Service field.** A string Bitrix24 assembles from the card text for its own full-text search. Filtering by this field returns `400 UNKNOWN_FILTER_FIELD`. For text search, filter `title` with `$contains`. Its contents can change without notice. Do not show it to users either |

The eleven fields above arrive in `list`/`get` data but cannot be written directly: Bitrix24 returns a success response but does not store the value, so the platform refuses them with `400 READONLY_FIELD`. Addresses are edited in the company requisites, and phone numbers and e-mail addresses are written through the `phone` and `email` multifields.

**User fields** (`ufCrm*`) are also returned and accepted. The set of such fields differs per Bitrix24 account, so they are not part of the static schema — their descriptions come from Bitrix24. For an `enumeration` field, this endpoint returns an array of options at `data.fields.<field name>.items`, shaped as `{ "ID": "3995", "VALUE": "warm" }`. To write to a user field, send the `ID`, while `VALUE` is the option label for display. A label sent instead of the identifier is lost without an error. For details, see [Value format by type](/docs/entity-api#value-format-by-type).

## Response example

```json
{
  "success": true,
  "data": {
    "fields": {
      "id": { "type": "number", "readonly": true, "label": "ID", "description": "Company identifier." },
      "title": { "type": "string", "readonly": false, "label": "Name", "description": "Company name." },
      "assignedById": { "type": "number", "readonly": false, "label": "Responsible person", "description": "User responsible for the company." }
    },
    "relations": {
      "contact": { "type": "many", "entity": "contacts", "operations": ["list", "add", "remove", "set", "clear"] }
    },
    "activities": { "operations": ["list", "create"], "types": ["call", "meeting", "email", "task"] },
    "aggregatable": ["typeId", "industry", "revenue", "assignedById", "currencyId"],
    "batch": ["create", "update", "delete"],
    "import": { "method": "POST", "path": "/v1/companies/import", "maxItems": 100 },
    "include": ["contact"]
  }
}
```

Three fields from `data.fields` are shown, along with the other `data` keys. The full set of fields is in the tables above.

## Error response example

403 — the key lacks the `crm` scope:

```json
{
  "success": false,
  "error": {
    "code": "SCOPE_DENIED",
    "message": "This endpoint requires 'crm' scope",
    "hint": "This request needs the 'crm' scope, which the calling key does not carry. Add 'crm' to this key in the developer cabinet (or through the management API), then repeat the call.",
    "cause": "key_scope_missing",
    "requiredScope": "crm",
    "keyScopes": ["task", "im"],
    "fix": { "action": "edit_key_scopes", "via": "cabinet" },
    "userMessage": "The app's API key lacks the “CRM” permission. You can add it in the key settings in the developer cabinet."
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|---------|
| 403 | `SCOPE_DENIED` | The API key does not have the `crm` scope |
| 401 | `TOKEN_MISSING` | The API key has no configured tokens |
| 429 | `RATE_LIMITED` | Rate limit exceeded: 300 requests per minute per portal. All API keys of the portal share one limit. The current limit is returned in the `x-ratelimit-limit` header. Retry after the delay in the `Retry-After` header |

For the full list of common API errors, see [Errors](/docs/errors).

## See also

- [Create company](/docs/entities/companies/create)
- [User fields](/docs/userfields)
- [Entity API](/docs/entity-api)
- [Limits and optimization](/docs/optimization)
