สำหรับเอเจนต์ AI: markdown ของหน้านี้ — /docs-content-en/timeline-logs.md ดัชนีเอกสาร — /llms.txt
บทความในเอกสารมีให้บริการเป็นภาษาอังกฤษในขณะนี้
CRM Timeline
12 REST endpoints for logging actions in the timeline of CRM entities: creating log entries, notes on them, pinning, binding to multiple entities at once. Entries are written by AI agents, background integrations, and automation scenarios when an action must leave a structured trail in a deal or contact card.
Scope: crm | Base URL: https://vibecode.bitrix24.com/v1 | Authorization: X-Api-Key
Quick start | An AI agent logs its actions (full example) | Error codes | Endpoint reference
Documentation sections
- Log entries — create, view, delete log entries
- Notes — a note attached to a log entry
- Pins — pin or unpin an entry at the top of the timeline
- Bindings — link one entry to multiple CRM entities
When to use
- Record an AI agent's action: analyzed the client, prepared a quote, sent a notification.
- Capture an event from an external system: payment succeeded, order packed, document signed.
- Build an audit trail of an integration: what data it processed, what it based its decision on.
- Pin a key deal event at the top of the timeline so the manager sees the context right away.
For text comments from users (not system events), use /v1/timelines — a separate API over crm.timeline.comment.*.
Quick start
1. Create an entry in a deal's timeline
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": "Client data analyzed. Recommendation: offer the Enterprise plan."
}'
Response:
{
"success": true,
"data": {
"id": 5012,
"created": "2026-04-27T10:00:00+00:00",
"authorId": 1,
"title": "AI agent processed the request",
"text": "Client data analyzed. Recommendation: offer the Enterprise plan.",
"iconCode": ""
}
}
2. Pin the entry at the top of the timeline
curl -X POST https://vibecode.bitrix24.com/v1/timeline-logs/5012/pin \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "entityTypeId": 2, "entityId": 100 }'
3. Attach an internal note
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 responds within 2 days." }'
Full example: an AI agent logs its actions
Scenario: an AI agent analyzes a deal, leaves a log entry with the result, binds it to a contact and a company, attaches a note for the manager, and pins it in the timeline.
const VIBE_KEY = process.env.VIBE_KEY
const BASE = 'https://vibecode.bitrix24.com/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. Record that work has started
const start = await api('POST', '/timeline-logs', {
entityTypeId: 2,
entityId: dealId,
title: 'AI agent started processing',
text: 'Client data analysis, credit-limit check, quote preparation.',
})
const startId = start.data.id
// 2. Bind the entry to the contact and the company — managers of both will see
// the same event in their timelines
await api('POST', `/timeline-logs/${startId}/bind`, { entityTypeId: 3, entityId: contactId })
await api('POST', `/timeline-logs/${startId}/bind`, { entityTypeId: 4, entityId: companyId })
// ... the AI agent does its work ...
// 3. Record the result as a separate log entry
const result = await api('POST', '/timeline-logs', {
entityTypeId: 2,
entityId: dealId,
title: 'AI agent finished processing',
text: [
'[b]Analysis results:[/b]',
'- Credit limit: OK (500,000 USD)',
'- Recommended plan: Enterprise',
'- Discount: 10% (returning client)',
'- Quote generated and sent by email',
].join('\n'),
})
const resultId = result.data.id
// 4. Pin the final entry at the top of the timeline
await api('POST', `/timeline-logs/${resultId}/pin`, { entityTypeId: 2, entityId: dealId })
// 5. Leave an internal note for the manager
await api('POST', `/timeline-logs/${resultId}/note`, {
entityTypeId: 2,
entityId: dealId,
text: 'The client usually responds within 2 days. Remind the manager if there is no reply.',
})
console.log('AI agent finished, all actions logged')
Which key to use
CRUD operations work with any key type — a personal key (vibe_api_*) or an OAuth application key (vibe_app_*). However, DELETE /v1/timeline-logs/:id imposes a restriction: Bitrix24 allows a log entry to be deleted only by the same app that created it.
- OAuth application (
vibe_app_*+Authorization: Bearer ...) — stableclient_id, you can delete your own entries. If you plan to delete the entries you create via the API, use this key type. - Personal key (
vibe_api_*) — Vibecode rotates tokens between calls, so to Bitrix24 each call looks like a separate app.DELETEalways returns403 CROSS_APP_DELETE_FORBIDDEN, including for freshly created entries.
If the app that created the entry is unavailable, there is no way to delete it at all. Bitrix24 does not provide a UI delete button for a log entry in the entity card. Keep this in mind when designing audit scenarios.
For details, see Delete an entry.
Parent entity types
The entityTypeId parameter (the CRM entity's numeric code) specifies whose timeline the entry is created in:
entityTypeId |
Entity | Where to find the ID |
|---|---|---|
| 1 | Lead | GET /v1/leads |
| 2 | Deal | GET /v1/deals |
| 3 | Contact | GET /v1/contacts |
| 4 | Company | GET /v1/companies |
| 7 | Quote | GET /v1/quotes |
| 14 | Order | GET /v1/orders |
| 31 | Invoice | GET /v1/invoices |
| ≥ 128 | Smart process | GET /v1/items/:entityTypeId; list of processes — GET /v1/smart-processes |
In bindings (bind/unbind) you can use either the numeric entityTypeId or the string entityType directly ("deal", "contact", "dynamic_174", etc.) — see Bind an entry.
Error codes
Timeline errors
| HTTP | Code | Description |
|---|---|---|
| 400 | INVALID_PARAMS |
Required parameters are missing or invalid (entityTypeId, entityId, title, text, itemType, etc. — the specific field is in message) |
| 400 | INVALID_ENTITY_TYPE_ID |
In bindings.bind/unbind, an entityTypeId was passed that has no mapping to ENTITY_TYPE (< 128 and not in the table above) |
| 403 | CROSS_APP_DELETE_FORBIDDEN |
Attempt to delete a log entry via a key other than the one it was created with |
| 404 | ENTITY_NOT_FOUND |
A log entry with the given id does not exist — Bitrix24 returned a NOT_FOUND error |
| 404 | NOT_FOUND |
Only GET /v1/timeline-logs/:id: Bitrix24 returned a successful response but the entry object is empty |
| 404 | NOTE_NOT_FOUND |
Only GET /v1/timeline-logs/:id/note: Bitrix24 answered without an error, but the response carries no note. For an item without a note, Bitrix24 returns an error, so that case returns 404 ENTITY_NOT_FOUND |
System errors
| HTTP | Code | Description |
|---|---|---|
| 401 | MISSING_API_KEY |
Missing X-Api-Key |
| 401 | INVALID_API_KEY |
The key is not recognized — no such key exists on the platform |
| 401 | TOKEN_MISSING |
The API key has no configured tokens (a vibe_app_* key requires Authorization: Bearer ...) |
| 403 | SCOPE_DENIED |
The API key lacks the crm scope |
| 403 | WRITE_BLOCKED_READONLY_KEY |
The key is read-only and the request writes something — see access rights |
| 422 | BITRIX_ERROR |
Bitrix24 returned an error (text in message) |
| 429 | RATE_LIMITED |
Request rate limit exceeded. Wait 1–2 seconds and retry. Several calls can be combined into POST /v1/batch |
| 429 | QUEUE_TIMEOUT |
The request to Bitrix24 did not get through the portal queue in time. The request was NOT sent to Bitrix24 — safe to retry (Retry-After). Narrow the filter or retry later |
| 429 | ERROR_LOOP_DETECTED |
A Vibecode-side block: many identical errors on one method in a row. Fix the cause first. Then retry reads with backoff; do not retry writes automatically — every Nth request may pass through, so read state first |
| 502 | BITRIX_UNAVAILABLE |
The Bitrix24 portal is unavailable |
| 503 | BITRIX_TIMEOUT |
Bitrix24 accepted the request but did not respond within 60 seconds. For write operations — re-read the entity first, as the change may have been applied |
| 500 | INTERNAL_ERROR |
Internal server error |
For the full list of common API codes, see Errors.
Endpoint reference
All 12 endpoints:
| Method | Path | Bitrix24 method | Description |
|---|---|---|---|
| POST | /v1/timeline-logs | crm.timeline.logmessage.add |
Create a log entry |
| GET | /v1/timeline-logs | crm.timeline.logmessage.list |
List log entries |
| GET | /v1/timeline-logs/:id | crm.timeline.logmessage.get |
Get a single entry |
| DELETE | /v1/timeline-logs/:id | crm.timeline.logmessage.delete |
Delete an entry |
| POST | /v1/timeline-logs/:id/note | crm.timeline.note.save |
Save or update a note |
| GET | /v1/timeline-logs/:id/note | crm.timeline.note.get |
Get a note |
| DELETE | /v1/timeline-logs/:id/note | crm.timeline.note.delete |
Delete a note |
| POST | /v1/timeline-logs/:id/pin | crm.timeline.item.pin |
Pin an entry |
| POST | /v1/timeline-logs/:id/unpin | crm.timeline.item.unpin |
Unpin an entry |
| POST | /v1/timeline-logs/:id/bind | crm.timeline.bindings.bind |
Bind to another entity |
| POST | /v1/timeline-logs/:id/unbind | crm.timeline.bindings.unbind |
Unbind from an entity |
| GET | /v1/timeline-logs/:id/bindings | crm.timeline.bindings.list |
List all bindings of an entry |