
## Create an entry

`POST /v1/timeline-logs`

Creates a new entry in a CRM entity's log (timeline). The entry will appear in the card history of a deal, lead, contact, company, or smart process as a message from an application.

## Request fields (body)

| Field | Type | Required | Description |
|------|-----|:-----:|---------|
| **`entityTypeId`** | number | yes | Parent CRM entity type: `1`=lead, `2`=deal, `3`=contact, `4`=company, `7`=quote, `14`=order, `31`=invoice, `≥128`=smart process. More — [Entity types](/docs/timeline-logs#parent-entity-types) |
| **`entityId`** | number | yes | Parent entry ID. Source: `GET /v1/deals`, `GET /v1/leads`, `GET /v1/contacts`, `GET /v1/companies`, `GET /v1/items/:entityTypeId` |
| **`title`** | string | yes | Entry title. Displayed in bold in the timeline card |
| **`text`** | string | yes | Main entry text. An empty string is allowed (`""`) |
| `iconCode` | string | no | Icon code next to the title. Commonly used: `info`, `circle-check`, `document`, `link`, `unlink`, `view`, `stage-change`, `sum`, `store`, `relation`, `IM`, `call`, `call-incoming`, `call-completed`. Defaults to the empty string `""` (no icon) |

## Examples

### curl — personal key

```bash
curl -X POST https://vibecode.bitrix24.com/v1/timeline-logs \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "entityTypeId": 2,
    "entityId": 100,
    "title": "AI agent processed the request",
    "text": "Customer data analyzed. Recommendation: Enterprise plan."
  }'
```

### curl — OAuth application

```bash
curl -X POST https://vibecode.bitrix24.com/v1/timeline-logs \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "entityTypeId": 2,
    "entityId": 100,
    "title": "AI agent processed the request",
    "text": "Customer data analyzed. Recommendation: Enterprise plan."
  }'
```

### JavaScript — personal key

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/timeline-logs', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    entityTypeId: 2,
    entityId: 100,
    title: 'AI agent processed the request',
    text: 'Customer data analyzed. Recommendation: Enterprise plan.',
  }),
})

const { success, data } = await res.json()
console.log('Log ID:', data.id)
```

### JavaScript — OAuth application

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/timeline-logs', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    entityTypeId: 2,
    entityId: 100,
    title: 'AI agent processed the request',
    text: 'Customer data analyzed. Recommendation: Enterprise plan.',
  }),
})

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

## Response fields

| Field | Type | Description |
|------|-----|---------|
| `id` | number | ID of the created log entry |
| `created` | datetime | Creation date, ISO 8601 with the Bitrix24 account timezone |
| `authorId` | number | Author ID. When created via the API it matches the API key's user |
| `title` | string | Title |
| `text` | string | Entry text |
| `iconCode` | string | Icon code (or `""` if not set) |

## Response example

```json
{
  "success": true,
  "data": {
    "id": 5012,
    "created": "2026-04-27T10:00:00+00:00",
    "authorId": 1,
    "title": "AI agent processed the request",
    "text": "Customer data analyzed. Recommendation: Enterprise plan.",
    "iconCode": ""
  }
}
```

## Error response example

400 — a required field is missing:

```json
{
  "success": false,
  "error": {
    "code": "INVALID_PARAMS",
    "message": "Required: entityTypeId (positive int), entityId (positive int), title (string), text (string). Optional: iconCode (string, default \"\")"
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|---------|
| 400 | `INVALID_PARAMS` | `entityTypeId`, `entityId`, `title`, `text` not provided or invalid, or `iconCode` type is not a string |
| 422 | `BITRIX_ERROR` | Bitrix24 rejected the request (for example, the parent entity does not exist) |
| 403 | `SCOPE_DENIED` | The API key does not have the `crm` scope |
| 401 | `TOKEN_MISSING` | The API key has no configured tokens |

Full list of common API errors — [Errors](/docs/errors).

## Known specifics

**Deletion is only possible by the same application.** Bitrix24 forbids deleting a log entry through an application other than the one that created it. Personal keys (`vibe_api_*`) rotate OAuth tokens, so through them `DELETE` always returns `403 CROSS_APP_DELETE_FORBIDDEN`. For the full "create → delete via API" lifecycle, use an OAuth application (`vibe_app_*` + `Authorization: Bearer ...`). More — [Delete an entry](/docs/timeline-logs/logs/delete).

**The `text` field is required but allows an empty string.** Bitrix24 accepts `text: ""`, and the `title` is still displayed. If you want to leave it without a description, pass an empty string, not `null`.

**The `iconCode` field is saved as an empty string by default.** In the response `iconCode` is always present, even if you did not pass it — it comes back as `""`.

## See also

- [List entries](/docs/timeline-logs/logs/list) — all entries of the parent entity
- [Get an entry](/docs/timeline-logs/logs/get) — a single entry by `id`
- [Delete an entry](/docs/timeline-logs/logs/delete) — mind the cross-app restriction
- [Pin an entry](/docs/timeline-logs/pins/pin) — after creation
- [Bind to another entity](/docs/timeline-logs/bindings/bind) — multi-binding
- [Save a note](/docs/timeline-logs/notes/save) — an internal comment on the entry
