Загрузка файлов
Три способа загрузки фото, от простого к сложному:
- URL в объявлении — передайте ссылки прямо при создании объявления
- Импорт по URL — загрузите фото отдельно, затем привяжите к объявлению
- Signed URL — для загрузки файлов с клиента
URL в объявлении (рекомендуется)
Самый простой способ — передать URL фотографий прямо при создании или обновлении объявления. Рекомендуется добавлять externalFileId для отслеживания:
{
"externalId": "apt-001",
"announcementStatus": "active",
"announcementType": "rent",
"propertyType": "residential",
"propertySecondaryType": "apartment",
"announcementValue": 500,
"files": [
{ "url": "https://placehold.co/1920x1080/jpg?text=Гостиная", "externalFileId": "apt-001-photo-1" },
{ "url": "https://placehold.co/1920x1080/jpg?text=Спальня", "externalFileId": "apt-001-photo-2" },
{ "url": "https://placehold.co/1920x1080/jpg?text=Кухня", "externalFileId": "apt-001-photo-3" }
]
}
Система автоматически загрузит фотографии, оптимизирует их и привяжет к объявлению. При повторной отправке того же externalFileId система использует уже загруженный файл, избегая дублирования.
Импорт по URL
Используйте этот способ, если хотите загрузить фото заранее или управлять ими отдельно от объявлений.
Загрузить одно фото
const response = await fetch('https://crm.rentix.md/api/v1/media/upload-from-url', {
method: 'POST',
headers: {
'Authorization': 'ApiKey YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: 'https://placehold.co/1920x1080/jpg?text=Гостиная',
externalId: 'apt-001-photo-1'
})
});
const result = await response.json();
console.log(`Media ID: ${result.mediaId}, Статус: ${result.status}`);
curl -X POST https://crm.rentix.md/api/v1/media/upload-from-url \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://placehold.co/1920x1080/jpg?text=Гостиная",
"externalId": "apt-001-photo-1"
}'
$data = [
'url' => 'https://placehold.co/1920x1080/jpg?text=Гостиная',
'externalId' => 'apt-001-photo-1'
];
$ch = curl_init('https://crm.rentix.md/api/v1/media/upload-from-url');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: ApiKey YOUR_API_KEY',
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$result = json_decode($response, true);
{
"mediaId": 123,
"status": "pending",
"externalId": "apt-001-photo-1",
"jobId": 456
}
Статус pending означает, что файл поставлен в очередь на загрузку и оптимизацию. Поле jobId позволяет отследить статус обработки.
Bulk-загрузка
Для загрузки нескольких файлов используйте bulk endpoint с операцией upload-from-url:
const response = await fetch('https://crm.rentix.md/api/v1/media/bulk', {
method: 'POST',
headers: {
'Authorization': 'ApiKey YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
operations: [
{ op: 'upload-from-url', url: 'https://placehold.co/1920x1080/jpg?text=Фото+1', externalId: 'apt-001-photo-1' },
{ op: 'upload-from-url', url: 'https://placehold.co/1920x1080/jpg?text=Фото+2', externalId: 'apt-001-photo-2' },
{ op: 'upload-from-url', url: 'https://placehold.co/1920x1080/jpg?text=Фото+3', externalId: 'apt-001-photo-3' }
]
})
});
const result = await response.json();
console.log(`Загружено: ${result.summary.succeeded} из ${result.summary.total}`);
curl -X POST https://crm.rentix.md/api/v1/media/bulk \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"operations": [
{ "op": "upload-from-url", "url": "https://placehold.co/1920x1080/jpg?text=Фото+1", "externalId": "apt-001-photo-1" },
{ "op": "upload-from-url", "url": "https://placehold.co/1920x1080/jpg?text=Фото+2", "externalId": "apt-001-photo-2" }
]
}'
$data = [
'operations' => [
['op' => 'upload-from-url', 'url' => 'https://placehold.co/1920x1080/jpg?text=Фото+1', 'externalId' => 'apt-001-photo-1'],
['op' => 'upload-from-url', 'url' => 'https://placehold.co/1920x1080/jpg?text=Фото+2', 'externalId' => 'apt-001-photo-2']
]
];
$ch = curl_init('https://crm.rentix.md/api/v1/media/bulk');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: ApiKey YOUR_API_KEY',
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
{
"results": [
{ "op": "upload-from-url", "externalId": "apt-001-photo-1", "mediaId": 123, "success": true },
{ "op": "upload-from-url", "externalId": "apt-001-photo-2", "mediaId": 124, "success": true }
],
"summary": { "total": 2, "succeeded": 2, "failed": 0 }
}
Signed URL
Используйте этот способ для загрузки файлов напрямую с клиента или когда файлы недоступны по публичному URL.
Шаг 1. Запросите URL для загрузки
const response = await fetch('https://crm.rentix.md/api/v1/media/request-upload-url', {
method: 'POST',
headers: {
'Authorization': 'ApiKey YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
files: [
{ fileName: 'living-room.jpg', size: 245000, contentType: 'image/jpeg', externalId: 'apt-001-photo-1' }
]
})
});
const result = await response.json();
console.log(`URL загрузки: ${result.upload[0].url}`);
curl -X POST https://crm.rentix.md/api/v1/media/request-upload-url \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"files": [
{ "fileName": "living-room.jpg", "size": 245000, "contentType": "image/jpeg", "externalId": "apt-001-photo-1" }
]
}'
$data = [
'files' => [
['fileName' => 'living-room.jpg', 'size' => 245000, 'contentType' => 'image/jpeg', 'externalId' => 'apt-001-photo-1']
]
];
$ch = curl_init('https://crm.rentix.md/api/v1/media/request-upload-url');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: ApiKey YOUR_API_KEY',
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$result = json_decode($response, true);
{
"uuid": "abc123",
"upload": [
{
"url": "https://storage.googleapis.com/bucket/abc123_living-room.jpg?signature=...",
"generatedFileName": "abc123_living-room.jpg",
"externalId": "apt-001-photo-1"
}
]
}
Шаг 2. Загрузите файл
Отправьте файл PUT-запросом на полученный URL:
curl -X PUT "https://storage.googleapis.com/bucket/abc123_living-room.jpg?signature=..." \
-H "Content-Type: image/jpeg" \
--data-binary @living-room.jpg
Шаг 3. Подтвердите загрузку
Используйте bulk endpoint с операцией confirm-upload:
const response = await fetch('https://crm.rentix.md/api/v1/media/bulk', {
method: 'POST',
headers: {
'Authorization': 'ApiKey YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
operations: [
{
op: 'confirm-upload',
uuid: 'abc123',
generatedFileName: 'abc123_living-room.jpg',
externalId: 'apt-001-photo-1'
}
]
})
});
const result = await response.json();
console.log(`Подтверждено: ${result.summary.succeeded} из ${result.summary.total}`);
curl -X POST https://crm.rentix.md/api/v1/media/bulk \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"operations": [
{
"op": "confirm-upload",
"uuid": "abc123",
"generatedFileName": "abc123_living-room.jpg",
"externalId": "apt-001-photo-1"
}
]
}'
$data = [
'operations' => [
[
'op' => 'confirm-upload',
'uuid' => 'abc123',
'generatedFileName' => 'abc123_living-room.jpg',
'externalId' => 'apt-001-photo-1'
]
]
];
$ch = curl_init('https://crm.rentix.md/api/v1/media/bulk');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: ApiKey YOUR_API_KEY',
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$result = json_decode($response, true);
Привяжите фото к объявлению
После загрузки привяжите фото к объявлению. Есть три способа указать файл:
По internal ID
{
"files": [
{ "id": 123 },
{ "id": 124 }
]
}
По external ID
{
"files": [
{ "externalFileId": "apt-001-photo-1" },
{ "externalFileId": "apt-001-photo-2" }
]
}
По URL (автоимпорт)
{
"files": [
{ "url": "https://placehold.co/1920x1080/jpg?text=Фото+1", "externalFileId": "apt-001-photo-1" },
{ "url": "https://placehold.co/1920x1080/jpg?text=Фото+2", "externalFileId": "apt-001-photo-2" }
]
}
Bulk операции с медиа
Все операции с медиафайлами можно выполнять через единый endpoint POST /media/bulk:
| Операция | Описание |
|---|---|
upload-from-url | Загрузить файл по URL |
confirm-upload | Подтвердить загрузку через signed URL |
link | Привязать external ID к файлу |
unlink | Отвязать external ID |
delete | Удалить файл |
Пример комбинации операций
{
"operations": [
{ "op": "upload-from-url", "url": "https://example.com/new.jpg", "externalId": "new-photo" },
{ "op": "link", "mediaId": 123, "externalId": "old-photo-linked" },
{ "op": "delete", "externalId": "old-photo-to-remove" }
]
}
Обработка ошибок
Ошибка в одной операции не останавливает остальные. Проверяйте success для каждого результата:
{
"results": [
{ "op": "upload-from-url", "externalId": "photo-1", "mediaId": 123, "success": true },
{
"op": "upload-from-url",
"externalId": "photo-2",
"mediaId": null,
"success": false,
"error": {
"statusCode": 400,
"body": {
"error": "Duplicate external ID",
"error_code": "DUPLICATE_EXTERNAL_ID"
}
}
}
],
"summary": { "total": 2, "succeeded": 1, "failed": 1 }
}
Частые ошибки
| Ошибка | Причина | Решение |
|---|---|---|
Duplicate external ID | External ID уже используется | Используйте уникальный ID для каждого файла |
Upload URL expired | Signed URL истёк | Запросите новый URL |
Invalid content type | Неверный формат файла | Используйте JPEG, PNG, WebP или HEIC |
File too large | Файл слишком большой | Уменьшите размер или сожмите |