CRM · ИМПОРТ

XML-импорт объектов

Массовое создание и обновление объектов агентства через XML в личном кабинете CRM.

Актуально для HATA XML + профиль YRL (yandex_yrl_hata_v1), 2026-07-30

<?xml version="1.0" encoding="UTF-8"?>
<objects>
  <object external_id="sample-min-001">
    <type_code>apartment</type_code>
    <title>Двухкомнатная квартира, минимальный пример</title>
  </object>
  <object external_id="sample-full-001">
    <type_code>apartment</type_code>
    <title>3-комнатная квартира с ремонтом</title>
    <description>Светлая квартира рядом с метро.</description>
    <price>95000</price>
    <currency>USD</currency>
    <status_code>draft</status_code>
    <visibility>agency</visibility>
    <rooms>3</rooms>
    <images>
      <image>https://example.com/sample-listing-1.jpg</image>
    </images>
  </object>
</objects>

1. Что такое XML-импорт

XML-импорт позволяет CRM-агентству массово создавать и обновлять объекты (объявления) из файла или HTTPS-фида.

Объекты создаются только в рамках текущего агентства (X-Agency-ID / tenant context). Изменить объекты другого агентства нельзя.

Для доступа нужно право objects.import. Наличие objects.update само по себе массовый импорт не открывает.

Политика v1: upsert only — отсутствие объекта в новом фиде не удаляет и не архивирует существующие записи.

2. Поддерживаемые форматы

HATA XML v1 — рекомендуемый формат для полного доступа к возможностям HATA (корень <objects>, элементы <object external_id>).

Поддерживаемый HATA профиль импорта Yandex Realty Language (yandex_yrl_hata_v1) — подмножество официального YRL, адаптированное под Узбекистан.

Это не полная совместимость с Яндекс.Недвижимостью: российские федеральные ограничения могут игнорироваться; HATA не гарантирует приём файла самим Яндексом.

Официальный namespace YRL: http://webmaster.yandex.ru/schemas/feed/realty/2010-06 (документация проверена 2026-07-30).

3. Профиль YRL

  • Корень <realty-feed>, элементы <offer internal-id> → external_id.
  • Минимум: продажа/аренда; квартира, комната, дом, участок, гараж.
  • География через справочники HATA; новые города/районы из XML не создаются.
  • Валюты: UZS, USD. Площадь: м²; сотки → м² (1 сотка = 100 м²) без двойного преобразования.
  • Неизвестные безопасные теги YRL → warning, не пишутся в EAV.
  • Пример: /samples/yandex-yrl-hata-example.xml.

4. XML-фиды по URL

  • CRM: вкладка «XML-фиды» на /objects/xml-import.
  • Расписание: manual | every_6_hours | daily.
  • v1: только публичные HTTPS URL (Basic Auth без encryption key не хранится).
  • Неизменный checksum → статус unchanged, без лишних update.
  • Очередь: RabbitMQ consumer; scheduler: python -m app.object_xml_feed_scheduler.main.

5. Ограничения

  • Максимальный размер файла по умолчанию: 5 МБ (OBJECT_XML_IMPORT_MAX_BYTES).
  • Максимум объектов в файле: 500 (OBJECT_XML_IMPORT_MAX_ITEMS).
  • Кодировка: только UTF-8.
  • Расширение: .xml; MIME: application/xml или text/xml.
  • Одновременно один apply-импорт на агентство; preview (validate) можно запускать параллельно.
  • Актуальные числовые лимиты также отдаёт GET /api2_0/object/imports/config и блок limits_config в ответе validate.

3. Формат XML

Корень: <objects>. Элементы: <object external_id="…">. Namespaces и DTD не поддерживаются.

Если status/visibility не указаны, применяются безопасные значения draft и agency. Отсутствие поля не делает объект публичным.

Неизвестные обычные теги — ошибка. Неизвестные EAV-коды не создаются автоматически.

ПолеОбязательноеТипОписаниеПример
external_id (атрибут)даstringВнешний ID в рамках агентстваagency-sku-123
titleдаstringНазвание объекта2-комн., Чиланзар
type_id или type_codeдаint / stringТип объекта из справочникаapartment
descriptionнетstringОписание
priceнетnumberЦена95000
currencyнетstring(3)ISO-код валютыUSD
status_id / status_codeнетint / stringПо умолчанию draftdraft
visibilityнетenumprivate|agency|public; по умолчанию agencyagency
deal_type_id / deal_type_codeнетint / stringТип сделкиsale
city_id / area_id / street_idнетintЛокация1
address / houseнетstringАдресЧиланзар
latitude / longitudeнетnumberКоординаты41.285
rooms / floor / floors_totalнетintСкалярные характеристики3
total_area / living_area / kitchen_areaнетnumberПлощади78.5
fields/field@codeнетEAVТолько существующие коды полейrenovation
images/imageнетhttps URLДо 30 на объект; SSRF-защитаhttps://…

4. Пример XML

Ниже и в файле /samples/object-xml-import-example.xml — минимальный и расширенный объекты. type_code и EAV-коды должны существовать в вашей базе.

5. Создание и обновление

  • Идентификация: (owning_agency_id, external_id).
  • Новый external_id → создание; существующий своего агентства → обновление.
  • Дубль external_id в одном XML → ошибка валидации.
  • Отсутствие объекта в новом XML ничего не удаляет и не архивирует.
  • Изменение external_id существующего объекта через XML не поддерживается.
  • Повтор одинаковых данных → unchanged; слот повторно не расходуется.
  • Обновление уже активного объекта слот не занимает.

6. Проверка перед импортом

  • Выберите XML → «Проверить файл» (validate).
  • Изучите preview: всего / новых / обновлений / ошибок / нужных и доступных слотов.
  • Исправьте критические ошибки; при listing_limit_reached запуск блокируется целиком.
  • «Запустить импорт» → status queued → polling detail до terminal status.
  • Скачайте CSV-отчёт при необходимости.

7. Статусы импорта

СтатусЗначениеДействие
validatedФайл проверен, объекты не измененыМожно запустить импорт, если can_apply
queuedИмпорт поставлен в очередьДождитесь running
runningИдёт обработкаPolling detail
completedУспешно без ошибок объектовСмотрите отчёт
completed_with_errorsЧасть объектов с ошибкамиСкачайте отчёт, исправьте XML
failedКритический сбой или все ошибкиПовторите после исправления

8. Ошибки

Ошибки объектов смотрите в таблице UI, GET …/errors или CSV report. Номер элемента — xml_index, путь — xml_path.

После исправления загрузите файл снова через validate.

КодПричинаЧто делать
xml_invalidПовреждённый или неверный XMLПроверьте UTF-8, корень <objects>, теги
xml_unsafeDTD/entities/опасная вложенностьУберите DOCTYPE и entity
file_too_largeФайл больше лимитаУменьшите файл (по умолчанию 5 МБ)
too_many_itemsБольше 500 объектовРазбейте файл
validation_failedОшибки в объектахСмотрите таблицу ошибок / отчёт
duplicate_external_idПовтор external_id в файле или конфликтСделайте ID уникальным в файле
listing_limit_reachedНе хватает слотов тарифаСнизьте публичные объекты или повысьте тариф
object_not_ownedexternal_id чужого агентстваИспользуйте свои ID
import_already_runningУже идёт applyДождитесь завершения
import_not_foundНет такого импортаПовторите validate
import_expiredИстёк TTL файлаЗаново проверьте файл
import_not_validatedНеверный статус для applyСначала validate
checksum_mismatchФайл изменилсяПовторите validate
unknown_fieldНеизвестный тегУдалите поле или смотрите контракт
unknown_eav_fieldНеизвестный EAV codeИспользуйте код из справочника
missing_requiredНет обязательного поляДобавьте external_id, title, type
invalid_enumНедопустимое значениеПроверьте visibility/status
type_not_foundТип не найденУкажите существующий type_code/type_id
status_not_foundСтатус не найденУкажите существующий status_code
image_forbiddenЗапрещённый URL изображенияТолько публичный https
image_fetch_failedНе удалось скачать изображениеПроверьте URL; объект всё равно может быть сохранён
redis_unavailableСервис блокировок временно недоступенПовторите позже
queue_unavailableОчередь импорта временно недоступнаПовторите позже

9. Права доступа

Permission: objects.import — для всех API импорта и раздела CRM /objects/xml-import.

По умолчанию выдаётся ролям agency_admin, admin, manager, supervisor, platform_admin.

Скрытие пункта меню на frontend не заменяет проверку на backend (403).

10. Тарифные лимиты

Лимит max_active_listings применяется только к продавцам доски (board sellers). Для типичных CRM-агентств preview показывает applies=false и «Без лимита».

Слот занимают живые public/опубликованные объекты. draft/archived/deleted и другие неактивные статусы слот не занимают.

Если slot_required > available — импорт не запускается частично; код listing_limit_reached.

11. Изображения и безопасность

  • Только https; localhost, private/link-local/reserved IP запрещены.
  • Редиректы перепроверяются; таймаут и лимит размера ответа действуют.
  • Ошибка одного изображения не откатывает весь импорт — пишется warning/ошибка по объекту.

12. API

Все ручки требуют JWT, tenant context и objects.import. Prefix: /api2_0.

  • POST /object/imports/xml/validate — multipart file → preview + import_id (status validated).
  • POST /object/imports/xml — body {import_id} → {import_id, status: queued}; apply в фоне.
  • GET /object/imports — история агентства.
  • GET /object/imports/{id} — детальный статус и счётчики.
  • GET /object/imports/{id}/errors — ошибки по объектам.
  • GET /object/imports/{id}/report — CSV-отчёт.
  • GET /object/imports/config — лимиты для UI.