For AI agents: markdown of this page — /docs-content-en/chats/messages/update.md documentation index — /llms.txt
Edit a message
PATCH /v1/chats/:dialogId/messages/:messageId
Updates the text of a previously sent message. The API cannot restore the original text after an edit — send a new message if needed.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
dialogId (path) |
string | yes | Dialog identifier: numeric user ID or chatXXX for group chats. chatXXX is the id field of a recent dialogs row; the user ID comes from the user list |
messageId (path) |
number | yes | Message ID — from the send response or the id field of a message in the chat feed |
format (query) |
string | no | v2 turns on the v2 mode — see "The v2 mode" below. Any other value is ignored and the response is unchanged. A repeated format is not rejected: with format=v1&format=v2 the last value wins, so the v2 mode is on, while format=v2&format=v1 returns the legacy response. The bracket form format[]=v2 turns on the v2 mode when all its values are v2 |
The v2 mode. format=v2 edits the message: besides the text it changes the attach, keyboard, menu and block blocks — with or without the text — and urlPreview turns the link preview on and off. data carries { "result": true } instead of true. Without message the text stays as it was. An edit that could turn into a deletion is refused before Bitrix24 is called, as in the regular mode: text that is empty by the Bitrix24 rule gets 400 MESSAGE_REQUIRED. Removing a block ([], {} or "") without new text in the same request gets 400 INVALID_PARAMS, because a message left with no text and no blocks would be deleted, and the platform cannot see whether the message has text. At least one of message, attach, keyboard, menu, block is required. In the v2 mode message must be a string. Any other body field and any query parameter other than format are rejected with 400 INVALID_PARAMS, and botId is rejected with a pointer to editing as a bot. The message must belong to the dialog in the path: after the input checks, the platform reads that dialog without joining the chat and, if the message is not there, returns 404 ENTITY_NOT_FOUND and changes nothing. The me alias is resolved before this check. The regular mode does not check dialogId.
Request body fields
| Field | Type | Required | Description |
|---|---|---|---|
message |
string | yes | New message text (up to 20,000 characters). Optional in the v2 mode when a block is passed |
attach |
array|object|string | no | The v2 mode only: new attachments — an object, an array or a string with the attachment JSON. [], {} or "" removes them — only together with message |
keyboard |
array|object|string | no | The v2 mode only: a new keyboard — an object or an array. An empty value ([], {} or "" — a string is accepted only when empty) removes it — only together with message |
menu |
array|object|string | no | The v2 mode only: a new context menu — an object or an array. An empty value ([], {} or "" — a string is accepted only when empty) removes it — only together with message |
block |
array|object|string | no | The v2 mode only: new message blocks in the Bitrix24 format — an object with elements (each element with its own type) and an optional config. An empty value ([], {} or "" — a string is accepted only when empty) removes them — only together with message |
urlPreview |
boolean | no | The v2 mode only. On by default: every edit builds the link preview anew from the text — the new one, or the current one when none is given — including after removing the preview. false leaves the message without a preview. true/false or "Y"/"N" |
Message layout
- Text formatting — BB codes in the message text
Examples
curl — personal key
curl -X PATCH https://vibecode.bitrix24.com/v1/chats/42/messages/36889 \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"message": "Invoice confirmed. Thank you."
}'
curl — OAuth application
curl -X PATCH https://vibecode.bitrix24.com/v1/chats/42/messages/36889 \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"message": "Invoice confirmed. Thank you."
}'
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/chats/42/messages/36889', {
method: 'PATCH',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
message: 'Invoice confirmed. Thank you.',
}),
})
const { success, data } = await res.json()
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/chats/42/messages/36889', {
method: 'PATCH',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
message: 'Invoice confirmed. Thank you.',
}),
})
const { success, data } = await res.json()
curl — the v2 mode
curl -X PATCH "https://vibecode.bitrix24.com/v1/chats/42/messages/36889?format=v2" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"keyboard": [{ "TEXT": "Open the invoice", "LINK": "https://example.com/invoice" }]
}'
Response fields
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true on success |
data |
boolean | true on successful update |
data.result |
boolean | The v2 mode: true on successful update |
Response example
{
"success": true,
"data": true
}
Error response example
422 — the message was not found, the edit time has expired, or there is no access:
{
"success": false,
"error": {
"code": "BITRIX_ERROR",
"message": "Time has expired for modification or you don't have access",
"b24Code": "CANT_EDIT_MESSAGE"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | INVALID_PARAMS |
messageId is not a positive integer — checked before the Bitrix24 call |
| 400 | MESSAGE_REQUIRED |
The message field is absent, not text, or empty by Bitrix24's own rule — whitespace only, [BR]/[br] line-break tags only, or the null character (NUL) (including text sent under another field name — the error message names that field). Nothing was sent to Bitrix24 |
| 422 | BITRIX_ERROR |
Bitrix24 returned an error — message not found or unavailable (details in message). The Bitrix24 code is in error.b24Code |
| 400 | INVALID_PARAMS |
The v2 mode only: nothing to update, a block removal without message, a body field outside the list, a query parameter other than format or an invalid value |
| 404 | ENTITY_NOT_FOUND |
The v2 mode only: the message is not in the dialog in the path (it belongs to another dialog or does not exist) — nothing is changed |
| 403 | WRITE_BLOCKED_READONLY_KEY |
The key is read-only — see access rights |
| 403 | SCOPE_DENIED |
The key does not have the im scope |
| 401 | TOKEN_MISSING |
The key has no configured tokens |
| 502 | ME_ALIAS_RESOLUTION_FAILED |
The v2 mode only: failed to resolve the user for the me alias |
Full list of common API errors — Errors.
Known specifics
Empty text is not an update. Text that is empty by the Bitrix24 rule would delete the message, so such a request is refused before Bitrix24 is called — see MESSAGE_REQUIRED in the errors table. To delete a message, use DELETE /v1/chats/:dialogId/messages/:messageId. A number in message is accepted and stored as text.
Only message is sent to Bitrix24. In the regular mode other fields of the request body are not forwarded to Bitrix24 — including Bitrix24's own upper-case keys. In the v2 mode the fields from the table are forwarded, and the rest are rejected. Bitrix24 compares parameter names case-insensitively and the last key takes effect: an alias such as Message: "" beside MESSAGE would delete the message.
System messages cannot be edited. Messages sent with system: true have authorId = 0. They cannot be changed — the API returns an error.
An edit without changes. In the v2 mode even an edit that changes nothing may mark the message as edited if other members have already seen it.