How to Upload Files
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.
This page describes how to upload a new file to Bitrix24 via the Bitrix24 REST API: how to encode a file in Base64, which format to use when passing it to a method, and which limitations to consider.
There is no single format for all methods: some accept a Base64 string, others accept an array containing a filename and such a string, and others use a separate parameter. Before making a call, check the How to Choose a Format table.
Updating, replacing, and deleting files are described in the How to Update and Delete Files article. To retrieve an already uploaded file, see the page for the relevant method.
The User permissions and scope required for the call are specified at the beginning of each method's page — check them before uploading a file.
Types of File Fields
In Bitrix24, there are two types of file fields.
-
File. This field is not linked to Drive. The file is passed directly into the field — either as a Base64 string or as an array containing a filename and such a string. Bitrix24 decodes the string and saves the file, while the field retains the
IDof the file. -
File (Drive). This field is linked to Drive, and the field stores the
IDof an object on Drive. Some methods accept Base64 and upload the file to Drive themselves — this is how "file (Drive)" type fields work in the CRM. If the method expects a ready-madeID, first upload the file to Drive, and then passIDto the field. For more details, see the How to Pass a File to a Field Linked to Drive section.
How to Encode a File in Base64
Base64 is an encoding standard that represents binary data as a text string. Encoding is necessary to pass a file through text-based protocols, such as HTTP.
In JavaScript, use the built-in FileReader object. The code reads the file selected by the user and converts it to Base64.
const fileInput = document.getElementById('fileInput'); // File selection field
fileInput.addEventListener('change', function() {
const file = fileInput.files[0]; // Get selected file
const reader = new FileReader();
reader.onload = function() {
const base64 = reader.result.split(',')[1]; // Get base64 without prefix
console.log(base64); // Display result
};
reader.readAsDataURL(file); // Encode file to base64
});
In PHP, use the base64_encode function. The code reads the file from the disk and encodes it in Base64.
$filePath = 'path/to/your/file.jpg'; // File path
$fileData = file_get_contents($filePath); // Read file
$base64 = base64_encode($fileData); // Encode to base64
The result of the encoding will be a string like YmFzZSDRgtC10YHRgg==. The larger the file size, the longer the string.
Consider the characteristics of the format.
-
A Base64 string is approximately one-third longer than the original file: every 3 bytes are converted into 4 characters. A 1.5 MB file will occupy about 2 MB in a request.
-
Pass the string without the
data:image/png;base64,prefix. In the JavaScript example, the prefix is stripped by the methodsplit(',')[1]. -
Validate the string before sending. Bitrix24 decodes it and saves the result as a file exactly as is: a corrupted string will result in a corrupted file, and an empty string will result in a method error.
-
In most formats, the filename is passed separately. If you pass only the Base64 string without a name, Bitrix24 will generate a name automatically — the file will be difficult to identify in the interface.
How to Choose a Transfer Format
The format depends on the method and whether the field is a multiple field or not.
|
Method |
One file |
Multiple files |
|
Base64 string in field |
— |
|
|
Base64 string in field |
— |
|
|
"name — Base64" array in field |
— |
|
|
"name — Base64" array in field |
— |
|
|
"name — Base64" array in "file" type field |
||
|
array of pairs of one item in field |
array of pairs in field |
|
|
array of pairs of one item in field |
array of pairs in field |
|
|
"name — Base64" array in "file" type property |
||
|
"name — Base64" array in "file" type property |
||
|
crm.lead.add, crm.deal.add, crm.contact.add, crm.company.add |
object |
|
|
object |
||
|
disk.storage.uploadfile, disk.folder.uploadfile, disk.file.uploadversion |
— |
|
|
— |
||
|
— |
If the required method is not in the table, check the parameter descriptions on the method's page for the format.
File Transfer Formats
How to Use Examples in Documentation
Base64 String in the File Field
Pass a Base64 string in the file field. The filename is not passed in this format.
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"fields":{"name":"Template example","file":"base64_encoded_content_here","code":"example_template_code"}}' \
https://**put_your_bitrix24_address**/rest/**put_your_user_id_here**/**put_your_webhook_here**/documentgenerator.template.add
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"fields":{"name":"Template example","file":"base64_encoded_content_here","code":"example_template_code"},"auth":"**put_access_token_here**"}' \
https://**put_your_bitrix24_address**/rest/documentgenerator.template.add
try
{
const response = await $b24.callMethod(
'documentgenerator.template.add',
{
fields: {
name: "Template example",
file: "base64_encoded_content_here", // File content encoded in base64
code: "example_template_code"
}
}
);
const result = response.getData().result;
console.log(result);
}
catch( error )
{
console.error('Error:', error);
}
try {
$response = $b24Service
->core
->call(
'documentgenerator.template.add',
[
'fields' => [
'name' => 'Template example',
'file' => 'base64_encoded_content_here', // File content encoded in base64
'code' => 'example_template_code'
]
]
);
$result = $response
->getResponseData()
->getResult();
echo 'Success: ' . print_r($result, true);
} catch (Throwable $e) {
error_log($e->getMessage());
echo 'Error adding template: ' . $e->getMessage();
}
BX24.callMethod(
'documentgenerator.template.add',
{
fields: {
name: "Template example",
file: "base64_encoded_content_here", // File content encoded in base64
code: "example_template_code"
}
}
);
require_once('crest.php');
$result = CRest::call(
'documentgenerator.template.add',
[
'fields' => [
'name' => 'Template example',
'file' => 'base64_encoded_content_here', // File content encoded in base64
'code' => 'example_template_code'
]
]
);
echo '<PRE>';
print_r($result);
echo '</PRE>';
// client and ctx are already created — see the Go SDK section
res, err := client.Core().Call(ctx, "documentgenerator.template.add", b24.Params{
"fields": b24.Params{
"name": "Template example",
"file": "base64_encoded_content_here",
"code": "example_template_code",
},
})
if err != nil {
return fmt.Errorf("documentgenerator.template.add: %w", err)
}
var item struct {
ID b24.ID `json:"ID"`
Name string `json:"NAME"`
Type string `json:"TYPE"`
StorageID b24.ID `json:"STORAGE_ID"`
FileID b24.ID `json:"FILE_ID"`
Size string `json:"SIZE"`
}
if err := json.Unmarshal(res.Result, &item); err != nil {
return fmt.Errorf("parse response: %w", err)
}
fmt.Println(item.ID, item.Name)
"Filename — Base64" Array
Pass an array of two items: the first is the filename with its extension, and the second is the Base64 string.
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"DOCUMENT_TYPE":["lists","BizprocDocument","iblock_164"],"NAME":"App template","TEMPLATE_DATA":["bp-379.bpt","base64_encoded_content_here"]}' \
https://**put_your_bitrix24_address**/rest/**put_your_user_id_here**/**put_your_webhook_here**/bizproc.workflow.template.add
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"DOCUMENT_TYPE":["lists","BizprocDocument","iblock_164"],"NAME":"App template","TEMPLATE_DATA":["bp-379.bpt","base64_encoded_content_here"],"auth":"**put_access_token_here**"}' \
https://**put_your_bitrix24_address**/rest/bizproc.workflow.template.add
try
{
const response = await $b24.callMethod(
'bizproc.workflow.template.add',
{
DOCUMENT_TYPE: ['lists', 'BizprocDocument', 'iblock_164'],
NAME: 'App template',
TEMPLATE_DATA: [
"bp-379.bpt", // First array element — filename
"base64_encoded_content_here" // Second array element — file content in base64
]
}
);
const result = response.getData().result;
console.log(result);
}
catch( error )
{
console.error('Error:', error);
}
try {
$response = $b24Service
->core
->call(
'bizproc.workflow.template.add',
[
'DOCUMENT_TYPE' => ['lists', 'BizprocDocument', 'iblock_164'],
'NAME' => 'App template',
'TEMPLATE_DATA' => [
'bp-379.bpt', // First array element — filename
'base64_encoded_content_here' // Second array element — file content in base64
]
]
);
$result = $response
->getResponseData()
->getResult();
echo 'Success: ' . print_r($result, true);
} catch (Throwable $e) {
error_log($e->getMessage());
echo 'Error adding workflow template: ' . $e->getMessage();
}
BX24.callMethod(
'bizproc.workflow.template.add',
{
DOCUMENT_TYPE: ['lists', 'BizprocDocument', 'iblock_164'],
NAME: 'App template',
TEMPLATE_DATA: [
"bp-379.bpt", // First array element — filename
"base64_encoded_content_here" // Second array element — file content in base64
]
}
);
require_once('crest.php');
$result = CRest::call(
'bizproc.workflow.template.add',
[
'DOCUMENT_TYPE' => ['lists', 'BizprocDocument', 'iblock_164'],
'NAME' => 'App template',
'TEMPLATE_DATA' => [
'bp-379.bpt', // Filename
'base64_encoded_content_here' // File content in base64
]
]
);
echo '<PRE>';
print_r($result);
echo '</PRE>';
// client and ctx are already created — see the Go SDK section
res, err := client.Core().Call(ctx, "bizproc.workflow.template.add", b24.Params{
"DOCUMENT_TYPE": []string{"lists", "BizprocDocument", "iblock_164"},
"NAME": "App template",
"TEMPLATE_DATA": []string{"bp-379.bpt", "base64_encoded_content_here"},
})
if err != nil {
return fmt.Errorf("bizproc.workflow.template.add: %w", err)
}
var item struct {
ID b24.ID `json:"ID"`
Name string `json:"NAME"`
Type string `json:"TYPE"`
StorageID b24.ID `json:"STORAGE_ID"`
FileID b24.ID `json:"FILE_ID"`
Size string `json:"SIZE"`
}
if err := json.Unmarshal(res.Result, &item); err != nil {
return fmt.Errorf("parse response: %w", err)
}
fmt.Println(item.ID, item.Name)
fileData Object
Pass an object with the fileData key. The key contains an array consisting of the filename and the Base64 string.
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"fields":{"iblockId":"24","name":"Product example","previewPicture":{"fileData":["example.jpg","base64_encoded_content_here"]}}}' \
https://**put_your_bitrix24_address**/rest/**put_your_user_id_here**/**put_your_webhook_here**/catalog.product.add
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"fields":{"iblockId":"24","name":"Product example","previewPicture":{"fileData":["example.jpg","base64_encoded_content_here"]}},"auth":"**put_access_token_here**"}' \
https://**put_your_bitrix24_address**/rest/catalog.product.add
try
{
const response = await $b24.callMethod(
'catalog.product.add',
{
fields: {
iblockId: '24',
name: "Product example",
previewPicture: {
fileData: [
"example.jpg", // Image filename
"base64_encoded_content_here" // Image content in base64
]
}
}
}
);
const result = response.getData().result;
console.log(result);
}
catch( error )
{
console.error('Error:', error);
}
try {
$response = $b24Service
->core
->call(
'catalog.product.add',
[
'fields' => [
'iblockId' => '24',
'name' => 'Product example',
'previewPicture' => [
'fileData' => [
'example.jpg', // Image filename
'base64_encoded_content_here' // Image content in base64
]
]
]
]
);
$result = $response
->getResponseData()
->getResult();
echo 'Success: ' . print_r($result, true);
} catch (Throwable $e) {
error_log($e->getMessage());
echo 'Error adding product: ' . $e->getMessage();
}
BX24.callMethod(
'catalog.product.add',
{
fields: {
iblockId: '24',
name: "Product example",
previewPicture: {
fileData: [
"example.jpg", // Image filename
"base64_encoded_content_here" // Image content in base64
]
}
}
}
);
require_once('crest.php');
$result = CRest::call(
'catalog.product.add',
[
'fields' => [
'iblockId' => '24',
'name' => 'Product example',
'previewPicture' => [
'fileData' => [
'example.jpg', // Image filename
'base64_encoded_content_here' // Image content in base64
]
]
]
]
);
echo '<PRE>';
print_r($result);
echo '</PRE>';
// client and ctx are already created — see the Go SDK section
res, err := client.Core().Call(ctx, "catalog.product.add", b24.Params{
"fields": b24.Params{
"iblockId": "24",
"name": "Product example",
"previewPicture": b24.Params{
"fileData": []string{"example.jpg", "base64_encoded_content_here"},
},
},
})
if err != nil {
return fmt.Errorf("catalog.product.add: %w", err)
}
var item struct {
ID b24.ID `json:"ID"`
Name string `json:"NAME"`
Type string `json:"TYPE"`
StorageID b24.ID `json:"STORAGE_ID"`
FileID b24.ID `json:"FILE_ID"`
Size string `json:"SIZE"`
}
if err := json.Unmarshal(res.Result, &item); err != nil {
return fmt.Errorf("parse response: %w", err)
}
fmt.Println(item.ID, item.Name)
Parameter fileContent
Pass a separate fileContent parameter containing an array of the filename and the Base64 string. The parameter is passed at the top level of the request, rather than inside fields.
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"id":4,"fileContent":["1.gif","base64_encoded_content_here"]}' \
https://**put_your_bitrix24_address**/rest/**put_your_user_id_here**/**put_your_webhook_here**/disk.file.uploadversion
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"id":4,"fileContent":["1.gif","base64_encoded_content_here"],"auth":"**put_access_token_here**"}' \
https://**put_your_bitrix24_address**/rest/disk.file.uploadversion
try
{
const response = await $b24.callMethod(
'disk.file.uploadversion',
{
id: 4, // File ID for which a new version is being uploaded
fileContent: [
'1.gif', // First array element — filename
'base64_encoded_content_here' // Second array element — file content in base64
]
}
);
const result = response.getData().result;
console.log(result);
}
catch( error )
{
console.error('Error:', error);
}
try {
$response = $b24Service
->core
->call(
'disk.file.uploadversion',
[
'id' => 4, // File ID for which a new version is being uploaded
'fileContent' => [
'1.gif', // Filename
'base64_encoded_content_here' // File content in base64
]
]
);
$result = $response
->getResponseData()
->getResult();
echo 'Success: ' . print_r($result, true);
} catch (Throwable $e) {
error_log($e->getMessage());
echo 'Error uploading file version: ' . $e->getMessage();
}
BX24.callMethod(
'disk.file.uploadversion',
{
id: 4, // File ID for which a new version is being uploaded
fileContent: [
'1.gif', // First array element — filename
'base64_encoded_content_here' // Second array element — file content in base64
]
}
);
require_once('crest.php');
$result = CRest::call(
'disk.file.uploadversion',
[
'id' => 4, // File ID for which a new version is being uploaded
'fileContent' => [
'1.gif', // Filename
'base64_encoded_content_here' // File content in base64
]
]
);
echo '<PRE>';
print_r($result);
echo '</PRE>';
// client and ctx are already created — see the Go SDK section
res, err := client.Core().Call(ctx, "disk.file.uploadversion", b24.Params{
"id": 4,
"fileContent": []string{"1.gif", "base64_encoded_content_here"},
})
if err != nil {
return fmt.Errorf("disk.file.uploadversion: %w", err)
}
var item struct {
ID b24.ID `json:"ID"`
Name string `json:"NAME"`
Type string `json:"TYPE"`
StorageID b24.ID `json:"STORAGE_ID"`
FileID b24.ID `json:"FILE_ID"`
Size string `json:"SIZE"`
}
if err := json.Unmarshal(res.Result, &item); err != nil {
return fmt.Errorf("parse response: %w", err)
}
fmt.Println(item.ID, item.Name)
FILENAME and FILE_CONTENT Parameters
The telephony.externalCall.attachRecord method accepts the filename and its content in two separate parameters: FILENAME and FILE_CONTENT.
If FILENAME is passed without FILE_CONTENT, the method will return uploadUrl — the file is uploaded via a separate request to this address. This method is suitable for large call recordings.
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"CALL_ID":"externalCall.716f1cb73def9700a23842adf9c4c568.1773130779","FILENAME":"call-001.mp3","FILE_CONTENT":"base64_encoded_content_here"}' \
https://**put_your_bitrix24_address**/rest/**put_your_user_id_here**/**put_your_webhook_here**/telephony.externalCall.attachRecord
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"CALL_ID":"externalCall.716f1cb73def9700a23842adf9c4c568.1773130779","FILENAME":"call-001.mp3","FILE_CONTENT":"base64_encoded_content_here","auth":"**put_access_token_here**"}' \
https://**put_your_bitrix24_address**/rest/telephony.externalCall.attachRecord
try
{
const response = await $b24.callMethod(
'telephony.externalCall.attachRecord',
{
CALL_ID: 'externalCall.716f1cb73def9700a23842adf9c4c568.1773130779',
FILENAME: 'call-001.mp3', // Record filename
FILE_CONTENT: 'base64_encoded_content_here' // Record content in base64
}
);
const result = response.getData().result;
console.log(result);
}
catch( error )
{
console.error('Error:', error);
}
try {
$response = $b24Service
->core
->call(
'telephony.externalCall.attachRecord',
[
'CALL_ID' => 'externalCall.716f1cb73def9700a23842adf9c4c568.1773130779',
'FILENAME' => 'call-001.mp3', // Record filename
'FILE_CONTENT' => 'base64_encoded_content_here' // Record content in base64
]
);
$result = $response
->getResponseData()
->getResult();
echo 'Success: ' . print_r($result, true);
} catch (Throwable $e) {
error_log($e->getMessage());
echo 'Error attaching call record: ' . $e->getMessage();
}
BX24.callMethod(
'telephony.externalCall.attachRecord',
{
CALL_ID: 'externalCall.716f1cb73def9700a23842adf9c4c568.1773130779',
FILENAME: 'call-001.mp3', // Record filename
FILE_CONTENT: 'base64_encoded_content_here' // Record content in base64
}
);
require_once('crest.php');
$result = CRest::call(
'telephony.externalCall.attachRecord',
[
'CALL_ID' => 'externalCall.716f1cb73def9700a23842adf9c4c568.1773130779',
'FILENAME' => 'call-001.mp3', // Record filename
'FILE_CONTENT' => 'base64_encoded_content_here' // Record content in base64
]
);
echo '<PRE>';
print_r($result);
echo '</PRE>';
// client and ctx are already created — see the Go SDK section
res, err := client.Core().Call(ctx, "telephony.externalCall.attachRecord", b24.Params{
"CALL_ID": "externalCall.716f1cb73def9700a23842adf9c4c568.1773130779",
"FILENAME": "call-001.mp3",
"FILE_CONTENT": "base64_encoded_content_here",
})
if err != nil {
return fmt.Errorf("telephony.externalCall.attachRecord: %w", err)
}
var item struct {
ID b24.ID `json:"ID"`
Name string `json:"NAME"`
Type string `json:"TYPE"`
StorageID b24.ID `json:"STORAGE_ID"`
FileID b24.ID `json:"FILE_ID"`
Size string `json:"SIZE"`
}
if err := json.Unmarshal(res.Result, &item); err != nil {
return fmt.Errorf("parse response: %w", err)
}
fmt.Println(item.ID, item.Name)
How to Upload Multiple Files to a Multiple Field
If a field has the "multiple" flag, you can upload several files in a single request. The format depends on the method — refer to the "Multiple Files" column in the How to Choose a Format table.
The FILES field in the crm.timeline.comment.add and log.blogpost.add methods always accepts an array, even when there is only one file. Files from these methods are saved to Drive in a system folder for uploaded files.
Array of "Filename — Base64" Pairs
Pass an array where each item is an array consisting of the filename and the Base64 string.
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"entityTypeId":2,"fields":{"title":"New deal (specifically for REST method examples)","ufCrm_123456":[["green_pixel.png","base64_encoded_content_here"],["blue_pixel.png","base64_encoded_content_here"],["red_pixel.png","base64_encoded_content_here"]]}}' \
https://**put_your_bitrix24_address**/rest/**put_your_user_id_here**/**put_your_webhook_here**/crm.item.add
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"entityTypeId":2,"fields":{"title":"New deal (specifically for REST method examples)","ufCrm_123456":[["green_pixel.png","base64_encoded_content_here"],["blue_pixel.png","base64_encoded_content_here"],["red_pixel.png","base64_encoded_content_here"]]},"auth":"**put_access_token_here**"}' \
https://**put_your_bitrix24_address**/rest/crm.item.add
try
{
const response = await $b24.callMethod(
'crm.item.add',
{
entityTypeId: 2,
fields: {
title: "New deal (specifically for REST method examples)",
ufCrm_123456: [ // Multiple field with an array of files
[
"green_pixel.png", // Filename № 1
"base64_encoded_content_here" // Content of the first file
],
[
"blue_pixel.png", // Filename № 2
"base64_encoded_content_here" // Content of the second file
],
[
"red_pixel.png", // Filename № 3
"base64_encoded_content_here" // Content of the third file
]
]
}
}
);
const result = response.getData().result;
console.log(result);
}
catch( error )
{
console.error('Error:', error);
}
try {
$response = $b24Service
->core
->call(
'crm.item.add',
[
'entityTypeId' => 2,
'fields' => [
'title' => 'New deal (specifically for REST method examples)',
'ufCrm_123456' => [ // Multiple field with an array of files
[
'green_pixel.png', // Filename № 1
'base64_encoded_content_here' // Content of the first file
],
[
'blue_pixel.png', // Filename № 2
'base64_encoded_content_here' // Content of the second file
],
[
'red_pixel.png', // Filename № 3
'base64_encoded_content_here' // Content of the third file
]
]
]
]
);
$result = $response
->getResponseData()
->getResult();
echo 'Success: ' . print_r($result, true);
} catch (Throwable $e) {
error_log($e->getMessage());
echo 'Error adding CRM item: ' . $e->getMessage();
}
BX24.callMethod(
'crm.item.add',
{
entityTypeId: 2,
fields: {
title: "New deal (specifically for REST method examples)",
ufCrm_123456: [ // Multiple field with an array of files
[
"green_pixel.png", // Filename № 1
"base64_encoded_content_here" // Content of the first file
],
[
"blue_pixel.png", // Filename № 2
"base64_encoded_content_here" // Content of the second file
],
[
"red_pixel.png", // Filename № 3
"base64_encoded_content_here" // Content of the third file
]
]
}
}
);
require_once('crest.php');
$result = CRest::call(
'crm.item.add',
[
'entityTypeId' => 2,
'fields' => [
'title' => 'New deal (specifically for REST method examples)',
'ufCrm_123456' => [
[
'green_pixel.png', // Filename № 1
'base64_encoded_content_here' // Content of the first file
],
[
'blue_pixel.png', // Filename № 2
'base64_encoded_content_here' // Content of the second file
],
[
'red_pixel.png', // Filename № 3
'base64_encoded_content_here' // Content of the third file
]
]
]
]
);
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.item.add", b24.Params{
"entityTypeId": 2,
"fields": b24.Params{
"title": "New deal (specifically for REST method examples)",
"ufCrm_123456": []any{
[]string{"green_pixel.png", "base64_encoded_content_here"},
[]string{"blue_pixel.png", "base64_encoded_content_here"},
[]string{"red_pixel.png", "base64_encoded_content_here"},
},
},
})
if err != nil {
return fmt.Errorf("crm.item.add: %w", err)
}
var item struct {
ID b24.ID `json:"ID"`
Name string `json:"NAME"`
Type string `json:"TYPE"`
StorageID b24.ID `json:"STORAGE_ID"`
FileID b24.ID `json:"FILE_ID"`
Size string `json:"SIZE"`
}
if err := json.Unmarshal(res.Result, &item); err != nil {
return fmt.Errorf("parse response: %w", err)
}
fmt.Println(item.ID, item.Name)
Array of value.fileData Objects
Pass an array of objects. Each object contains the value field with the fileData key.
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"fields":{"iblockId":1,"name":"Product example","PROPERTY_1077":[{"value":{"fileData":["blue_pixel.txt","YmFzZSDRgtC10YHRgg=="]}},{"value":{"fileData":["red_pixel.txt","YmFzZSDRgtC10YHRgg=="]}}]}}' \
https://**put_your_bitrix24_address**/rest/**put_your_user_id_here**/**put_your_webhook_here**/catalog.product.add
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"fields":{"iblockId":1,"name":"Product example","PROPERTY_1077":[{"value":{"fileData":["blue_pixel.txt","YmFzZSDRgtC10YHRgg=="]}},{"value":{"fileData":["red_pixel.txt","YmFzZSDRgtC10YHRgg=="]}}]},"auth":"**put_access_token_here**"}' \
https://**put_your_bitrix24_address**/rest/catalog.product.add
try
{
const response = await $b24.callMethod(
'catalog.product.add',
{
fields: {
iblockId: 1,
name: "Product example",
PROPERTY_1077: [
{
value: {
fileData: [
"blue_pixel.txt", // Filename
"YmFzZSDRgtC10YHRgg==" // File content in base64
]
}
},
{
value: {
fileData: [
"red_pixel.txt",
"YmFzZSDRgtC10YHRgg=="
]
}
}
]
}
}
);
const result = response.getData().result;
console.log(result);
}
catch( error )
{
console.error('Error:', error);
}
try {
$response = $b24Service
->core
->call(
'catalog.product.add',
[
'fields' => [
'iblockId' => 1,
'name' => 'Product example',
'PROPERTY_1077' => [
[
'value' => [
'fileData' => [
'blue_pixel.txt', // Filename
'YmFzZSDRgtC10YHRgg==' // File content in base64
]
]
],
[
'value' => [
'fileData' => [
'red_pixel.txt',
'YmFzZSDRgtC10YHRgg=='
]
]
]
]
]
]
);
$result = $response
->getResponseData()
->getResult();
echo 'Success: ' . print_r($result, true);
} catch (Throwable $e) {
error_log($e->getMessage());
echo 'Error adding product: ' . $e->getMessage();
}
BX24.callMethod(
'catalog.product.add',
{
fields: {
iblockId: 1,
name: "Product example",
PROPERTY_1077: [
{
value: {
fileData: [
"blue_pixel.txt", // Filename
"YmFzZSDRgtC10YHRgg==" // File content in base64
]
}
},
{
value: {
fileData: [
"red_pixel.txt",
"YmFzZSDRgtC10YHRgg=="
]
}
}
]
}
}
);
require_once('crest.php');
$result = CRest::call(
'catalog.product.add',
[
'fields' => [
'iblockId' => 1,
'name' => 'Product example',
'PROPERTY_1077' => [
[
'value' => [
'fileData' => [
'blue_pixel.txt',
'YmFzZSDRgtC10YHRgg=='
]
]
],
[
'value' => [
'fileData' => [
'red_pixel.txt',
'YmFzZSDRgtC10YHRgg=='
]
]
]
]
]
]
);
echo '<PRE>';
print_r($result);
echo '</PRE>';
// client and ctx are already created — see the Go SDK section
res, err := client.Core().Call(ctx, "catalog.product.add", b24.Params{
"fields": b24.Params{
"iblockId": 1,
"name": "Product example",
"PROPERTY_1077": []b24.Params{
{
"value": b24.Params{
"fileData": []string{"blue_pixel.txt", "YmFzZSDRgtC10YHRgg=="},
},
},
{
"value": b24.Params{
"fileData": []string{"red_pixel.txt", "YmFzZSDRgtC10YHRgg=="},
},
},
},
},
})
if err != nil {
return fmt.Errorf("catalog.product.add: %w", err)
}
var item struct {
ID b24.ID `json:"ID"`
Name string `json:"NAME"`
Type string `json:"TYPE"`
StorageID b24.ID `json:"STORAGE_ID"`
FileID b24.ID `json:"FILE_ID"`
Size string `json:"SIZE"`
}
if err := json.Unmarshal(res.Result, &item); err != nil {
return fmt.Errorf("parse response: %w", err)
}
fmt.Println(item.ID, item.Name)
Array of fileData Objects
Pass an array of objects, where each object contains the fileData key with the filename and the Base64 string.
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"fields":{"TITLE":"Lead example","UF_CRM_1711610801":[{"fileData":["file1.png","base64_encoded_content_here"]},{"fileData":["file2.png","base64_encoded_content_here"]}]}}' \
https://**put_your_bitrix24_address**/rest/**put_your_user_id_here**/**put_your_webhook_here**/crm.lead.add
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"fields":{"TITLE":"Lead example","UF_CRM_1711610801":[{"fileData":["file1.png","base64_encoded_content_here"]},{"fileData":["file2.png","base64_encoded_content_here"]}]},"auth":"**put_access_token_here**"}' \
https://**put_your_bitrix24_address**/rest/crm.lead.add
try
{
const response = await $b24.callMethod(
'crm.lead.add',
{
fields: {
TITLE: "Lead example",
UF_CRM_1711610801: [
{
fileData: [
"file1.png", // Filename
"base64_encoded_content_here" // File content in base64
]
},
{
fileData: [
"file2.png",
"base64_encoded_content_here"
]
}
]
}
}
);
const result = response.getData().result;
console.log(result);
}
catch( error )
{
console.error('Error:', error);
}
try {
$response = $b24Service
->core
->call(
'crm.lead.add',
[
'fields' => [
'TITLE' => 'Lead example',
'UF_CRM_1711610801' => [
[
'fileData' => [
'file1.png', // Filename
'base64_encoded_content_here' // File content in base64
]
],
[
'fileData' => [
'file2.png',
'base64_encoded_content_here'
]
]
]
]
]
);
$result = $response
->getResponseData()
->getResult();
echo 'Success: ' . print_r($result, true);
} catch (Throwable $e) {
error_log($e->getMessage());
echo 'Error adding lead: ' . $e->getMessage();
}
BX24.callMethod(
'crm.lead.add',
{
fields: {
TITLE: "Lead example",
UF_CRM_1711610801: [
{
fileData: [
"file1.png", // Filename
"base64_encoded_content_here" // File content in base64
]
},
{
fileData: [
"file2.png",
"base64_encoded_content_here"
]
}
]
}
}
);
require_once('crest.php');
$result = CRest::call(
'crm.lead.add',
[
'fields' => [
'TITLE' => 'Lead example',
'UF_CRM_1711610801' => [
[
'fileData' => [
'file1.png',
'base64_encoded_content_here'
]
],
[
'fileData' => [
'file2.png',
'base64_encoded_content_here'
]
]
]
]
]
);
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.lead.add", b24.Params{
"fields": b24.Params{
"TITLE": "Lead example",
"UF_CRM_1711610801": []b24.Params{
{
"fileData": []string{"file1.png", "base64_encoded_content_here"},
},
{
"fileData": []string{"file2.png", "base64_encoded_content_here"},
},
},
},
})
if err != nil {
return fmt.Errorf("crm.lead.add: %w", err)
}
var item struct {
ID b24.ID `json:"ID"`
Name string `json:"NAME"`
Type string `json:"TYPE"`
StorageID b24.ID `json:"STORAGE_ID"`
FileID b24.ID `json:"FILE_ID"`
Size string `json:"SIZE"`
}
if err := json.Unmarshal(res.Result, &item); err != nil {
return fmt.Errorf("parse response: %w", err)
}
fmt.Println(item.ID, item.Name)
How to Pass a File to a Field Linked to Drive
A "file (Drive)" type field stores the ID of an object on Drive. If a method does not accept Base64 in such a field, the upload takes two steps.
-
Upload the file to Drive using the disk.folder.uploadfile or disk.storage.uploadfile method — the file is passed in the fileContent parameter.
-
Take the
IDfrom the response and pass it to the object field. For example, the tasks.task.file.attach method attaches a file that is already stored on Drive to a task.
"File (Drive)" type fields in the CRM are an exception. They accept a fileData object with Base64, and Bitrix24 automatically saves the file to Drive in a system folder for REST files.
Response Content
disk.* methods return a Drive file object: ID, name, size, and download link DOWNLOAD_URL.
{
"result": {
"ID": 9035,
"NAME": "picture.png",
"TYPE": "file",
"STORAGE_ID": "1357",
"FILE_ID": 32895,
"SIZE": "1679",
"DOWNLOAD_URL": "https://your-domain.bitrix24.com/rest/download.json?auth=b8d880690000071b006e2cf2000004f5...",
"DETAIL_URL": "https://your-domain.bitrix24.com/company/personal/user/1269/disk/file/picture.png"
}
}
Methods that upload a file to an object field return the identifier of the created object, not the file. To retrieve the ID of a file and its download links, request the object using a read method — for example, crm.item.get. The file field will return an array of objects.
{
"ufCrm_123456": [
{
"id": 30577,
"url": "https://your-domain.bitrix24.com/bitrix/services/main/ajax.php?action=crm.controller.item.getFile&fileId=30577",
"urlMachine": "https://your-domain.bitrix24.com/rest/crm.controller.item.getFile.json?auth=c2a8ad670000071b..."
}
]
}
These ID will be required when you need to update or delete files.
To download a file using DOWNLOAD_URL or urlMachine, send a separate GET request. Pass the User-Agent, Accept, Accept-Language, and Referer headers according to the rules in How a Request Is Executed. If the HTTP client does not pass these headers or inserts a technical User-Agent, the file may fail to download even if the link is signed correctly.
Limitations When Working with Files
-
GET requests are limited by the URL length — approximately 2048 characters. This is a general limitation of browsers and web servers, not a specific feature of Bitrix24. A Base64 string is almost always longer, so pass files via a POST request.
-
The POST request size in Bitrix24 Cloud is limited by server settings — 2 GB. A file larger than this size will not be processed. If multiple files are passed in a single request and their total size exceeds the limit, the request will be interrupted — pass such files in separate requests. Refer to the size of the Base64 string rather than the original file: the string is approximately one-third longer.
-
In the Self-hosted version, the request size limit is determined by your server settings, not Bitrix24. Check this with your portal administrator.
-
The request execution time limit is 60 seconds for Bitrix24 Cloud. The request will time out if processing takes longer. You can check the execution time in the time object of the response, parameter
duration. -
If the method is executed via a GET request in the address bar or through cURL, the Base64 string must be additionally URL-encoded, otherwise the file will not be read.
Next Steps
-
How to Update and Delete Files — replacing a file, deleting, and retaining other files in a multiple field
-
How to Work with Files — a section overview: field types, linking files to Bitrix24 objects, and core methods
-
Data Encoding — how to pass data in GET requests and cURL