
## Поля счёта

`GET /v1/invoices/fields`

Возвращает описание всех полей счёта, включая пользовательские (`ufCrm_*`).

## Примеры

### curl — личный ключ

```bash
curl -X GET https://vibecode.bitrix24.tech/v1/invoices/fields \
  -H "X-Api-Key: YOUR_API_KEY"
```

### curl — OAuth-приложение

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

### JavaScript — личный ключ

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

const { success, data } = await res.json()
console.log('Полей:', Object.keys(data.fields).length)
```

### JavaScript — OAuth-приложение

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

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

## Поля ответа

Подписи полей `label` и `description` приходят на русском языке, а те, что платформа берёт напрямую с портала, — на языке портала. Заголовками запроса язык не переключается.

| Поле | Тип | Описание |
|------|-----|---------|
| `success` | boolean | Всегда `true` при успехе |
| `data.fields` | object | Схема полей счёта: имя поля → `type`, `readonly`, `label`, `description`. Стандартные поля перечислены ниже, к ним добавляются пользовательские `ufCrm_*` этого портала |
| `data.relations` | object | Связанные сущности с признаком `includable` — `contact` и `company` |
| `data.products` | object | Операции над товарными позициями и схема их полей. Подробнее — [Поля товаров](/docs/entities/invoices/products-fields) |
| `data.aggregatable` | array | Стандартные поля, допустимые в `groupBy` агрегации: `opportunity`, `stageId`, `assignedById` |
| `data.batch` | array | Операции счёта, доступные в [`POST /v1/batch`](/docs/batch): `create`, `update`, `delete` |
| `data.import` | object | Метод, путь и потолок пакета для [импорта записей](/docs/import) |
| `data.include` | array | Имена, которые принимает параметр `include` |

### Стандартные поля счёта

| Поле | Тип | Только чтение | Описание |
|------|-----|:---:|---------|
| `id` | number | да | ID счёта |
| `title` | string | | Название счёта |
| `stageId` | string | | Стадия. Формат: `DT31_{categoryId}:{stage}`. Список стадий: `GET /v1/statuses?filter[entityId]=SMART_INVOICE_STAGE_{categoryId}` — categoryId зависит от портала. Узнать: `GET /v1/invoices?limit=1&select=categoryId` или запросить у администратора |
| `categoryId` | number | | ID воронки |
| `assignedById` | number | | Ответственный. Список: `GET /v1/users` |
| `contactId` | number | | ID контакта-плательщика. Поиск: `GET /v1/contacts` |
| `companyId` | number | | ID компании-плательщика. Поиск: `GET /v1/companies` |
| `mycompanyId` | number | | ID своей компании-продавца, выставляющей счёт. Поиск: `GET /v1/companies` |
| `opportunity` | number | | Итоговая сумма счёта |
| `currencyId` | string | | Валюта. Список: `GET /v1/currencies` |
| `taxValue` | double | | Сумма налога |
| `begindate` | datetime | | Дата начала счёта |
| `closedate` | datetime | | Дата закрытия счёта |
| `accountNumber` | string | | Печатный номер счёта |
| `comments` | string | | Произвольный комментарий |
| `sourceId` | string | | Источник. Список: `GET /v1/statuses?filter[entityId]=SOURCE` |
| `sourceDescription` | string | | Произвольное описание источника |
| `xmlId` | string | | Внешний идентификатор для сопоставления при интеграции |
| `opened` | boolean | | Доступен ли счёт всем сотрудникам, а не только ответственному |
| `isManualOpportunity` | boolean | | Ручной режим суммы |
| `isRecurring` | boolean | | Счёт-шаблон повторяющегося счёта |
| `observers` | user | | Наблюдатели. Список: `GET /v1/users` |
| `contactIds` | crm_contact | | Контакты счёта. Поиск: `GET /v1/contacts` |
| `contacts` | crm_contact | | Контакты счёта в развёрнутом виде |
| `locationId` | location | | Местоположение |
| `webformId` | crm_webform | | CRM-форма, которой создан счёт |
| `parentId2` | crm_entity | | Связанная сделка. Поиск: `GET /v1/deals` |
| `parentId7` | crm_entity | | Связанное предложение. Поиск: `GET /v1/quotes` |
| `createdBy` | number | да | ID создателя |
| `createdTime` | datetime | да | Дата создания |
| `updatedBy` | number | да | ID сотрудника, изменившего счёт последним |
| `updatedTime` | datetime | да | Дата изменения |
| `movedBy` | number | да | ID сотрудника, последним сменившего стадию |
| `movedTime` | datetime | да | Дата последней смены стадии |
| `previousStageId` | string | да | Стадия до текущей |
| `lastActivityBy` | user | | Автор последней активности в таймлайне |
| `lastActivityTime` | datetime | | Дата последней активности |
| `lastCommunicationTime` | datetime | да | Дата последней коммуникации любого канала |
| `lastCommunicationCallTime` | datetime | да | Дата последнего звонка |
| `lastCommunicationEmailTime` | datetime | да | Дата последнего письма |
| `lastCommunicationImolTime` | datetime | да | Дата последней коммуникации в открытой линии |
| `lastCommunicationWebformTime` | datetime | да | Дата последней коммуникации через веб-форму |

Пользовательские поля (`ufCrm_*`) возвращаются в ответе наравне со стандартными и доступны для записи. Их состав и количество зависят от портала, поэтому в таблице их нет — читайте живой ответ.

**Не всякое поле из таблицы принимается в `filter` и `order`.** Восемь полей — `taxValue`, `observers`, `contactIds`, `contacts`, `locationId`, `webformId`, `lastActivityBy`, `lastActivityTime` — приходят в ответе и работают в `select`, но в фильтре дают `400 UNKNOWN_FILTER_FIELD`, а в сортировке `400 UNKNOWN_SORT_FIELD`. Поля связей `parentId2` и `parentId7` фильтруются, но не сортируются. Брать имена для этих двух осей нужно не из таблицы выше, а из текста самой ошибки: он перечисляет допустимые.

## Пример ответа

```json
{
  "success": true,
  "data": {
    "fields": {
      "id": { "type": "number", "readonly": true, "label": "ID счёта", "description": "Уникальный числовой идентификатор счёта." },
      "title": { "type": "string", "readonly": false, "label": "Название", "description": "Название счёта." },
      "assignedById": { "type": "number", "readonly": false, "label": "Ответственный", "description": "ID ответственного пользователя. Список: GET /v1/users." }
    },
    "relations": {
      "contact": { "type": "one", "entity": "contact", "includable": true },
      "company": { "type": "one", "entity": "company", "includable": true }
    },
    "aggregatable": ["opportunity", "stageId", "assignedById"],
    "batch": ["create", "update", "delete"],
    "import": { "method": "POST", "path": "/v1/invoices/import", "maxItems": 100 },
    "include": ["contact", "company"]
  }
}
```

Показаны три поля из `data.fields` и остальные ключи `data`. Блок `data.products` в примере опущен, полный состав полей — в таблицах выше.

Что делать с именами из `data.include`, разобрано на странице [Получить счёт](/docs/entities/invoices/get#связанные-данные).

## Пример ответа при ошибке

403 — у ключа нет нужного скоупа:

```json
{
  "success": false,
  "error": {
    "code": "SCOPE_DENIED",
    "message": "This endpoint requires 'crm' scope"
  }
}
```

## Ошибки

| HTTP | Код | Описание |
|------|-----|---------|
| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` |
| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |

Полный список общих ошибок API — [Ошибки](/docs/errors).

## Смотрите также

- [Создать счёт](/docs/entities/invoices/create)
- [Список счетов](/docs/entities/invoices/list)
- [Entity API](/docs/entity-api)
