
## Invoice fields

`GET /v1/invoices/fields`

Returns a description of all invoice fields, including user fields (`ufCrm_*`).

## Examples

### curl — personal key

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

### curl — OAuth application

```bash
curl -X GET https://vibecode.bitrix24.com/v1/invoices/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/invoices/fields', {
  headers: { 'X-Api-Key': 'YOUR_API_KEY' },
})

const { success, data } = await res.json()
console.log('Fields:', Object.keys(data.fields).length)
```

### JavaScript — OAuth application

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/invoices/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.fields` | object | The invoice field schema: field name → `type`, `readonly`, `label`, `description`. The standard fields are listed below, and the `ufCrm_*` user fields of this Bitrix24 account are added to them |
| `data.relations` | object | Related entities with the `includable` flag: `contact`, `company`, and `deal` |
| `data.products` | object | Product-row operations and their field schema. See [Product fields](/docs/entities/invoices/products-fields) |
| `data.aggregatable` | array | Standard fields allowed in the aggregation `groupBy`: `opportunity`, `stageId`, `assignedById`, `currencyId` |
| `data.batch` | array | Invoice operations available in [`POST /v1/batch`](/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 |

### Standard invoice fields

| Field | Type | Read-only | Description |
|------|-----|:---:|---------|
| `id` | number | yes | Invoice ID |
| `title` | string | | Invoice title |
| `stageId` | string | | Stage. Format: `DT31_{categoryId}:{stage}`. Stage list: `GET /v1/statuses?filter[entityId]=SMART_INVOICE_STAGE_{categoryId}` — categoryId depends on the Bitrix24 account. To find it: `GET /v1/invoices?limit=1&select=categoryId` or ask your Bitrix24 account administrator |
| `categoryId` | number | | Funnel ID |
| `assignedById` | number | | Assignee. List: `GET /v1/users` |
| `contactId` | number | | Payer contact ID. Lookup: `GET /v1/contacts` |
| `companyId` | number | | Payer company ID. Lookup: `GET /v1/companies` |
| `mycompanyId` | number | | ID of your own company (the seller) issuing the invoice. Lookup: `GET /v1/companies` |
| `opportunity` | number | | Invoice total amount |
| `currencyId` | string | | Currency. List: `GET /v1/currencies` |
| `taxValue` | number | yes | Tax amount in the invoice currency; 0 when no tax applies. Computed by Bitrix24 from the product rows; a supplied value is not saved through any write endpoint, so the write is rejected. Set the tax through the product rows |
| `begindate` | datetime | | Invoice start date |
| `closedate` | datetime | | Invoice closing date |
| `accountNumber` | string | | Printable invoice number |
| `comments` | string | | Free-text comment |
| `sourceId` | string | | Source. List: `GET /v1/statuses?filter[entityId]=SOURCE` |
| `sourceDescription` | string | | Free-text description of the source |
| `utmSource` | string | yes | Traffic source (utm_source of the advertising campaign). Set by Bitrix24; `null` when absent. A supplied value is not saved, and the write is rejected. An explicit `select` in list or search requests does not return this field (see below) |
| `utmMedium` | string | yes | Traffic type of the advertising campaign (utm_medium): cpc, banner, email and so on. Set by Bitrix24; `null` when absent |
| `utmCampaign` | string | yes | Advertising campaign name (utm_campaign). Set by Bitrix24; `null` when absent |
| `utmContent` | string | yes | Advertising campaign content (utm_content). Set by Bitrix24; `null` when absent |
| `utmTerm` | string | yes | Search phrase of the advertising campaign (utm_term). Set by Bitrix24; `null` when absent |
| `xmlId` | string | | External identifier for integration mapping |
| `opened` | boolean | | Whether the invoice is visible to all employees, not only the assignee |
| `isManualOpportunity` | boolean | | Manual amount mode |
| `isRecurring` | boolean | | Recurring invoice template |
| `observers` | array | | Observers (user IDs). List: `GET /v1/users`. Send the full list: an update replaces the entire set rather than adding to it; an empty list clears the observers on `PATCH /v1/invoices/{id}` — the batch endpoints do not support empty lists and reject them: the entity batch with `400 BATCH_ITEM_VALIDATION`, the global batch with `INVALID_PARAMS` under the call in `data.errors` |
| `contactIds` | array | | All linked contacts (IDs). Lookup: `GET /v1/contacts`. Send the full list: an update replaces all links rather than adding to them; an empty list clears the links on `PATCH /v1/invoices/{id}` — the batch endpoints do not support empty lists and reject them: the entity batch with `400 BATCH_ITEM_VALIDATION`, the global batch with `INVALID_PARAMS` under the call in `data.errors` |
| `contacts` | array | yes | Not returned (`notReturned: true`): the Bitrix24 item API never returns this key for invoices, although the live Bitrix24 metadata lists it. Declared so that write attempts receive a clear validation error instead of a raw Bitrix24 error (create and update — `400 READONLY_FIELD`, import — `400 IMPORT_ITEM_VALIDATION`, entity batch — `400 BATCH_ITEM_VALIDATION`, global batch — `READONLY_FIELD` under the call); in `select` it yields an `UNKNOWN_SELECT_FIELD` warning and no value. The linked contacts are in `contactIds` |
| `locationId` | string | | Location identifier (Bitrix24 type `location`). Bitrix24 stores the sent string as is; `null` when unset |
| `webformId` | number | | ID of the CRM form that created the invoice. Writable on invoices: a sent value is stored and read back |
| `parentId2` | crm_entity | | Related deal. Lookup: `GET /v1/deals` |
| `parentId7` | crm_entity | | Related quote. Lookup: `GET /v1/quotes` |
| `createdBy` | number | yes | Creator ID |
| `createdTime` | datetime | yes | Creation date |
| `updatedBy` | number | yes | ID of the employee who last changed the invoice |
| `updatedTime` | datetime | yes | Modification date |
| `movedBy` | number | yes | ID of the employee who last changed the stage |
| `movedTime` | datetime | yes | Date of the last stage change |
| `previousStageId` | string | yes | The stage before the current one |
| `lastActivityBy` | number | yes | Author of the last timeline activity. Set by Bitrix24; a supplied value is not saved through any write endpoint, so the write is rejected. Lookup: `GET /v1/users` |
| `lastActivityTime` | datetime | yes | Date and time of the last activity on the invoice; set by Bitrix24. Returned in UTC, like all other dates in the record. Not accepted in `filter` or `order` (see below) |
| `lastCommunicationTime` | datetime | yes | Date of the last communication on any channel |
| `lastCommunicationCallTime` | datetime | yes | Date of the last call |
| `lastCommunicationEmailTime` | datetime | yes | Date of the last email |
| `lastCommunicationImolTime` | datetime | yes | Date of the last Open Channel communication |
| `lastCommunicationWebformTime` | datetime | yes | Date of the last web-form communication |

User fields (`ufCrm_*`) come back alongside the standard ones and are writable. Their set and count depend on the Bitrix24 account, so the table does not list them — read the live response.

**Not every field in the table is accepted in `filter` and `order`.** Twelve of them — `taxValue`, `observers`, `contactIds`, `locationId`, `webformId`, `lastActivityBy`, `lastActivityTime`, `utmSource`, `utmMedium`, `utmCampaign`, `utmContent`, `utmTerm` — arrive in the response, but return `400 UNKNOWN_FILTER_FIELD` in a filter and `400 UNKNOWN_SORT_FIELD` in a sort; the not-returned `contacts` is refused the same way. The first seven fields are supported in `select` by every read endpoint; the five `utm*` arrive only in the full record (no `select`) and in `GET /v1/invoices/{id}` — in an explicit `select` on list or search, Bitrix24 ignores their names, and the rows carry no such keys. The relation fields `parentId2` and `parentId7` are accepted in a filter but not in a sort. For those two axes, take the names from the error message rather than from the table above — the error lists the ones that are accepted.

## Response example

```json
{
  "success": true,
  "data": {
    "fields": {
      "id": { "type": "number", "readonly": true, "label": "ID", "description": "Unique numeric identifier of the invoice." },
      "title": { "type": "string", "readonly": false, "label": "Title", "description": "Invoice title." },
      "assignedById": { "type": "number", "readonly": false, "label": "Assignee", "description": "ID of the responsible user. List: GET /v1/users." }
    },
    "relations": {
      "contact": { "type": "one", "entity": "contacts", "includable": true },
      "company": { "type": "one", "entity": "companies", "includable": true },
      "deal": { "type": "one", "entity": "deals", "includable": true }
    },
    "aggregatable": ["opportunity", "stageId", "assignedById", "currencyId"],
    "batch": ["create", "update", "delete"],
    "import": { "method": "POST", "path": "/v1/invoices/import", "maxItems": 100 },
    "include": ["contact", "company", "deal"]
  }
}
```

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

The `deal` relation reads the deal ID from the invoice's dynamic `parentId2` field. The field comes from live metadata for the Bitrix24 account and may be absent from `data.fields` when the response contains a `fields_partial` warning.

What to do with the names from `data.include` is covered on the [Get invoice](/docs/entities/invoices/get#related-data) page.

## Error response example

403 — the key lacks the required scope:

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

## Errors

| HTTP | Code | Description |
|------|-----|---------|
| 403 | `SCOPE_DENIED` | The API key lacks 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 invoice](/docs/entities/invoices/create)
- [List invoices](/docs/entities/invoices/list)
- [Entity API](/docs/entity-api)
