
## Save note

`POST /v1/timeline-logs/:id/note`

Saves a note to a single timeline item. Each timeline item can have only one note — calling again with the same `:id` overwrites the previous text.

## Parameters

| Parameter | Type | Required | Description |
|----------|-----|:-----:|---------|
| `id` (path) | number | yes | ID of the log entry (or another timeline item) the note is attached to |

## Request fields (body)

| Field | Type | Required | Default | Description |
|------|-----|:-----:|-----------|---------|
| **`entityTypeId`** | number | yes | — | Type of the parent CRM entity — the one whose timeline contains the item. See [Entity types](/docs/timeline-logs#parent-entity-types) |
| **`entityId`** | number | yes | — | ID of the parent record |
| **`text`** | string | yes | — | Note text. Overwrites the existing note, if any |
| `itemType` | number | no | `1` | Item type: `1` — timeline history entry (including log entries), `2` — activity (see [`/v1/activities`](/docs/entities/activities)) |

## Examples

### curl — personal key

```bash
curl -X POST https://vibecode.bitrix24.com/v1/timeline-logs/5012/note \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "entityTypeId": 2,
    "entityId": 100,
    "text": "The client usually replies within 2 days."
  }'
```

### curl — OAuth application

```bash
curl -X POST https://vibecode.bitrix24.com/v1/timeline-logs/5012/note \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "entityTypeId": 2,
    "entityId": 100,
    "text": "The client usually replies within 2 days."
  }'
```

### JavaScript — personal key

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/timeline-logs/5012/note', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    entityTypeId: 2,
    entityId: 100,
    text: 'The client usually replies within 2 days.',
  }),
})

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

### JavaScript — OAuth application

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/timeline-logs/5012/note', {
  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,
    text: 'The client usually replies within 2 days.',
  }),
})

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

## Response fields

| Field | Type | Description |
|------|-----|---------|
| `success` | boolean | Always `true` on success |
| `data.saved` | boolean | Always `true` — operation confirmation |

## Response example

HTTP 201:

```json
{
  "success": true,
  "data": { "saved": true }
}
```

## Error response example

400 — a required field is missing:

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

## Errors

| HTTP | Code | Description |
|------|-----|---------|
| 400 | `INVALID_PARAMS` | `entityTypeId` / `entityId` / `text` are missing or invalid, or `itemType` is not 1 or 2 |
| 422 | `BITRIX_ERROR` | Bitrix24 rejected the request (for example, no item with the given `id` exists) |
| 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

**A single call creates or updates.** If the item has no note — one is created; if it does — the text is overwritten. There is no separate update method; a repeat `POST` with new text is the "update".

**Does not validate the existence of the `:id` log entry.** If you pass the `id` of a nonexistent entry — `save` still returns `201 + {saved: true}`. The note will not actually attach — when you try to read it via [`GET /:id/note`](/docs/timeline-logs/notes/get), the response will be `404 ENTITY_NOT_FOUND`. Before `save`, make sure the log entry exists.

**`itemType: 1` works for log entries and timeline comments.** Use `itemType: 2` only if you are working with an activity from [`/v1/activities`](/docs/entities/activities).

**A note and a log entry are different concepts.** A log entry is a standalone item in the timeline history (created via [`POST /v1/timeline-logs`](/docs/timeline-logs/logs/create)). A note is a short comment attached to an item. An item has at most one note.

**A note cannot be retrieved without `entityTypeId` + `entityId`.** Even though a note is tied to a specific `itemId`, B24 requires the parent entity context when reading and deleting. Keep these parameters from the time of creation.

## See also

- [Get note](/docs/timeline-logs/notes/get) — read the text and author
- [Delete note](/docs/timeline-logs/notes/delete) — parameters are passed in the query, not the body
- [Create log entry](/docs/timeline-logs/logs/create) — the primary item that a note attaches to
- [Pin entry](/docs/timeline-logs/pins/pin) — highlight an entry with a note at the top of the timeline
