Медиафайлы

Загрузка файлов

Как загружать фото — через URL в объявлении, импорт по URL или signed URL

Три способа загрузки фото, от простого к сложному:

  1. URL в объявлении — передайте ссылки прямо при создании объявления
  2. Импорт по URL — загрузите фото отдельно, затем привяжите к объявлению
  3. 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}`);
Ответ
{
  "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}`);
Ответ
{
  "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}`);
Ответ
{
  "uuid": "abc123",
  "upload": [
    {
      "url": "https://storage.googleapis.com/bucket/abc123_living-room.jpg?signature=...",
      "generatedFileName": "abc123_living-room.jpg",
      "externalId": "apt-001-photo-1"
    }
  ]
}
URL действителен 30 минут. Загрузите файл до истечения срока.

Шаг 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}`);

Привяжите фото к объявлению

После загрузки привяжите фото к объявлению. Есть три способа указать файл:

По 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 IDExternal ID уже используетсяИспользуйте уникальный ID для каждого файла
Upload URL expiredSigned URL истёкЗапросите новый URL
Invalid content typeНеверный формат файлаИспользуйте JPEG, PNG, WebP или HEIC
File too largeФайл слишком большойУменьшите размер или сожмите
Copyright © 2026