Reply to an Email v 3.0 crm.activity.mail.reply
Choose a tool for developing with an AI agent:
- use Alaio Vibecode to build an app for Bitrix24 from a task description without knowing any programming language. The agent writes the code and deploys the app to a server, with no manual hosting setup
- use the MCP server to develop a REST API integration in your own project. The agent refers to the official REST documentation
Scope:
crmWho can execute the method: a user with permission to view the email and with a mailbox available for sending
This method belongs to REST 3.0. The call specifics and response format of the new API version are described in the REST 3.0 overview.
The crm.activity.mail.reply method sends a reply to a CRM email and saves it as a new email in the same thread with the same bindings to CRM items. The method sends the email to the recipients immediately.
The method determines the recipients and subject itself:
- a reply to an incoming email goes to the sender or to the address from the
Reply-Toheader - a reply to an outgoing email goes to the recipients of the original email
- if the email contains no addresses, the reply goes to the first email address from the communication contacts of the email
- the subject is the subject of the original email with the
Re:prefix
The sender addresses are excluded from the recipients. The method works only with emails, which are activities with providerId equal to CRM_EMAIL.
Method Parameters
Required parameters are marked with *
|
Name |
Description |
|
activityId* |
ID of the email to reply to. The ID can be retrieved with the crm.<type>.activity.list method with the |
|
body* |
Reply text. An empty string and a string of spaces are not accepted |
|
cc |
CC addresses |
|
bcc |
BCC addresses |
|
from |
Sender address, for example, Default: the CRM address from the settings if it is available to the user, otherwise the first available sender |
|
senderId |
Sender ID. Use together with |
|
mailboxId |
Mailbox ID. Use together with |
The total number of recipients in to, cc, and bcc is limited by the plan, for example, to 10 addresses. The reply recipient counts toward this number. On the demo plan and on plans without mail synchronization, each field allows only one address.
The method checks the addresses before sending: if cc or bcc contains an invalid address or the number of recipients exceeds the limit, the email is not sent.
Code Examples
How to Use Examples in Documentation
The new API call differs by adding the /api/ segment to the request URL:
https://{installation_address}/rest/api/{user_id}/{webhook_token}/crm.activity.mail.reply
The examples reply to the email with the ID 747 and copy the manager.
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"activityId":747,"body":"Hello! Thank you for your email, we will reply by the end of the day.","cc":["manager@example.com"]}' \
https://**put_your_bitrix24_address**/rest/api/**put_your_user_id_here**/**put_your_webhook_here**/crm.activity.mail.reply
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"activityId":747,"body":"Hello! Thank you for your email, we will reply by the end of the day.","cc":["manager@example.com"],"auth":"**put_access_token_here**"}' \
https://**put_your_bitrix24_address**/rest/api/crm.activity.mail.reply
CRM methods are not yet included in the list of REST 3.0 methods known to $b24.actions.v3.call.make: such a call returns the SDK error JSSDK_CORE_METHOD_NOT_SUPPORT_IN_API_V3. Call the method through the REST 3.0 HTTP client — $b24.getHttpClient(ApiVersion.v3).call.
import { ApiVersion, Text } from '@bitrix24/b24jssdk'
import type { B24Frame } from '@bitrix24/b24jssdk'
declare const $b24: B24Frame
type MailReplyResult = {
activityId: number
parentActivityId: number
from: string
to: string[]
warnings: string[]
}
try {
const response = await $b24.getHttpClient(ApiVersion.v3).call<MailReplyResult>(
'crm.activity.mail.reply',
{
activityId: 747,
body: 'Hello! Thank you for your email, we will reply by the end of the day.',
cc: ['manager@example.com'],
},
Text.getUuidRfc4122()
)
if (!response.isSuccess) {
console.error(response.getErrorMessages().join('; '))
} else {
const result = response.getData()!.result
console.info('Reply sent, activity:', result.activityId)
}
} catch (error) {
// Thrown on transport or SDK failures (AjaxError, SdkError, etc.)
console.error(error)
}
CRM methods are not yet included in the list of REST 3.0 methods known to $b24.actions.v3.call.make. Call the method through the REST 3.0 HTTP client — $b24.getHttpClient(B24Js.ApiVersion.v3).call.
<script src="https://unpkg.com/@bitrix24/b24jssdk@1/dist/umd/index.min.js"></script>
<script>
async function replyToMail() {
try {
const $b24 = await B24Js.initializeB24Frame()
const response = await $b24.getHttpClient(B24Js.ApiVersion.v3).call(
'crm.activity.mail.reply',
{
activityId: 747,
body: 'Hello! Thank you for your email, we will reply by the end of the day.',
cc: ['manager@example.com'],
},
B24Js.Text.getUuidRfc4122()
)
if (!response.isSuccess) {
console.error(response.getErrorMessages().join('; '))
return
}
const result = response.getData().result
console.info('Reply sent, activity:', result.activityId)
} catch (error) {
// Thrown on transport or SDK failures (AjaxError, SdkError, etc.)
console.error(error)
}
}
document.addEventListener('DOMContentLoaded', replyToMail)
</script>
b24pysdk has no ready-made wrappers for CRM methods, and the SDK sends to REST 3.0 only the methods from the Config().api_v3_methods list. Add the method to this list and call it via bitrix_token.call_method with prefer_version=3.
from b24pysdk import Config
from b24pysdk.errors import BitrixSDKException
from b24pysdk.errors.v3 import BitrixAPIError
method = "crm.activity.mail.reply"
Config().configure(api_v3_methods=Config().api_v3_methods | {method})
try:
response = bitrix_token.call_method(
api_method=method,
params={
"activityId": 747,
"body": "Hello! Thank you for your email, we will reply by the end of the day.",
"cc": ["manager@example.com"],
},
prefer_version=3,
)
result = response["result"]
print(result)
except BitrixAPIError as error:
print(
"Bitrix API error",
f"code: {error.code}",
f"message: {error.error.message}",
sep="\n",
)
except BitrixSDKException as error:
print(f"Bitrix SDK error: {error.message}")
except Exception as error:
print(f"Unexpected error: {error}")
SDKs do not yet support the /rest/api/ address in calls. Use direct HTTP requests, for example, via curl or fetch.
try {
$response = $b24Service
->core
->call(
'crm.activity.mail.reply',
[
'activityId' => 747,
'body' => 'Hello! Thank you for your email, we will reply by the end of the day.',
'cc' => ['manager@example.com'],
]
);
$result = $response
->getResponseData()
->getResult();
print_r($result);
} catch (Throwable $e) {
echo $e->getMessage();
}
SDKs do not yet support the /rest/api/ address in calls. Use direct HTTP requests, for example, via curl or fetch.
BX24.callMethod(
'crm.activity.mail.reply',
{
activityId: 747,
body: 'Hello! Thank you for your email, we will reply by the end of the day.',
cc: ['manager@example.com'],
},
result => {
if (result.error())
console.error(result.error());
else
console.dir(result.data());
}
);
SDKs do not yet support the /rest/api/ address in calls. Use direct HTTP requests, for example, via curl or fetch.
require_once('crest.php');
$result = CRest::call(
'crm.activity.mail.reply',
[
'activityId' => 747,
'body' => 'Hello! Thank you for your email, we will reply by the end of the day.',
'cc' => ['manager@example.com'],
]
);
echo '<PRE>';
print_r($result);
echo '</PRE>';
// client and ctx are already created — see the Go SDK section
res, err := client.Core().Call(ctx, "crm.activity.mail.reply", b24.Params{
"activityId": 747,
"body": "Hello! Thank you for your email, we will reply by the end of the day.",
"cc": []string{"manager@example.com"},
})
if err != nil {
return fmt.Errorf("crm.activity.mail.reply: %w", err)
}
var result struct {
ActivityID int `json:"activityId"`
ParentActivityID int `json:"parentActivityId"`
From string `json:"from"`
To []string `json:"to"`
Warnings []string `json:"warnings"`
}
if err := json.Unmarshal(res.Result, &result); err != nil {
return fmt.Errorf("parse response: %w", err)
}
fmt.Println(result.ActivityID, result.To)
Response Handling
HTTP status: 200
{
"result": {
"activityId": 8473,
"parentActivityId": 8471,
"from": "sales@example.com",
"to": [
"client@example.com"
],
"cc": [],
"bcc": [],
"isSyncedToImap": false,
"warnings": [
"No mailbox is configured for the chosen \"from\" address; the message is not mirrored to a Sent IMAP folder. Replies are tracked via Reply-To and the URN."
]
},
"time": {
"start": 1793712321,
"finish": 1793712322.461878,
"duration": 1.4618780612945557,
"processing": 1,
"date_start": "2026-11-03T16:25:21+03:00",
"date_finish": "2026-11-03T16:25:22+03:00",
"operating_reset_at": 1793712900,
"operating": 0.46572399139404297
}
}
Returned Data
|
Name |
Description |
|
result |
Sending result |
|
result.activityId |
ID of the new CRM email with the reply |
|
result.parentActivityId |
ID of the email the reply was sent to |
|
result.from |
Address the reply was sent from |
|
result.to |
Reply recipients |
|
result.cc |
CC addresses |
|
result.bcc |
BCC addresses |
|
result.isSyncedToImap |
|
|
result.warnings |
Warnings that did not prevent sending |
|
time |
Information about the request execution time |
Error Handling
HTTP status: 400
{
"error": {
"code": "CRM_EMAIL_INVALID_REQUEST",
"message": "body must be a non-empty string."
}
}
|
Name |
Description |
|
error.code |
String error code. Use it to identify the type of exception |
|
error.message |
Text description of the error |
|
error.validation |
Array with error details. Present only in data validation errors |
|
error.validation[].field |
Name of the field where the validation error occurred |
|
error.validation[].message |
Description of the error related to the specified field |
Possible Error Codes
|
Code |
Error description |
How to Fix |
|
|
activityId must be a positive integer. |
Pass |
|
|
body must be a non-empty string. |
Pass the reply text in |
|
|
Parent activity is not a CRM email (PROVIDER_ID must be "CRM_EMAIL"). |
Pass the ID of an email, not of an activity of another kind. HTTP status: 400 |
|
|
Cannot determine reply recipients from the parent activity. |
The original email has no addresses to reply to. Send the email with the previous version methods, specifying the recipients explicitly. HTTP status: 400 |
|
|
Parent CRM email activity not found. |
The email does not exist, or the email's client is hidden from you by access settings. HTTP status: 404 |
|
|
Access denied to the parent CRM email activity. |
You have no permission to view the email. HTTP status: 403 |
|
|
Invalid recipient email(s): |
Check the addresses in |
|
|
Too many recipients: |
Reduce the number of addresses in |
|
|
Tariff restriction: cannot send to more than |
The plan limits the number of addresses in a single field. Reduce the number of addresses in |
|
|
Some recipients are in the global mail blacklist: |
Remove the addresses from the mail blacklist. HTTP status: 400 |
|
|
No available email sender is configured for this user. |
Connect a mailbox or a sender for the user. HTTP status: 400 |
|
|
Sender email is not available for this user. |
The address from |
|
|
Cannot resolve a valid "from" address. |
Check the address in |
|
|
The "mail" module is not available. |
Mail is not available on this Bitrix24. HTTP status: 400 |
|
|
|
The email was not sent. Retry the request later. HTTP status: 400 |
|
|
This request requires data type |
Pass the parameter of the type specified in its description. HTTP status: 400 |
Statuses and System Error Codes
HTTP Status: 4xx, 5xx
The errors described below are returned by the REST API itself, not by the logic of a specific method. They can arrive in response to any method.
|
Status |
Code |
Description |
|
|
|
An internal server error has occurred. Retry the call, and if the error persists, contact the server administrator or Bitrix24 technical support |
|
|
|
The server returned an unexpected response. Retry the call, and if the error persists, contact the server administrator or Bitrix24 technical support |
|
|
|
The request intensity limit has been exceeded |
|
|
|
The method is blocked because the request resource intensity limit has been exceeded. The block is lifted automatically once the accumulated execution time of the method no longer exceeds the limit |
|
|
|
The request contains no authorization data: neither an access token nor a webhook code was passed |
|
|
|
Methods are called over the HTTPS protocol only |
|
|
|
The REST API is blocked due to overload. This is a manual individual block. To have it lifted, contact Bitrix24 technical support |
|
|
|
REST API access is not active for this account. In Bitrix24 Cloud, check the current plan or trial status: Vibe+ plans include REST API access, while Essentials plans do not. A webhook receives a different error message — |
|
|
|
No active webhook with the specified user identifier and secret code was found |
|
|
|
No method with this name was found. The name is misspelled, the method does not exist in the REST API, or it is unavailable without the required scope |
|
|
|
The request requires broader permissions than the token has: for a webhook these are the permissions granted to it, for an application it is the scope. For an application, the error message ends with |
|
|
|
The access token has expired |
|
|
|
The application is installed, but the Bitrix24 administrator has granted access to it only to specific users |
|
|
|
The public part of the site is closed. To open it on an on-premise installation, disable the "Temporary closure of the public part of the site" option. Path to the setting: Desktop > Settings > Product Settings > Module Settings > Main Module > Temporary closure of the public part of the site |