How to Transfer a Deal from One Object Type to Another
Scope:
crmWho can execute the method: users with permission to modify CRM entities
If you are developing integrations for Bitrix24 using AI tools (Codex, Claude Code, Cursor), connect to the MCP server so that the assistant can utilize the official REST documentation.
Activities related to CRM entities are stored in the timeline of the entity's detail form. Transferring activities may be necessary between different types of entities: lead, deal, contact, company, invoice, SPA. For example, a client has two email addresses, but only one is saved in the company detail form in your Bitrix24. When the client sends an email from the second, unknown address, the email will create a new lead instead of attaching the email to the existing company. To keep client information in one place, you can transfer the activity from the lead to the company detail form.
To transfer the activity, we will sequentially execute four methods:
-
crm.activity.list — retrieve the activity ID
-
crm.company.list — retrieve the company ID for transferring the activity
-
crm.activity.binding.add — add the binding of the activity to the company
-
crm.activity.binding.delete — remove the binding of the activity from the lead
1. Retrieving the Activity ID
We will use the method crm.activity.list with the following filter:
-
OWNER_TYPE_ID— object type, specify1for lead -
OWNER_ID— ID of the entity from which we will transfer the activity
How to Use Examples in Documentation
BX24.callMethod(
"crm.activity.list",
{
filter:
{
"OWNER_TYPE_ID": 1,
"OWNER_ID": 1000977
},
},
);
require_once('crest.php');
$result = CRest::call(
'crm.activity.list',
[
'filter' => [
'OWNER_TYPE_ID' => 1,
'OWNER_ID' => 1000977
]
]
);
from b24pysdk import BitrixWebhook, Client
client = Client(
BitrixWebhook(
domain="your-domain.bitrix24.com",
auth_token="your-webhook-token",
)
)
result = client.crm.activity.list(
filter={
"OWNER_TYPE_ID": 1,
"OWNER_ID": 1000977,
}
).response.result
As a result, we will receive all activities associated with the specified entity.
{
"result": [
{
"ID": "7685",
"OWNER_ID": "1000977",
"OWNER_TYPE_ID": "1",
"TYPE_ID": "4",
"PROVIDER_ID": "CRM_EMAIL",
"PROVIDER_TYPE_ID": "EMAIL",
"PROVIDER_GROUP_ID": null,
"ASSOCIATED_ENTITY_ID": "0",
"SUBJECT": "for leads",
"CREATED": "2025-03-10T10:57:41+01:00",
"LAST_UPDATED": "2025-03-10T10:57:41+01:00",
"START_TIME": "2025-03-10T10:57:34+01:00",
"END_TIME": "2025-03-10T20:00:00+01:00",
"DEADLINE": "9999-12-31T00:00:00+01:00",
"COMPLETED": "N",
"STATUS": "1",
"RESPONSIBLE_ID": "29",
"PRIORITY": "2",
"NOTIFY_TYPE": "0",
"NOTIFY_VALUE": "0",
"DESCRIPTION": "<div>first email</div>\r\n",
"DESCRIPTION_TYPE": "3",
"DIRECTION": "1",
"LOCATION": "",
"SETTINGS": {
"EMAIL_META": {
"__email": "some_email@gmail.com",
"from": "Some client <some_client@gmail.com>",
"replyTo": "",
"to": "\"some_email@gmail.com\" <some_email@gmail.com>",
"cc": "",
"bcc": ""
},
"SANITIZE_ON_VIEW": 1
},
"ORIGINATOR_ID": null,
"ORIGIN_ID": null,
"AUTHOR_ID": "1",
"EDITOR_ID": "29",
"PROVIDER_PARAMS": [],
"PROVIDER_DATA": null,
"RESULT_MARK": "0",
"RESULT_VALUE": null,
"RESULT_SUM": null,
"RESULT_CURRENCY_ID": null,
"RESULT_STATUS": "0",
"RESULT_STREAM": "0",
"RESULT_SOURCE_ID": null,
"AUTOCOMPLETE_RULE": "0"
},
],
"total": 1,
}
2. Retrieving the Company ID
We will use the method crm.company.list with the following filter:
TITLE— name of the company
To limit the returned fields, we will add the select parameter and specify only the ID and TITLE fields.
BX24.callMethod(
"crm.company.list",
{
filter: { "TITLE": "Company_Name" },
select: [ "ID", "TITLE" ]
},
);
require_once('crest.php');
$result = CRest::call(
'crm.company.list',
[
'filter' => [
'TITLE' => 'Company_Name'
],
'select' => [
'ID', 'TITLE'
]
]
);
result = client.crm.company.list(
filter={
"TITLE": "Company_Name",
},
select=["ID", "TITLE"],
).response.result
As a result, we will receive the company ID — ID: 173.
{
"result": [
{
"ID": "173",
"TITLE": "Company_Name"
}
],
"total": 1,
}
3. Adding the Binding of the Activity to the Company
To bind the activity and the company, we will use the method crm.activity.binding.add with the following parameters:
-
activityId— ID of the activity, obtained in step 1 using the method crm.activity.list -
entityTypeId— ID of the object type, specify4for company -
entityId— ID of the company, obtained in step 2 using the method crm.company.list
BX24.callMethod(
'crm.activity.binding.add',
{
activityId: 7685,
entityTypeId: 4,
entityId: 173
},
);
require_once('crest.php');
$result = CRest::call(
'crm.activity.binding.add',
[
'activityId' => 7685,
'entityTypeId' => 4,
'entityId' => 173
]
);
result = client.crm.activity.binding.add(
activity_id=7685,
entity_type_id=4,
entity_id=173,
).response.result
As a result, we will receive true, indicating that the binding for the activity was successfully created. If you receive an error in the result, refer to the documentation for the method crm.activity.binding.add to understand possible errors.
{
"result": true,
}
4. Removing the Binding of the Activity from the Lead
We will use the method crm.activity.binding.delete with the following parameters:
-
activityId— ID of the activity, obtained in step 1 using the method crm.activity.list -
entityTypeId— ID of the object type, specify1for lead -
entityId— ID of the lead from which we are removing the activity
BX24.callMethod(
'crm.activity.binding.delete',
{
activityId: 7685,
entityTypeId: 1,
entityId: 1000977
},
);
require_once('crest.php');
$result = CRest::call(
'crm.activity.binding.delete',
[
'activityId' => 7685,
'entityTypeId' => 1,
'entityId' => 1000977
]
);
result = client.crm.activity.binding.delete(
activity_id=7685,
entity_type_id=1,
entity_id=1000977,
).response.result
As a result, we will receive true, indicating that the binding of the activity from the lead was successfully removed. If you receive an error in the result, refer to the documentation for the method crm.activity.binding.delete to understand possible errors.
{
"result": true,
}
Code Example
// Function to execute all steps
function transferActivityToCompany() {
// Prompt user for lead ID
const leadId = prompt("Enter the lead ID:");
// Prompt user for company name
const companyName = prompt("Enter the company name:");
// Step 1: Retrieve the list of activities for the specified lead
BX24.callMethod(
"crm.activity.list",
{
filter: {
"OWNER_TYPE_ID": 1,
"OWNER_ID": leadId
},
},
function(result) {
if (result.error()) {
console.error(result.error());
return;
}
const activities = result.data();
if (activities.length === 0) {
console.log("No activities found for the specified lead.");
return;
}
const activityId = activities[0].ID;
// Step 2: Search for the company by name
BX24.callMethod(
"crm.company.list",
{
filter: { "TITLE": companyName },
select: [ "ID", "TITLE" ]
},
function(result) {
if (result.error()) {
console.error(result.error());
return;
}
const companies = result.data();
if (companies.length === 0) {
console.log("No company found with the specified name.");
return;
}
const companyId = companies[0].ID;
// Step 3: Create a binding for the found activity and company
BX24.callMethod(
'crm.activity.binding.add',
{
activityId: activityId,
entityTypeId: 4,
entityId: companyId
},
function(result) {
if (result.error()) {
console.error(result.error());
return;
}
console.log("Activity successfully bound to the company.");
// Step 4: Remove the binding of the activity from the lead
BX24.callMethod(
'crm.activity.binding.delete',
{
activityId: activityId,
entityTypeId: 1,
entityId: leadId
},
function(result) {
if (result.error()) {
console.error(result.error());
} else {
console.log("Activity successfully unbound from the lead.");
}
}
);
}
);
}
);
}
);
}
// Execute the function
transferActivityToCompany();
require_once('crest.php');
// Function to execute all steps
function transferActivityToCompany($leadId, $companyName) {
// Step 1: Retrieve the list of activities for the specified lead
$activityResult = CRest::call(
'crm.activity.list',
[
'filter' => [
'OWNER_TYPE_ID' => 1,
'OWNER_ID' => $leadId
]
]
);
if (isset($activityResult['error'])) {
echo 'Error: ' . $activityResult['error_description'];
return;
}
$activities = $activityResult['result'];
if (empty($activities)) {
echo "No activities found for the specified lead.";
return;
}
$activityId = $activities[0]['ID'];
// Step 2: Search for the company by name
$companyResult = CRest::call(
'crm.company.list',
[
'filter' => ['TITLE' => $companyName],
'select' => ['ID', 'TITLE']
]
);
if (isset($companyResult['error'])) {
echo 'Error: ' . $companyResult['error_description'];
return;
}
$companies = $companyResult['result'];
if (empty($companies)) {
echo "No company found with the specified name.";
return;
}
$companyId = $companies[0]['ID'];
// Step 3: Create a binding for the found activity and company
$bindingAddResult = CRest::call(
'crm.activity.binding.add',
[
'activityId' => $activityId,
'entityTypeId' => 4,
'entityId' => $companyId
]
);
if (isset($bindingAddResult['error'])) {
echo 'Error: ' . $bindingAddResult['error_description'];
return;
}
echo "Activity successfully bound to the company.";
// Step 4: Remove the binding of the activity from the lead
$bindingDeleteResult = CRest::call(
'crm.activity.binding.delete',
[
'activityId' => $activityId,
'entityTypeId' => 1,
'entityId' => $leadId
]
);
if (isset($bindingDeleteResult['error'])) {
echo 'Error: ' . $bindingDeleteResult['error_description'];
} else {
echo "Activity successfully unbound from the lead.";
}
}
// Prompt user for lead ID and company name
$leadId = readline("Enter the lead ID: ");
$companyName = readline("Enter the company name: ");
// Execute the function
transferActivityToCompany($leadId, $companyName);
from b24pysdk import BitrixWebhook, Client
from b24pysdk.errors import BitrixAPIError
def transfer_activity_to_company(client, lead_id, company_name):
try:
activity_result = client.crm.activity.list(
filter={
"OWNER_TYPE_ID": 1,
"OWNER_ID": lead_id,
}
).response.result
except BitrixAPIError as error:
print(f"Error: {error}")
return
if not activity_result:
print("No activities found for the specified lead.")
return
activity_id = activity_result[0]["ID"]
try:
company_result = client.crm.company.list(
filter={"TITLE": company_name},
select=["ID", "TITLE"],
).response.result
except BitrixAPIError as error:
print(f"Error: {error}")
return
if not company_result:
print("No company found with the specified name.")
return
company_id = company_result[0]["ID"]
try:
add_result = client.crm.activity.binding.add(
activity_id=activity_id,
entity_type_id=4,
entity_id=company_id,
).response.result
except BitrixAPIError as error:
print(f"Error: {error}")
return
if not add_result:
return
print("Activity successfully bound to the company.")
try:
delete_result = client.crm.activity.binding.delete(
activity_id=activity_id,
entity_type_id=1,
entity_id=lead_id,
).response.result
except BitrixAPIError as error:
print(f"Error: {error}")
else:
if delete_result:
print("Activity successfully unbound from the lead.")
client = Client(
BitrixWebhook(
domain="your-domain.bitrix24.com",
auth_token="your-webhook-token",
)
)
lead_id = int(input("Enter the lead ID: "))
company_name = input("Enter the company name: ")
transfer_activity_to_company(client, lead_id, company_name)