
# Таймлайн CRM

12 REST-эндпоинтов для журналирования действий в таймлайне CRM-сущностей: создание лог-записей, заметки к ним, закрепление, привязка к нескольким сущностям одновременно. Записи оставляют AI-агенты, фоновые интеграции и сценарии автоматизации, когда действие должно остаться структурированным следом в карточке сделки или контакта.

**Скоуп:** `crm` | **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** `X-Api-Key`

[Быстрый старт](#быстрый-старт) | [AI-агент логирует свои действия (полный пример)](#полный-пример-ai-агент-логирует-свои-действия) | [Коды ошибок](#коды-ошибок) | [Справочник эндпоинтов](#справочник-эндпоинтов)

## Разделы документации

- [Записи журнала](/docs/timeline-logs/logs) — создание, просмотр, удаление лог-записей
- [Заметки](/docs/timeline-logs/notes) — заметка-комментарий к лог-записи
- [Закрепления](/docs/timeline-logs/pins) — закрепить или открепить запись в верхней части таймлайна
- [Привязки](/docs/timeline-logs/bindings) — связать одну запись с несколькими сущностями CRM

## Когда использовать

- Записать действие AI-агента: проанализировал клиента, подготовил коммерческое предложение, отправил уведомление.
- Зафиксировать событие из внешней системы: оплата прошла, заказ собран, документ подписан.
- Создать аудиторский след интеграции: какие данные обработала, на основании чего приняла решение.
- Закрепить ключевое событие сделки в верхней части таймлайна, чтобы менеджер сразу видел контекст.

Для текстовых комментариев пользователя (не системных событий) используйте [`/v1/timelines`](/docs/entities/timelines) — это отдельный API над `crm.timeline.comment.*`.

## Быстрый старт

### 1. Создайте запись в таймлайне сделки

```bash
curl -X POST https://vibecode.bitrix24.tech/v1/timeline-logs \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "entityTypeId": 2,
    "entityId": 100,
    "title": "AI-агент обработал заявку",
    "text": "Проанализированы данные клиента. Рекомендация: предложить тариф Enterprise."
  }'
```

Ответ:

```json
{
  "success": true,
  "data": {
    "id": 5012,
    "created": "2026-04-27T10:00:00+03:00",
    "authorId": 1,
    "title": "AI-агент обработал заявку",
    "text": "Проанализированы данные клиента. Рекомендация: предложить тариф Enterprise.",
    "iconCode": ""
  }
}
```

### 2. Закрепите запись в верхней части таймлайна

```bash
curl -X POST https://vibecode.bitrix24.tech/v1/timeline-logs/5012/pin \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "entityTypeId": 2, "entityId": 100 }'
```

### 3. Прикрепите внутреннюю заметку

```bash
curl -X POST https://vibecode.bitrix24.tech/v1/timeline-logs/5012/note \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "entityTypeId": 2, "entityId": 100, "text": "Клиент обычно отвечает в течение 2 дней." }'
```

## Полный пример: AI-агент логирует свои действия

Сценарий: AI-агент анализирует сделку, оставляет лог-запись с результатом, привязывает её к контакту и компании, прикрепляет заметку для менеджера, закрепляет в таймлайне.

```javascript
const VIBE_KEY = process.env.VIBE_KEY
const BASE = 'https://vibecode.bitrix24.tech/v1'

async function api(method, path, body = null) {
  const opts = { method, headers: { 'X-Api-Key': VIBE_KEY } }
  if (body) {
    opts.headers['Content-Type'] = 'application/json'
    opts.body = JSON.stringify(body)
  }
  const res = await fetch(`${BASE}${path}`, opts)
  return res.json()
}

const dealId = 100
const contactId = 50
const companyId = 10

// 1. Записать факт начала работы
const start = await api('POST', '/timeline-logs', {
  entityTypeId: 2,
  entityId: dealId,
  title: 'AI-агент начал обработку',
  text: 'Анализ данных клиента, проверка кредитного лимита, подготовка предложения.',
})
const startId = start.data.id

// 2. Связать запись с контактом и компанией — менеджеры обоих увидят
//    то же событие в своих таймлайнах
await api('POST', `/timeline-logs/${startId}/bind`, { entityTypeId: 3, entityId: contactId })
await api('POST', `/timeline-logs/${startId}/bind`, { entityTypeId: 4, entityId: companyId })

// ... AI-агент выполняет работу ...

// 3. Записать результат отдельной лог-записью
const result = await api('POST', '/timeline-logs', {
  entityTypeId: 2,
  entityId: dealId,
  title: 'AI-агент завершил обработку',
  text: [
    '[b]Результаты анализа:[/b]',
    '- Кредитный лимит: OK (500 000 руб.)',
    '- Рекомендованный тариф: Enterprise',
    '- Скидка: 10% (постоянный клиент)',
    '- КП сформировано и отправлено на email',
  ].join('\n'),
})
const resultId = result.data.id

// 4. Закрепить итоговую запись в верхней части таймлайна
await api('POST', `/timeline-logs/${resultId}/pin`, { entityTypeId: 2, entityId: dealId })

// 5. Оставить внутреннюю заметку для менеджера
await api('POST', `/timeline-logs/${resultId}/note`, {
  entityTypeId: 2,
  entityId: dealId,
  text: 'Клиент обычно отвечает в течение 2 дней. Напомнить менеджеру, если нет ответа.',
})

console.log('AI-агент завершил работу, все действия залогированы')
```

## Какой ключ использовать

CRUD-операции работают с любым типом ключа — личным (`vibe_api_*`) или OAuth-приложением (`vibe_app_*`). Однако **`DELETE /v1/timeline-logs/:id` накладывает ограничение**: Битрикс24 разрешает удалить лог-запись только тому же приложению, которое её создало.

- **OAuth-приложение** (`vibe_app_*` + `Authorization: Bearer ...`) — стабильное `client_id`, удалить свои записи можно. Если планируете удалять созданные записи через API, используйте этот тип ключа.
- **Личный ключ** (`vibe_api_*`) — Вайбкод ротирует токены между вызовами, для Битрикс24 каждый вызов выглядит как отдельное приложение. `DELETE` всегда возвращает `403 CROSS_APP_DELETE_FORBIDDEN`, в том числе на свежесозданные записи.

Если приложение, создавшее запись, недоступно — удалить её нельзя в принципе. Битрикс24 не предоставляет UI-кнопку удаления log-записи в карточке сущности. Учитывайте это при проектировании сценариев аудита.

Подробнее — [Удалить запись](/docs/timeline-logs/logs/delete).

## Типы родительских сущностей

Параметр `entityTypeId` (числовой код CRM-сущности) указывает, в чьём таймлайне создаётся запись:

| `entityTypeId` | Сущность | Где найти ID |
|:---:|----------|--------------|
| 1 | Лид | [`GET /v1/leads`](/docs/entities/leads/list) |
| 2 | Сделка | [`GET /v1/deals`](/docs/entities/deals/list) |
| 3 | Контакт | [`GET /v1/contacts`](/docs/entities/contacts) |
| 4 | Компания | [`GET /v1/companies`](/docs/entities/companies) |
| 7 | Предложение | [`GET /v1/quotes`](/docs/entities/quotes) |
| 14 | Заказ | [`GET /v1/orders`](/docs/entities/orders) |
| 31 | Счёт | [`GET /v1/invoices`](/docs/entities/invoices) |
| ≥ 128 | Смарт-процесс | [`GET /v1/items/:entityTypeId`](/docs/entities/items/list); список процессов — [`GET /v1/smart-processes`](/docs/entities/smart-processes/list) |

В привязках (`bind`/`unbind`) можно использовать как числовой `entityTypeId`, так и строковый `entityType` напрямую (`"deal"`, `"contact"`, `"dynamic_174"` и т. п.) — см. [Привязать запись](/docs/timeline-logs/bindings/bind).

## Коды ошибок

### Ошибки таймлайна

| HTTP | Код | Описание |
|------|-----|---------|
| 400 | `INVALID_PARAMS` | Не переданы или некорректны обязательные параметры (`entityTypeId`, `entityId`, `title`, `text`, `itemType` и т. д. — конкретное поле в `message`) |
| 400 | `INVALID_ENTITY_TYPE_ID` | В `bindings.bind`/`unbind` передан `entityTypeId` без отображения на `ENTITY_TYPE` (`< 128` и не из таблицы выше) |
| 403 | `CROSS_APP_DELETE_FORBIDDEN` | Попытка удалить лог-запись через ключ, отличный от того, которым она создана |
| 404 | `ENTITY_NOT_FOUND` | Лог-запись с указанным `id` не существует — Битрикс24 вернул ошибку `NOT_FOUND` |
| 404 | `NOT_FOUND` | Только `GET /v1/timeline-logs/:id`: Битрикс24 вернул успешный ответ, но объект записи пуст |
| 404 | `NOTE_NOT_FOUND` | У указанного элемента таймлайна нет привязанной заметки |

### Системные ошибки

| HTTP | Код | Описание |
|------|-----|---------|
| 401 | `MISSING_API_KEY` | Отсутствует `X-Api-Key` |
| 401 | `INVALID_API_KEY` | Неверный API-ключ |
| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов (для `vibe_app_*` нужен `Authorization: Bearer ...`) |
| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` |
| 422 | `BITRIX_ERROR` | Битрикс24 вернул ошибку (текст в `message`) |
| 429 | `RATE_LIMITED` | Превышен лимит запросов. Подождите 1–2 секунды и повторите. Несколько вызовов можно объединить в [`POST /v1/batch`](/docs/batch) |
| 429 | `QUEUE_TIMEOUT` | Запрос к B24 не успел выполниться в очереди портала. Запрос не был отправлен в Битрикс24 — безопасно повторить (`Retry-After`). Сузьте фильтр или повторите позже |
| 429 | `ERROR_LOOP_DETECTED` | Блокировка на стороне Вайбкод: подряд много одинаковых ошибок на одном методе. Повторяйте с задержкой — каждый N-й запрос пробрасывается для проверки восстановления |
| 502 | `BITRIX_UNAVAILABLE` | Портал Битрикс24 недоступен |
| 503 | `BITRIX_TIMEOUT` | Битрикс24 принял запрос, но не ответил за 15 секунд. Для write-операций — сначала перечитайте сущность, изменение могло примениться |
| 500 | `INTERNAL_ERROR` | Внутренняя ошибка сервера |

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

## Справочник эндпоинтов

Все 12 эндпоинтов:

| Метод | Путь | Bitrix24 метод | Описание |
|-------|------|---------------|---------|
| POST | [/v1/timeline-logs](/docs/timeline-logs/logs/create) | `crm.timeline.logmessage.add` | Создать лог-запись |
| GET | [/v1/timeline-logs](/docs/timeline-logs/logs/list) | `crm.timeline.logmessage.list` | Список лог-записей |
| GET | [/v1/timeline-logs/:id](/docs/timeline-logs/logs/get) | `crm.timeline.logmessage.get` | Получить одну запись |
| DELETE | [/v1/timeline-logs/:id](/docs/timeline-logs/logs/delete) | `crm.timeline.logmessage.delete` | Удалить запись |
| POST | [/v1/timeline-logs/:id/note](/docs/timeline-logs/notes/save) | `crm.timeline.note.save` | Сохранить или обновить заметку |
| GET | [/v1/timeline-logs/:id/note](/docs/timeline-logs/notes/get) | `crm.timeline.note.get` | Получить заметку |
| DELETE | [/v1/timeline-logs/:id/note](/docs/timeline-logs/notes/delete) | `crm.timeline.note.delete` | Удалить заметку |
| POST | [/v1/timeline-logs/:id/pin](/docs/timeline-logs/pins/pin) | `crm.timeline.item.pin` | Закрепить запись |
| POST | [/v1/timeline-logs/:id/unpin](/docs/timeline-logs/pins/unpin) | `crm.timeline.item.unpin` | Открепить запись |
| POST | [/v1/timeline-logs/:id/bind](/docs/timeline-logs/bindings/bind) | `crm.timeline.bindings.bind` | Привязать к ещё одной сущности |
| POST | [/v1/timeline-logs/:id/unbind](/docs/timeline-logs/bindings/unbind) | `crm.timeline.bindings.unbind` | Отвязать от сущности |
| GET | [/v1/timeline-logs/:id/bindings](/docs/timeline-logs/bindings/list) | `crm.timeline.bindings.list` | Список всех привязок записи |

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

- [Комментарии таймлайна](/docs/entities/timelines)
- [Сделки](/docs/entities/deals)
- [Лиды](/docs/entities/leads)
- [Контакты](/docs/entities/contacts)
- [Компании](/docs/entities/companies)
- [Смарт-процессы](/docs/entities/smart-processes)
- [Batch](/docs/batch)
- [Лимиты и оптимизация](/docs/optimization)
