API DomXML
Машиночитаемая схема: /api/v1/openapi.json (OpenAPI 3.1), интерактивный справочник — /api-reference.
REST API для управления шахматкой: жилые комплексы, квартиры, статусы, фиды. База: https://domxml.ru/api/v1. Для нейросетей есть MCP-сервер с теми же возможностями. Обзор возможностей и сценарии — на странице «API и MCP».
Быстрый старт
- Создайте ключ: аватарка → API и MCP → «Создать ключ», уровень
editor. Скопируйте секрет — он показывается один раз. - Найдите ID ЖК:
curl https://domxml.ru/api/v1/complexes \ -H "Authorization: Bearer dxk_ВАШ_КЛЮЧ" # [{"id": 1234567, "name": "Приречный", "kind": "residential", …}] - Получите объекты ЖК — например, свободные двухкомнатные:
curl "https://domxml.ru/api/v1/complexes/1234567/apartments?rooms=2&status=available" \ -H "Authorization: Bearer dxk_ВАШ_КЛЮЧ" # [{"id": 345, "number": "32", "floor": 5, "price": 7810000, "status": "available", …}] - Поменяйте цену:
curl -X PUT https://domxml.ru/api/v1/complexes/1234567/apartments/345 \ -H "Authorization: Bearer dxk_ВАШ_КЛЮЧ" \ -H "Content-Type: application/json" \ -d '{"price": 7950000}'
Правка сразу видна в панели и на витрине и попадает в журнал ЖК со способом key. Фиды пересобираются сами раз в 3 часа, если в ЖК были изменения; POST …/feeds/{feed}/generate — чтобы пересобрать сейчас.
Аутентификация
Создайте ключ в панели: аватарка → API и MCP → «Создать ключ». Секрет показывается один раз. Передавайте его в заголовке:
curl https://domxml.ru/api/v1/complexes \ -H "Authorization: Bearer dxk_ВАШ_КЛЮЧ"
При создании ключа выбираются:
- Уровень доступа:
readonly— только GET;editor— чтение и изменение;full— плюс удаление. - ЖК: все или выбранные. Ключ с ограничением работает с путями
/complexes/{id}/…своих ЖК, справочниками, фото (/apartment-images/…) и импортом-экспортом Excel — ЖК там сверяется по телу запроса и по строкам файла. Создавать новые ЖК такой ключ не может; импорт файла, где есть чужой или новый ЖК, не выполняется целиком. - Срок: пресеты 1–30 дней или бессрочно. Отзыв в панели действует мгновенно.
Ключом закрыто всегда — только в панели, ответ 403: профиль и вход (/auth), выпуск ключей (/apikeys) и подключений нейросетей (/oauth), обращения в поддержку (/support), уведомления (/notifications), партнёрская программа (/partner), управление доступами к ЖК (любой путь с /access), подключение Битрикс24 (/b24). Каналы публикации — только с отдельным разрешением ключа, а удаляются только в панели (ниже).
Основные эндпоинты
Проекты (ЖК, посёлки, паркинги…), застройщик, корпуса
| Метод | Путь | Описание |
|---|---|---|
| GET | /complexes | Список проектов: свои и те, к которым вам открыли доступ. Вид — поле kind (residential, settlement, parking, commercial, house, resale — виды проектов), площадки фидов, доступные виду, — feedPlatforms |
| POST | /complexes | Создать проект: обязательно name; kind — вид проекта (по умолчанию residential); developer — застройщик: {"name": "…"} — новый, {"fromComplexId": N} — синхронизированный с застройщиком проекта N. Вместе с проектом одной транзакцией создаются застройщик и, только у ЖК, три вида из окон (подробнее) |
| GET | /complexes/{id} | Данные ЖК |
| PUT | /complexes/{id} | Изменить проект (частичное тело). Смена kind проверяется: если в проекте есть то, чего у нового вида не бывает, — 422 (ниже) |
| DELETE | /complexes/{id} | Удалить ЖК в корзину на 7 дней (уровень full, только владелец ЖК); POST /complexes/{id}/restore — вернуть |
| GET, PUT | /complexes/{id}/developer | Застройщик: название, ИНН, ОГРН, сайт, телефон, логотип |
| GET | /developers | Застройщики ваших проектов — выбрать «из ваших» при создании нового (подробнее) |
| GET | /complexes/{id}/readiness | Чек-лист «Что сделать для работы»: реквизиты, контакты, фото, объекты, фид, витрина (подробнее) |
| GET, POST | /complexes/{id}/buildings | Корпуса, очереди посёлка, здания паркинга и коммерции; создать — обязательно name. Назначение purpose (residential, commercial, parking, phase) по умолчанию — по виду проекта; неподходящее виду — 422. У отдельного дома зданий нет |
| GET, PUT, DELETE | /complexes/{id}/buildings/{bid} | Корпус. Удалить можно только пустой |
| GET, POST | /complexes/{id}/window-views | Виды из окон ЖК; …/window-views/domclick-values — допустимые значения Домклика |
| PUT, DELETE | /complexes/{id}/window-views/{vid} | Изменить или удалить вид |
| GET, POST | /complexes/{id}/discounts | Акции; …/discounts/types — типы акций |
| PUT, DELETE | /complexes/{id}/discounts/{did} | Изменить или удалить акцию. Скидка на жильё: value + valueUnit (percent или rub) и target — где действует: info (только описание, цены не меняет; по умолчанию), all, filter (buildings, kinds, rooms, areaMin, areaMax), objects (ids). Цена со скидкой уходит в фиды Домклика, Яндекса, Авито, VK и на витрину (discountPrice в снимке); в Циан — cianActionId из его кабинета |
| POST | /complexes/{id}/discounts/{did}/objects | Добавить (add) или убрать (remove) объекты акции — режим «выбранные объекты» |
| GET | /dictionaries | Допустимые значения справочных полей: отделка, класс, тип дома, состояние корпуса, статусы, вид проекта (complex.kind), тип гаража (apartment.garageType); complex.kindRules — правила видов проекта |
Квартиры
| Метод | Путь | Описание |
|---|---|---|
| GET | /complexes/{id}/apartments | Все объекты ЖК со всеми полями, включая internalId; поле crmBooking — активная бронь клиента CRM. Фильтры: kind (вид объекта), rooms, floor, status, min_price, max_price, min_area, max_area (общая площадь). Ответ — массив целиком, без пагинации |
| GET | /complexes/{id}/apartments/delta | Что изменилось с ревизии since — в том же виде, что список: {"rev", "fullRequired": false, "updated": […], "removed": [ID]}. В removed — удалённые и снятые с публикации объекты. Если журнал ревизию уже не помнит — "fullRequired": true: загрузите список целиком. Текущую ревизию даёт /version |
| POST | /complexes/{id}/apartments | Создать квартиру. complexId в теле не нужен — берётся из пути. Нужно хотя бы одно из полей number, floor, rooms, areaTotal, price, иначе 422 |
| POST | /complexes/{id}/apartments/bulk | Создать до 500 квартир одним запросом: {"apartments": [{…}, …]}. Всё или ничего: при ошибке в любой квартире не создаётся ни одна |
| GET | /complexes/{id}/apartments/{aid} | Одна квартира |
| PUT | /complexes/{id}/apartments/{aid} | Изменить квартиру (частичное тело) |
| DELETE | /complexes/{id}/apartments/{aid} | Удалить объект (уровень full). Куплен клиентом CRM — 409; активная бронь — 409 с crmBooking, повтор с ?force=true снимает бронь и удаляет |
| PUT | /complexes/{id}/apartments/bulk | Массовое изменение: {"apartmentIds": […], "updates": {…}}, до 500 квартир |
| GET | /complexes/{id}/apartments/statuses | Статусы квартир: базовые available, reserved, sold (system: true) и свои статусы застройщика |
| GET | /complexes/{id}/changelog | Журнал ЖК: кто, когда, было и стало и способ (via: panel, key — ключ или подключение нейросети по REST, mcp, excel, feed, crm, support, b24; none — старые записи без пометки). Параметры: entityType (apartment, complex, developer, building, discount, window_view, status), action, days — за сколько дней, userId, via, apartmentId — история объекта, limit (по умолчанию 100, до 500) и offset. Новые записи первыми. Автор — userName и userPublicId, почта не отдаётся. Хранится год. …/changelog/stats?days=30 — сводка по действиям, сущностям и авторам |
Фото и планировки
| Метод | Путь | Описание |
|---|---|---|
| POST | /apartment-images/upload | Загрузить файл: multipart с полями image (файл), complex_id, необязательно apartment_id и image_type (photo | floorplan). Одинаковые файлы не дублируются |
| POST | /apartment-images/bulk-add | Привязать загруженные файлы к квартирам: apartmentIds, imageFileIds, imageType |
| GET | /apartment-images/apartment/{aid} | Фото и планировки квартиры |
Уже загруженные файлы можно привязать и при создании квартиры: поля imageIds и floorPlanIds.
Любую загруженную картинку сервер пережимает сам: не больше 1920 пикселей по большей стороне, JPEG с качеством 85, поворот по EXIF, прозрачный фон — белым, метаданные (в том числе координаты съёмки) удаляются. Исходник — JPEG, PNG или WebP до 40 МБ; повреждённый файл отклоняется с ошибкой 400.
Планировка квартиры — поле floorplanUrl, а если оно пустое, первая привязанная планировка (imageType: "floorplan"). Так её читают снимок (floorPlan), фиды и проверка фида, поэтому заполнять floorplanUrl после bulk-add не нужно.
Ссылка на страницу квартиры для фидов VK Рекламы и Яндекс Директа — поле pageUrl: полный адрес http(s)://… на вашем сайте, до 500 символов. Его берут фиды, где включён «Ваш сайт» (adLinks ЖК), а где его нет — шаблон; пусто (null или "") — снять. В Excel — колонка «Ссылка на страницу» (BF), пустая ячейка ссылку не снимает.
Фиды и импорт
| Метод | Путь | Описание |
|---|---|---|
| GET | /complexes/{id}/feeds | Фиды ЖК: площадка, отбор (selection: all | filter | manual), постоянная ссылка url, counts — сколько объектов попадёт и почему не попали остальные, missing — без чего площадка отклонит фид, overlaps — общие объекты с другими фидами той же площадки, последний выпуск. У площадки может быть несколько фидов (Домклик — один на ЖК), до 20 на ЖК. platforms — площадки, доступные виду проекта |
| POST | /complexes/{id}/feeds | Создать фид: {platform, title?, selection, filter?, apartmentIds?, premises?, adLinks?, complexData?}. filter — kinds, buildingIds, rooms (studio, 1, 2, 3, 4+), priceFrom/To, areaFrom/To, floorFrom/To; manual — только apartmentIds, новые объекты сами не попадают. Фид «все объекты» получает стандартный адрес complex_{id}.xml, если у площадки ЖК ещё нет стандартного фида (выключенный тоже занимает адрес, удаление освобождает); остальные — {площадка}/{код}.xml. complexData — данные ЖК, которые нужны площадке: ID ЖК в её справочнике (yandexBuildingId, cianJkId, avitoDevelopmentId; у посёлка — yandexVillageId, cianKpId) и шаблон адреса страницы объекта objectUrlTemplate для VK и Директа. Пишутся в сам ЖК вместе с фидом (ошибка фида — не пишутся) и общие для всех его фидов; в ответе — complexData после записи. Имена полей — camelCase или snake_case. Собирается сразу — итог в build. Площадка, недоступная виду проекта, — 422 со списком доступных в ctx.allowed |
| POST | /complexes/{id}/feeds/preview | Сколько объектов попадёт — до сохранения (тело как у создания, ?feedId= — правка существующего). complexData учитывается в расчёте, но не записывается |
| GET, PATCH, DELETE | /complexes/{id}/feeds/{feed} | Фид, правка (не присланные поля не меняются, isActive: false — выключить, файл удаляется), удаление. {feed} — ID фида или площадка: тогда её стандартный фид |
| GET | /complexes/{id}/feeds/{feed}/validate, …/logs, …/download | Готовность фида, история выпусков, скачать файл |
| GET | /complexes/{id}/feeds/status | Сводка по стандартным фидам площадок (старый формат) |
| GET | /complexes/{id}/feeds/validate | Проверка готовности: feeds.{площадка} — blocking (фид не соберётся), recommended (стоит поправить), count (объектов в фиде) для всех шести площадок, включённых и нет; errors/warnings — сводно по включённым |
| PUT | /complexes/{id}/feeds/{type}/toggle | Включить или выключить стандартный фид площадки: {"enabled": true} (устаревшее — используйте POST/PATCH …/feeds). Включение не собирает фид сразу — соберёт планировщик или …/generate; PATCH …/feeds/{feed} с isActive: true собирает сразу |
| GET | /complexes/{id}/feeds/object-links | Ссылки рекламных фидов: опубликованные витрины с этим ЖК, шаблон, сколько объектов со своей ссылкой; по vk и direct — настройка и счётчики (stats: в продаже, попадёт в фид, по своей ссылке, по шаблону, на витрину, без ссылки, на другом домене, без фото). Настройка ссылок — у каждого фида VK и Директа своя: adLinks в PATCH …/feeds/{feed} ({"site": true, "showcase": false, "showcaseId": 12}, null — по данным ЖК); здесь — настройка стандартного фида площадки. VK принимает ссылки одного домена — у него включается что-то одно |
| POST | /complexes/{id}/feeds/{feed}/generate | Пересобрать фид: ID фида или площадка (domclick | cian | yandex | avito | vk | direct) — её стандартный фид. Фид должен быть включён, иначе 409; несуществующий ID — 404 |
| GET | /files | Файловое хранилище: картинки и документы с местами использования. category: all | realty (объекты недвижимости) | crm (витрины, виджеты) | unused | system (вложения поддержки: system: true, их id — ID вложения, не файла хранилища, переименовать и удалить нельзя); kind, complexId, q. Ключу, ограниченному списком ЖК, недоступно |
| POST | /files | Загрузить (multipart file, title): картинка сжимается, документ — PDF, Excel, Word, CSV, TXT, XML до 25 МБ, только владельцу. 413 — закончилось место. GET /files/usage — занято и лимит |
| GET, PATCH, DELETE | /files/{id}, /files/{id}/content | Файл, переименование {title}, удаление (используемый — 409 со списком мест, ?force=true — убрать из мест и удалить), скачивание документа |
| GET | /complexes/{id}/files | Для форм ЖК: картинки этого ЖК и файлы хранилища; привязать — imageFileId в imageIds объекта, POST /apartment-images/bulk-add или POST /apartment-images/complex/{id}/link (фото ЖК) |
| GET | /import-export/template | Шаблон Excel для импорта шахматки; ?complex_id=N — шаблон под этот проект (подробнее) |
| POST | /import-export/import/preview, …/execute | Импорт Excel — файл .xlsx (листы «Застройщик», «ЖК», «Корпуса», «Квартиры»; корпус из колонки «Корпус», которого нет в ЖК, создаётся сам): сначала предпросмотр — ошибки и что изменится у каждого объекта (changes: было → стало), затем применение. Предпросмотр без ошибок отдаёт importId — запись по нему идёт в фоне (/import-export/jobs/{id}/execute), файл второй раз не нужен; …/execute с файлом пишет сразу. В warnings — странные значения (этаж выше этажности, координаты вне России, цена за м²). Строки без изменений не трогаются; изменения пишутся в журнал ЖК и расходятся по синхронизированным ЖК, фиды помечаются к пересборке. Права: владелец, администратор или редактор с правом «Импорт» |
| POST | /import-export/feed/preview | Импорт из фида площадки по ссылке ({url, format}, формат domclick, yandex, cian или avito) — разовый, не синхронизация. Сервер скачивает и разбирает фид и показывает тот же предпросмотр, что у Excel, плюс importId и feed: ЖК фида, куда они пойдут, сколько картинок скачается. Не больше 20 проверок в час |
| POST | /import-export/feed/{id}/retarget | Сменить, куда импортировать ЖК фида ({targets: [ID ЖК или null]}) — пересчёт без повторного скачивания |
| POST | /import-export/jobs/{id}/execute | Запустить импорт по importId из предпросмотра (фид или Excel без ошибок): фоновая задача скачивает и сжимает картинки фида, пишет данные (журнал — способ feed, excel или mcp). Ход и итог — GET /import-export/jobs/{id} |
| GET | /import-export/export | Выгрузка шахматки в Excel: ЖК с правом «Выгрузка» (у владельца и администратора — всегда). complex_ids — через запятую, до 200 за раз; ЖК без права — 403, чужой или несуществующий — 404 |
Яндекс, Циан и Авито получают квартиры как новостройку от застройщика. Квартиры без цены или общей площади в эти три фида не попадают.
Фиды для рекламы. vk — каталог недвижимости VK Рекламы (Центр коммерции, собственный формат VK), direct — фид недвижимости Яндекс Директа для товарных объявлений ЕПК и товарных кампаний. В них попадают свободные квартиры со ссылкой на свою страницу (для VK — ещё и с планировкой или фото), а ЖК — отдельной позицией или каталогом. Ссылка берётся из шаблона objectUrlTemplate у ЖК (например, https://site.ru/flats/{number}; подстановки {number}, {id}, {building}), а если он пуст — со страницы квартиры на опубликованной витрине. Без ссылок, города (и для VK — региона и адреса), а для Директа — без названия застройщика фид не собирается: ответ 400 со списком.
Виды проектов
Проект — это ЖК, коттеджный посёлок, паркинг, бизнес-центр, отдельный дом или вторичка агентства. Вид задаёт поле kind проекта: от него зависят объекты, которые в нём заводятся, назначения зданий и площадки фидов.
kind | Что внутри | Здания | Площадки фидов |
|---|---|---|---|
residential — жилой комплекс | квартиры и апартаменты (flat), коммерция, машиноместа, кладовые | корпуса: residential, commercial, parking | все шесть: Домклик, Яндекс Недвижимость, Циан, Авито, VK Реклама, Яндекс Директ |
settlement — коттеджный посёлок | участки, дома, таунхаусы, коммерция | очереди (phase) и любые другие | все, кроме Домклика |
parking — паркинг и гаражи | машиноместа, гаражи (garage), кладовые | только parking | VK Реклама и Яндекс Директ |
commercial — коммерческая недвижимость | помещения и машиноместа | commercial, parking | VK Реклама и Яндекс Директ |
house — отдельный дом | один дом с участком (house) | нет | Яндекс Недвижимость, Циан, Авито, Яндекс Директ |
resale — вторичка агентства или частного риэлтора | квартиры, комнаты (room), дома, таунхаусы, участки, гаражи, машиноместа, кладовые, коммерция — у каждого свой адрес | нет | Яндекс Недвижимость (эту же ссылку берут Домклик и Move), Циан, Авито, VK Реклама, Яндекс Директ |
- При создании вид передаётся в
POST /complexes: код или подпись изGET /dictionaries(complex.kind). Без поля —residential. В ответахGET /complexesиGET /complexes/{id}—kindиfeedPlatforms. - Смена вида —
PUT /complexes/{id}сkind. Отказ —422сloc: ["body", "kind"]и перечнем причин: в проекте есть объекты другого вида, объектов больше, чем допускает вид (у дома — один), есть здания с неподходящим назначением, каталог проектов домов не у посёлка или включены фиды площадок, недоступных новому виду (выключите или удалите их). - Отдельный дом — один объект. Второй объект в проекте
houseне создаётся — ни в REST (в том числе…/apartments/bulk), ни в MCP, ни из Excel:422«В проекте «Отдельный дом» — один дом…». Каждый дом — своим проектом со своим адресом; несколько домов в одном месте ведите коттеджным посёлком. - Вид объекта по проекту. Объект вида, которого в проекте не бывает (гараж в ЖК, квартира в паркинге), —
422с перечнем допустимых видов. Еслиkindобъекта не прислан, у паркинга создаётся машиноместо, у коммерческой недвижимости — помещение, у дома — дом. - Площадки. Паркинг и коммерция вне ЖК уходят только в VK Рекламу и Яндекс Директ: Домклик, Яндекс Недвижимость, Циан и Авито принимают их только в составе ЖК из своего каталога новостроек. Посёлок и дом — без Домклика, дом — ещё и без VK (VK нужно от трёх объектов в каталоге). Фид недоступной площадки не создать:
422сloc: ["body", "platform"]иctx.allowed— при создании, предпросмотре и правке фида, в…/feeds/{type}/toggleи во флагахdomclickEnabled,cianEnabled,yandexEnabledпроекта. - Нежилое по умолчанию. У паркинга и коммерции оно и есть товар: при создании проекта включено для VK и Директа (
premisesFeeds), а новый фид безpremisesполучает всё, что площадка принимает из видов проекта. - Сводка правил —
GET /dictionaries, ключcomplex.kindRules: по каждому видуlabel,objectKinds,maxObjects,buildingPurposes,feedPlatforms,premisesFeeds.
Паркинг и коммерция внутри ЖК остаются в ЖК — зданиями с назначением parking или commercial — и уходят на все площадки, кроме Домклика.
Новый проект: застройщик, готовность, шаблон Excel
Те же ручки, что у мастера «Добавить» в панели: проект с застройщиком — одним запросом, затем объекты из Excel по шаблону проекта и чек-лист готовности.
curl -X POST https://domxml.ru/api/v1/complexes \
-H "Authorization: Bearer dxk_ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{"name": "Паркинг на Ленина", "kind": "parking", "city": "Казань",
"developer": {"name": "ООО «СЗ Восток»"}}'
# 201 {"id": 1234590, "kind": "parking", "feedPlatforms": ["vk", "direct"], …}
developerвPOST /complexes:{"name": "…"}— новый застройщик с этим названием (ИНН и реквизиты — потом,PUT …/developer);{"fromComplexId": N}— застройщик синхронизирован с застройщиком проекта N, как…/developer/sync-from: правка реквизитов расходится по всем проектам с ним. Проект N должен быть доступен вам на правку. Без поля — заглушка «Застройщик {название}», как раньше. Иное значение —422. Ключ, ограниченный списком ЖК, проекты не создаёт.GET /developers— застройщики проектов, которые вы можете править, без повторов (по ИНН, без ИНН — по названию) и без заглушек:{"developers": [{"complexId": 12, "complexName": "Заречье", "name": "ООО «СЗ Восток»", "inn": "1655123456", "projects": 3, "complexIds": [12, 40, 41]}]}complexId— проект-источник: его передают какdeveloper.fromComplexId. Ключу, ограниченному списком ЖК, —403.GET /complexes/{id}/readiness— «Что сделать для работы»:{complexId, kind, done, total, ready, items}, у каждого пунктаkey,title,done,hintиsection— раздел панели. Пункты:developer— название застройщика не заглушка и ИНН из 10 или 12 цифр;contacts— город и телефон отдела продаж (или застройщика) из 10 цифр;photos— фото проекта;objects— объекты в продаже;feed— последний выпуск хотя бы одного включённого фида успешен и не пуст;showcase— опубликованная витрина с этим проектом. Названия и подсказки — по виду проекта.GET /import-export/template?complex_id=N— шаблон Excel под проект: без листов «Застройщик» и «ЖК» (данные проекта правятся в панели, файл их не перезапишет), лист «Корпуса» — по виду (у отдельного дома его нет), на листе «Квартиры» — примеры объектов этого вида с ID проекта. Заполненный файл загружается обычным импортом (/import-export/import/preview).
Виды объектов, гаражи и посёлки
Квартиры, коммерция, машиноместа, кладовые, гаражи, участки и дома — объекты одного списка /complexes/{id}/apartments. Вид задаёт поле kind, по умолчанию flat. Какие виды можно завести, зависит от вида проекта (kind у самого проекта):
| Проект | Виды объектов |
|---|---|
residential — жилой комплекс | flat — квартира, commercial — коммерческое помещение, parking — машиноместо, storage — кладовая |
settlement — коттеджный посёлок | plot — участок, house — дом с участком, townhouse — таунхаус, commercial |
parking — паркинг и гаражи | parking, garage — гараж, storage |
commercial — коммерческая недвижимость | commercial, parking |
house — отдельный дом | один house |
resale — вторичка | flat, room — комната, house, townhouse, plot, garage, parking, storage, commercial |
Вид, который не подходит проекту, отклоняется с 422. Отобрать объекты одного вида — GET …/apartments?kind=parking. Справочные поля принимают код или подпись из GET /dictionaries.
- Нежилое (
commercial,parking,storage):commercialUse(office, free, retail, catering, warehouse),entranceType(street, yard),separateEntrance,vat(included, not_included, none),parkingType(underground, multilevel, covered, open),secured. - Гараж (
garage, только в проектеparking):garageType—brick(кирпичный),concrete(железобетонный),metal(металлический),box(бокс в ГСК или паркинге);secured— охрана. Площадь, цена и этаж — общие поля; этаж у гаража необязателен: пусто — отдельно стоящий, −1, −2 — подземные уровни. В Excel — колонка BG «Тип гаража» листа «Квартиры». В VK Рекламу и Яндекс Директ гараж уходит как машиноместо. - Участки, дома, таунхаусы:
landArea— площадь участка в м²,cadastralNumber,landCategory(settlements, agricultural, other),landUse(izhs, lph, gardening, dnp, farm),utilities— коммуникации{"gas", "electricityKw", "water", "sewerage"},saleMode(plot_only, with_contract, both — без подряда, только с подрядом, с подрядом или без),wallMaterial,houseStage(ready, construction, to_order),builtYear,street,houseProjectId— проект дома из каталога посёлка,planShape— контур на генплане. Площадь дома —areaTotal, этажность —totalFloors. - Вторичка (проект
resale): адрес у каждого объекта —region,city,district,street,houseNumber(полныйaddressсоберётся сам) илиaddressцеликом;latitude,longitude;flatNumber— номер квартиры: уходит только в фиды (площадки проверяют его при модерации), в снимок и на витрину — нет;metro— до 5 станций[{"name", "minutes", "by": "foot" | "transport"}]; дом —houseType(brick, panel, monolith, monolith-brick, block, wood, stalin),passengerLifts,cargoLifts,garbageChute,builtYear;renovation(none, cosmetic, euro, design, needs_repair),saleKind(free, alternative),haggle,ownersCount,ownershipYears; комната —rooms(всего в квартире),roomsOffered(в продаже),flatArea(площадь квартиры;areaTotal— площадь комнаты);roomLayout(isolated, adjoining, mixed),commercialParking(none, street, building);internalId— внешний ID (ID объявления в вашей CRM, по нему импорт фида обновляет объект). Номер объекта — номер лотаA-0001: у нового объекта его можно не передавать. Список фильтруется по?city=и?agent=. Договор, комиссия, цена «на руки» и собственники объекта по API-ключу недоступны (пути…/listingи…/owners— только из панели); назначают агента и собственников тоже в панели. Имя и рабочий телефон ответственного агента публикуются с объектом — в фидах и в снимке. - Посёлок — поля ЖК:
highwayиdistanceKm— шоссе и расстояние от города,settlement— описание и значения по умолчанию для участков:{"landCategory", "landUse", "utilities", "security", "roads", "feeMonthly"}; ID в справочниках площадок —yandexVillageId,cianKpId. Очереди посёлка — корпуса с назначениемphase.
| Метод | Путь | Описание |
|---|---|---|
| GET, POST | /complexes/{id}/house-projects | Каталог проектов домов посёлка: name, area, floors, bedrooms, bathrooms, wallMaterial, width, length, minLandArea — минимальный участок, buildMonths, description, prices — цена по вариантам готовности {"box", "warm", "whitebox", "turnkey"}, images — до 50 картинок ({"url", "type": "render" | "plan"}), isActive, sortOrder |
| GET, PUT, DELETE | /complexes/{id}/house-projects/{pid} | Проект, правка, удаление |
Что уходит в фиды. Квартиры попадают во все фиды. Участки, дома и таунхаусы — во все, кроме Домклика. Нежилое — только туда, где оно отмечено у фида (premises в POST/PATCH …/feeds) и где площадка его принимает: Яндекс и Авито — коммерция и машиноместа, Циан — коммерция, машиноместа и кладовые, VK — коммерция, машиноместа, кладовые и гаражи, Директ — машиноместа и гаражи. Какие площадки вообще доступны проекту — по его виду (выше). Прежнее поле ЖК premisesFeeds ({"yandex": ["commercial", "parking"]}) по-прежнему принимается и меняет стандартные фиды площадок; для новых интеграций используйте premises у фида.
В снимке и дельтах у объекта есть kind, у участков, домов и таунхаусов — ещё landArea, street, saleMode, houseStage, planShape (в профиле full — и остальные поля посёлка), а у ЖК-посёлка — блок complex.settlement: генплан, шоссе, значения по умолчанию и каталог проектов домов. У объектов вторички — address, city, district, lat, lon, в профиле full — ещё метро, дом, ремонт, сделка, комнаты и agent (имя и рабочий телефон ответственного, как в объявлениях); номера квартиры в снимке нет.
Поля и типы
Имена полей принимаются и в camelCase (areaTotal), и в snake_case (area_total). Отсутствующее поле не меняется, null очищает значение.
- Типы проверяются. Значение не того типа, слишком длинная строка или число вне диапазона — ответ 422 с именем поля в
loc. Число в строковом поле принимается как текст ("entrance": 1), число в строке — как число ("price": "5000000"), пустая строка в числовом поле — какnull. - Корпус задаётся через
buildingIdи должен принадлежать этому ЖК. Название корпуса подставляется вbuildingсамо. - Часовой пояс ЖК (
timezone) — смещение от UTC:+5,UTC+5,+05:00, или IANA-имя пояса России (Asia/Yekaterinburg). Хранится как+5. Если не передан, определяется поregionилиcity, иначе+3. - Срок сдачи задаётся у корпуса (
builtYear,readyQuarter1–4) и у ЖК (completionYear,completionQuarter). У корпуса без срока берётся срок ЖК. - ID в справочниках площадок нужны, чтобы объявления привязались к ЖК и корпусу: у ЖК —
yandexBuildingId,cianJkId,avitoDevelopmentId, у корпуса —yandexHouseId,cianHouseId,avitoDevelopmentId. Справочники: Яндекс (3-й и 7-й столбцы), Циан, Авито (ID корпуса; ID ЖК — только если корпусов нет). - Справочные поля —
finishing,classType,buildingType,buildingState— принимают код, подпись или синоним изGET /dictionaries. Незнакомое значение сохраняется, но площадки его не примут:/feeds/validateоб этом предупредит.
Одно поле в разных местах
REST управляет данными, снимок — публичный контракт для сайтов с короткими именами и своей версией (contract), инструменты MCP принимают аргументы в snake_case.
| REST | Снимок и дельты | MCP |
|---|---|---|
areaTotal | area | area_total |
pricePerMeter | pricePerM2 — если не задана, считается как цена / площадь | — |
акции ЖК (/discounts) | discountPrice, discountTitle — цена по действующей акции и её название; price — без скидки. В complex.discounts — только идущие сегодня, с датой until | — |
entrance | section | entrance |
building, buildingId | building, buildingId | building |
rooms, isStudio, euroPlan | rooms, roomsKind | rooms |
floorplanUrl | floorPlan (профиль full) | — |
internalId | не публикуется | — |
roomsKind — вид планировки одной строкой: studio — студия, euro2, euro3… — евроформат (euroPlan: true, цифра — значение rooms), 1, 2, 3… — классическая, число комнат.
internalId в снимок не попадает: снимок же отдаёт публичный канал витрины, а внутренние номера наружу не уходят. Для сопоставления храните id квартиры DomXML или берите internalId из GET /complexes/{id}/apartments.
В снимке у каждого корпуса (complex.buildings) есть completionYear и completionQuarter — срок сдачи корпуса или ЖК.
Синхронизация шахматки: версия, снимок, изменения
Чтобы держать шахматку на своём сайте в актуальном состоянии, не нужно скачивать её целиком. Сначала спросите версию — это одна строка из базы, — и качайте данные, только если она изменилась.
| Метод | Путь | Описание |
|---|---|---|
| GET | /complexes/{id}/version | Версия ЖК: rev, время изменения, счётчики по статусам, ссылка на снимок |
| GET | /complexes/{id}/snapshot | Снимок целиком: profile=short|full, rev=N |
| GET | /complexes/{id}/changes | Что изменилось: since=N, profile=short|full — изменённые (items) и удалённые (deleted) лоты в формате снимка |
Версия ЖК растёт при любом изменении, которое видно покупателю: цена, статус, площадь, фотографии, корпуса, акции, данные самого ЖК. Служебные правки её не двигают.
# 1. дёшево узнаём, изменилось ли что-нибудь
curl -H "Authorization: Bearer dxk_КЛЮЧ" \
https://domxml.ru/api/v1/complexes/1234567/version
# {"rev": 42, "changedAt": "...", "apartments": {"available": 180, "total": 344},
# "snapshotUrl": "/api/v1/complexes/1234567/snapshot?rev=42"}
# 2. если rev вырос — забираем только изменения
curl -H "Authorization: Bearer dxk_КЛЮЧ" \
"https://domxml.ru/api/v1/complexes/1234567/changes?since=41"
# 3. или снимок целиком: адрес с rev неизменяем, его можно кэшировать навсегда
curl -H "Authorization: Bearer dxk_КЛЮЧ" \
"https://domxml.ru/api/v1/complexes/1234567/snapshot?rev=42"
Надёжнее всего сверять rev из /version с сохранённым у себя: совпал — ничего не качать. Адрес snapshotUrl с ревизией неизменяем, его можно кэшировать навсегда. Снимок отдаётся и с заголовком ETag (если ответ пришёл сжатым, nginx помечает его как слабый: W/"…") — его можно вернуть в If-None-Match как есть.
complexChanged: true в ответе /changes значит, что менялись данные самого ЖК — например, описание, корпуса или акции. Их в дельте нет: перечитайте блок complex из снимка. Изменения объектов при этом приходят как обычно, в items и deleted.
Дельта с profile=full отдаёт квартиры в том же виде, что снимок, вместе с images и floorPlan.
Журнал изменений хранится 30 дней и минимум 50 ревизий. Если запрошенная версия уже забыта, ответ придёт с "fullRequired": true — значит, нужно перекачать снимок целиком.
Публичное API виджета и витрины
Этот раздел — для кода, который работает в браузере посетителя: сам виджет, витрина или ваш скрипт на сайте. Авторизации нет, вместо неё — ключ канала dxp_, который создаётся в панели вместе с виджетом или витриной. Ключ виден в исходном коде страницы и секретом не является: доступ ограничивают список разрешённых доменов и лимиты запросов.
| Метод | Путь | Описание |
|---|---|---|
| GET | /api/public/v1/{ключ}/version | Версия канала и счётчики по каждому ЖК |
| GET | /api/public/v1/{ключ}/apartments | Снимок канала: profile=short|full, v=версия |
| GET | /api/public/v1/{ключ}/changes | Изменения: since=8 или since=1234567:8,1234568:3 |
| POST | /api/public/v1/{ключ}/leads | Заявка из формы — сразу клиентом в CRM |
fetch('https://domxml.ru/api/public/v1/dxp_КЛЮЧ/version')
.then(r => r.json())
.then(v => fetch(`https://domxml.ru/api/public/v1/dxp_КЛЮЧ/apartments?v=${v.version}`))
.then(r => r.json())
.then(data => console.log(data.complexes[0].apartments.length));
Ограничения: 240 запросов в минуту с одного адреса и 1200 в минуту на канал, сверх — 429. Если канал выключен или удалён, ответ — 404: по ключу нельзя узнать, что витрина существует, но скрыта.
Домены. Если у канала задан список доменов, запрос должен прийти с одного из них: сервер смотрит заголовок Origin, а без него — Referer. Браузер присылает их сам, а запрос без обоих заголовков — curl или ваш сервер — получит 403 «Этот виджет не разрешён на текущем домене». Для проверки из терминала передайте заголовок явно:
curl https://domxml.ru/api/public/v1/dxp_КЛЮЧ/version \ -H "Origin: https://ваш-сайт.ru"
Канал с пустым списком доменов отвечает любому сайту и запросам без заголовков. Серверу, который синхронизирует шахматку, удобнее REST API с ключом dxk_ (выше): там проверки домена нет.
Заявка с сайта
Форма на вашей странице может отправлять заявку тем же ключом — она попадёт в CRM как клиент со статусом по умолчанию и источником «Виджет». Обязательны имя и телефон; всё остальное по желанию.
fetch('https://domxml.ru/api/public/v1/dxp_КЛЮЧ/leads', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: 'Пётр',
phone: '+7 917 000-11-22',
apartmentId: 96, // из снимка, необязательно
comment: 'Перезвоните после 18',
utm: { utm_source: 'yandex' },
ft: Date.now() - formOpenedAt, // сколько форма была открыта, мс
company: '' // ловушка для ботов: поле должно остаться пустым
})
}).then(r => r.json());
Ответ — {"ok": true}. Он одинаков и для новой карточки, и когда человек уже писал с этого телефона: во втором случае заявка ложится записью в его карточку, а не создаёт дубль. По ответу нельзя проверить, есть ли телефон в вашей базе.
Два поля нужны против ботов. company прячут от человека стилями — если оно заполнено, заявка тихо отбрасывается. ft — сколько миллисекунд форма была открыта: меньше полутора секунд считается автоматической отправкой. В обоих случаях ответ тот же {"ok": true}, чтобы по нему нельзя было подобрать обход. Лимиты: 10 заявок в час с одного адреса и 5 в сутки с одного телефона, дальше — 429.
Если в настройках канала включена галочка согласия, передавайте consent: true — иначе придёт 400. Вместе с заявкой сохраняются метки рекламы, адрес страницы и текст согласия, который видел посетитель.
Каналы публикации
Виджеты и витрины создаются в панели, но ими же можно управлять по API — например, завести по виджету на каждый ЖК скриптом. Канал принадлежит проекту CRM: собирается из его ЖК, заявки с него приходят в его CRM.
| Метод | Путь | Описание |
|---|---|---|
| GET | /channels?crm={id} | Каналы проекта CRM с кодом вставки, сам проект (crm: publicId, name, canPublish) и его ЖК (complexes). Без crm — первый проект, где есть право «Настройка витрины» |
| POST | /channels?crm={id} | Создать: kind (widget | showcase), complexIds — только ЖК этого проекта, template |
| GET | /channels/{id} | Канал целиком: настройки, ЖК, домены, статус |
| PATCH | /channels/{id} | Настройки, оформление, блоки, домены, состав ЖК — всё сразу |
| PATCH | /channels/{id}/design | Только оформление: accent, mode, radius |
| PATCH | /channels/{id}/blocks | Только блоки витрины, включая квиз |
| PATCH | /channels/{id}/form | Только форма заявки: поля, тексты, согласие |
| PATCH | /channels/{id}/quiz | Квиз на витрине: quizId — квиз кнопки и адреса /quiz, floatingQuizId — плавающий чат, on, title — подпись кнопки (квизы) |
| PATCH | /channels/{id}/domains | Только список доменов, где разрешена вставка |
| GET | /channels/schema | Допустимые виды, пресеты, блоки и значения настроек |
| GET | /channels/{id}/embed | Код вставки и ссылки: предпросмотр, витрина |
| GET | /channels/{id}/stats | Показы, заявки и конверсия за 30 дней |
| GET | /channels/{id}/log | Кто, когда и через что менял канал |
| POST | /channels/{id}/publish | Опубликовать |
| POST | /channels/{id}/unpublish | Снять с публикации |
| DELETE | /channels/{id} | Удалить канал — только в панели (вставка на сайте перестаёт работать) |
Узкие ручки безопаснее широкого PATCH: скрипт, который раз в месяц меняет акцентный цвет, не затрёт блоки витрины. Что можно прислать в каждое поле, отвечает /channels/schema.
Ключу нужно отдельное разрешение. Управление каналами не входит в «Чтение и редактирование»: витрина видна всему интернету, и ключ синхронизации цен не должен её трогать. При создании ключа включите «Управление витриной и виджетами», а чтобы ключ мог ещё и включать канал — подопцию «и публиковать». Без них придёт 403 с объяснением, чего не хватает. Удалять каналы ключом нельзя никогда — только в панели.
Сотрудникам застройщика права выдаются в CRM → Настройки → Команда: «Витрина» — собирать и менять каналы, «Публикует» — включать их. Маркетолог собирает, руководитель публикует.
В ответе приходят embedCode — готовая строка для вставки на сайт, previewUrl — адрес предпросмотра, apiUrl — корень публичного API канала, stats — показы и заявки за 30 дней и updatedAt — когда канал последний раз меняли или включали.
Новый канал создаётся выключенным: сначала предпросмотр, потом публикация отдельным вызовом. Так неудачная автоматическая настройка не попадёт в интернет сама.
Квиз — отдельная запись проекта CRM (ниже), витрина на неё ссылается: quizId — кнопка и адрес /quiz, floatingQuizId — плавающий чат на страницах витрины. on: true у витрины без квиза заводит ей квиз со стандартным набором шагов. Кнопка и /quiz работают только у опубликованного квиза того же проекта; иначе адрес /quiz отвечает 404 и пропадает из карты сайта витрины.
Свой домен витрины задаётся тем же полем domains, что и список доменов виджета: витрина открывается по нему, как только домен направлен на сервис (DNS и сертификат подключает поддержка).
Для витрины (kind: "showcase") обязателен slug — адрес вида v.domxml.ru/{slug}. Оформление блоков лежит в blocks: незаполненные поля считаются из карточки ЖК, поэтому пустую строку слать не нужно — она перекроет умолчание.
Опубликовать витрину не получится, пока не заполнены застройщик и ИНН в карточке ЖК, ссылка на проектную декларацию (blocks.legal.declarationUrl) и ссылка на политику обработки персональных данных (settings.policyUrl): по 214-ФЗ и закону о рекламе они обязательны.
Квизы и чат-боты
Квиз — запись проекта CRM, как фид: создаёте, настраиваете, получаете постоянную ссылку https://v.domxml.ru/q/{code} и код вставки на сайт. Режим steps показывает сценарий по шагам, chat — диалогом чат-бота; заявки, статистика и вставка у них общие. До 20 квизов на проект CRM. Права и разрешения ключа — как у каналов: «Управление витриной и виджетами», публикация — подопцией «и публиковать»; удаление — только в панели. Обзор для маркетолога — страницы квиза и чат-бота.
| Метод | Путь | Описание |
|---|---|---|
| GET | /quizzes?crm={id} | Квизы проекта, лимит, проект (crm: publicId, name, canPublish, customSteps) и его ЖК (complexes) |
| GET | /quizzes/catalog?crm={id}&complexIds=1,2 | Что можно выбрать для этих проектов: шаги, наборы, блоки чата, закрытия, значки, раскладки, темы, лимиты, текст про свои вопросы |
| POST | /quizzes?crm={id} | Создать — выключенным; complexIds обязательно |
| GET | /quizzes/{id} | Квиз целиком: поля, url, embedCode, inlineCode, liveComplexIds, статистика за 30 дней |
| PATCH | /quizzes/{id} | Только присланные поля; объекты сливаются с прежними, null у поля — убрать |
| POST | /quizzes/{id}/publish | Опубликовать: нужны живые проекты и ссылка на политику обработки ПД |
| POST | /quizzes/{id}/unpublish | Снять: ссылка показывает заглушку, вставка не работает |
| GET | /quizzes/{id}/embed | Ссылка и код вставки: плавающая кнопка и блок |
| GET | /quizzes/{id}/stats?days=30 | Воронка по дням (1–365 дней) |
| GET | /quizzes/{id}/log | Кто, когда и через что менял квиз (последние 100) |
| GET | /quizzes/{id}/preview | HTML предпросмотра — и у выключенного квиза; ?embed=1 — окно чата. Заявка из предпросмотра не уходит |
| POST | /quizzes/{id}/preview | Предпросмотр черновика: тело — несохранённые поля (как у PATCH, те же проверки), страница собирается без записи |
| POST, DELETE | /quizzes/{id}/images/{slot} | Картинка: cover, background или avatar |
| DELETE | /quizzes/{id} | Удалить — только в панели |
Поля
| Поле | Что это |
|---|---|
title | Название в панели и в ленте CRM («Заявка из квиза: …»), до 120 знаков |
complexIds | Проекты: свои ЖК проекта CRM и ЖК агентских программ, до 20. Один — квиз привязан к нему, несколько — первый шаг «Какой интересует», заявка уходит в выбранный (при «Пока не знаю» — в первый) |
mode | steps — пошагово, chat — чат-бот |
preset | Набор шагов для steps: short, standard, detailed — свой у каждого вида проекта; у нескольких видов наборы объединяются |
blocks | Блоки диалога для chat по порядку: choose, object, rooms_budget, area_floor, timing_pay, mortgage, invest, question. Пусто — набор по умолчанию для вида проекта |
steps | Свои шаги вместо набора: {"key"} из каталога или {"key": "c_…", "custom": true, "type": "single"|"multi", "text", "options": [2–8], "optional"}, до 12. Только если у проекта их включила поддержка (customSteps), иначе 400 |
closing | {type, title, bonus, minutes} — закрытие, ниже |
content | {heading ≤120, subheading ≤300, advantages, cover, background}; advantages — до 4 пунктов {icon, text ≤80}, значки: percent, key, home, shield, clock, gift, star, check, ruble, map, car, tree |
design | {theme: light|dark|auto, color: "#RRGGBB", layout: cover-left|center|fullscreen, start: auto|button, startStyle: solid|soft|outline|arrow|pulse, startText: ≤40} — start: button: квиз открывается кнопкой |
bot | {name ≤40, avatar} — для чата; по умолчанию — название проекта и логотип застройщика |
floating | Плавающая кнопка: {on, text ≤40, position: right|left, delay: 0–120} (секунды); цвет — design.color |
settings | {policyUrl, consentCheckbox, consentText, phone}; чего нет — берётся из витрины, где стоит квиз |
domains | Сайты, где разрешена вставка; пусто — любой сайт. Домены витрин с этим квизом разрешены всегда |
metrikaId | Номер счётчика Яндекс Метрики для целей |
Ссылки на картинки и политику — https:// или свой путь /uploads/…. Неизвестное поле, блок или шаг, который не подходит виду проекта, — 400 с объяснением, а не молчаливый пропуск.
curl -X POST "https://domxml.ru/api/v1/quizzes?crm=CRM_ID" \
-H "Authorization: Bearer dxk_КЛЮЧ" -H "Content-Type: application/json" \
-d '{
"title": "Подбор квартиры — реклама VK",
"complexIds": [1234567],
"mode": "steps",
"preset": "short",
"closing": { "type": "bonus_form", "bonus": "Скидка 2% при бронировании" },
"content": { "advantages": [{ "icon": "key", "text": "Ключи в 2027 году" }] },
"design": { "theme": "auto", "color": "#2E5BFF", "layout": "cover-left" },
"settings": { "policyUrl": "https://ваш-сайт.ru/privacy" }
}'
Закрытия
closing.type | Что видит человек |
|---|---|
pick_form | Подборка до трёх объектов и форма: имя, телефон. По умолчанию |
bonus_form | То же с бонусом; bonus обязателен (до 120 знаков) и закрепляется за заявкой |
callback | «Перезвоним за N минут»: телефон, имя необязательно, без подборки; minutes — 5–240 |
messenger | Подборка и выбор, куда прислать: Telegram, WhatsApp, MAX или звонок — ответом messenger |
viewing | Запись на просмотр: день из ближайших десяти и время — ответом viewing |
email_pick | Подборка на почту: почта обязательна, плюс телефон |
Тексты закрытий готовые, title меняет заголовок. Контакты — всегда последний шаг, в steps и blocks их не перечисляют.
Вставка на сайт
<!-- плавающая кнопка --> <script src="https://v.domxml.ru/s/quiz-embed.js" data-quiz="CODE" async></script> <!-- блоком в странице --> <div id="dx-quiz-CODE"></div> <script src="https://v.domxml.ru/s/quiz-embed.js" data-quiz="CODE" data-target="#dx-quiz-CODE" async></script>
Квиз открывается в рамке с v.domxml.ru, поэтому стили сайта его не задевают. Загрузчик передаёт в квиз адрес страницы и utm-метки, а цели — в Метрику сайта: атрибут data-metrika или metrikaId квиза. Цели: quiz_view, quiz_start, quiz_step_N, quiz_contact, quiz_lead.
Публичные ручки квиза
Их вызывают страница квиза и загрузчик. Авторизации нет — вместо неё код квиза и список domains (сверяются Origin, Referer и заголовок окна вставки). Выключенный и удалённый квиз отвечает 404.
| Метод | Путь | Описание |
|---|---|---|
| GET | /api/public/v1/q/{code}/config | Настройки кнопки: allowed, mode, text, position, delay, color, bot, metrika |
| POST | /api/public/v1/q/{code}/event | {"type": "view"|"start"|"contact"} — счётчик воронки, без персональных данных |
| POST | /api/public/v1/q/{code}/leads | Заявка: name, phone, email, complexId, quiz: [{key, question, answer}], page, utm, consent, company, ft |
Антиспам и лимиты заявок — как у формы канала: ловушка company, время заполнения ft, 10 заявок в час с адреса и 5 в сутки с телефона. Ответов — до 20, ответ — до 300 знаков, меток — до 10 по 200 знаков.
Статистика
GET /api/v1/quizzes/42/stats?days=30
{
"days": 30, "views": 1240, "starts": 612, "contacts": 288, "leads": 97,
"startRate": 49.4, "contactRate": 47.1, "conversion": 7.8,
"byDay": [{ "day": "2026-10-01", "views": 51, "starts": 24, "contacts": 11, "leads": 4 }]
}
startRate — начали из открывших, contactRate — дошли до контактов из начавших, conversion — заявки из показов, в процентах; без базы — null.
Заявка из квиза создаёт клиента CRM с источником «Квиз» (режим chat — «Чат-бот»), в ленту пишутся ответы и обещанный бонус, в Битрикс24 уходят пары «вопрос: ответ», в вебхук lead.created — quizId, quizCode, quiz и bonus. MCP: инструменты quiz_* (документация).
Вебхуки
Вместо опроса API можно получать события запросом на свой адрес. Подписка создаётся в панели (API и MCP → Вебхуки) или по API.
| Метод | Путь | Описание |
|---|---|---|
| GET | /webhooks/events | Список событий, задержки повторов, порог отключения |
| GET | /webhooks | Свои подписки |
| POST | /webhooks | Создать: url, events, необязательно name и complexIds |
| PATCH | /webhooks/{id} | Адрес, набор событий, ЖК, включить или выключить |
| DELETE | /webhooks/{id} | Удалить подписку |
| GET | /webhooks/{id}/deliveries | Журнал последних 50 доставок: попытки, коды ответа, ошибки |
| POST | /webhooks/{id}/test | Поставить в очередь пробное событие |
События: lead.created, client.created, client.status_changed, apartment.booked, apartment.released, apartment.sold, deal.created, deal.lost (только по сделкам: отказ от интереса и снятая бронь сюда не попадают), complex.changed, channel.published; агентская программа — fixation.created, fixation.activated, fixation.extended, fixation.closed, fixation.confirmed (клиент ответил, работает ли с агентом), showing.requested, showing.confirmed, showing.done, showing.cancelled, booking.requested, booking.decided, commission.created, commission.updated (застройщику — по его ЖК, агенту и руководителю агентства — по их закреплениям).
Что приходит
POST https://ваш-сервер.ru/domxml-hook
Content-Type: application/json
X-DomXML-Event: lead.created
X-DomXML-Delivery: 8241
X-DomXML-Timestamp: 1789902000
X-DomXML-Signature: sha256=2f1c…
{
"event": "lead.created",
"createdAt": "2026-09-20T11:00:00Z",
"data": {
"clientNumber": 42,
"isNewClient": true,
"name": "Пётр",
"phone": "+7 917 000-11-22",
"source": "Витрина",
"channelKey": "dxp_…",
"complexId": 1234567,
"apartmentId": 96,
"quizId": null,
"quizCode": null,
"quiz": [],
"bonus": null,
"utm": { "utm_source": "yandex", "utm_campaign": "zarechye" }
}
}
channelKey — ключ канала (виджета или витрины), с которого пришла заявка; utm — метки рекламы, которые прислала форма (не было — пустой объект). isNewClient: false — человек уже был в CRM, заявка легла в его карточку.
Заявка из квиза или чат-бота приходит с source «Квиз» или «Чат-бот», channelKey: null, номером и кодом квиза, ответами и обещанным бонусом:
"source": "Квиз",
"channelKey": null,
"quizId": 42,
"quizCode": "k7m2x9q4p1az",
"quiz": [
{ "key": "rooms", "question": "Сколько комнат нужно?", "answer": "2-комнатная" },
{ "key": "budget", "question": "Какой бюджет комфортен?", "answer": "7,5–9,5 млн ₽" },
{ "key": "pay", "question": "Как планируете оплату?", "answer": "Ипотека" }
],
"bonus": "Скидка 2% при бронировании"
Событие complex.changed несёт новую и прежнюю ревизию — по ним можно сразу запросить /changes?since=, не вызывая /version:
{
"event": "complex.changed",
"createdAt": "2026-09-23T09:00:00Z",
"data": {
"complexId": 1234567,
"name": "ЖК «Приречный»",
"rev": 43,
"previousRev": 42
}
}
Проверка подписи
Секрет выдаётся один раз при создании подписки. Подпись считается от строки «метка времени, точка, тело запроса» — метка внутри подписи не даёт переиграть старый запрос:
signature = "sha256=" + hmac_sha256(secret, timestamp + "." + raw_body)
Сравнивайте подписи функцией с постоянным временем сравнения и отклоняйте запросы старше пяти минут по X-DomXML-Timestamp.
Повторы
Ответ 2xx считается доставкой. При любом другом ответе или ошибке сети запрос повторяется через 1, 5, 30, 120 и 360 минут, после чего доставка помечается неудачной и остаётся в журнале. После 20 неудач подряд подписка выключается сама, а владелец получает уведомление — так отвалившийся навсегда адрес не копит очередь.
Отвечайте быстро: приёмнику даётся 10 секунд. Тяжёлую работу ставьте в свою очередь, а нам отвечайте сразу. Переходы по редиректам не выполняются, адрес должен быть публичным и на https.
CRM для застройщика
CRM — это проект: отдел продаж со своими ЖК, командой, клиентами, настройками, витринами и виджетами. У аккаунта может быть несколько проектов и приглашения в чужие. Доступ к ЖК и доступ к CRM независимы: менеджеру продаж шахматка не нужна, а редактор шахматки не видит клиентов.
Ключ без ограничения по ЖК работает с CRM так же, как пользователь в панели, в пределах прав владельца ключа в проекте («только свои», правка чужих, удаление, смена ответственного, задачи другим, администратор). Ключ с ограничением по ЖК к /crm не допускается — используйте MCP. {owner} в путях — публичный ID проекта (publicId из GET /crm/workspaces; у CRM, созданных до проектов, он совпадает с публичным ID владельца, поэтому старые интеграции работают). Клиент адресуется номером {number} в рамках проекта.
| Метод | Путь | Описание |
|---|---|---|
| GET | /crm/workspaces | Проекты CRM пользователя: publicId, name, isOwn, role, rights, canChannels, canPublish — свои первыми |
| POST | /crm/workspaces | Создать проект ({"name": "…", "kind": "sales|agency"}, до 120 символов; agency — агентство); создатель — владелец. PUT /crm/{owner}/agency — профиль агентства |
| PATCH / DELETE | /crm/{owner} | Переименовать (администратор проекта); удалить может только владелец и только пустой проект — без клиентов, открытых задач, ЖК и каналов, иначе 409 |
| PUT | /crm/{owner}/complexes/{complexId} | Добавить свой ЖК в проект или перенести из другого (владелец ЖК и администратор проекта). ЖК входит в один проект; клиенты и история остаются в прежнем, каналы прежнего проекта этот ЖК больше не показывают |
| POST | /crm/{owner}/team | Пригласить в команду (администратор): {"who": "почта или публичный ID"} — только зарегистрированных; права по умолчанию — видит всех, правит, передаёт, ставит задачи |
| DELETE | /crm/{owner}/team/{publicId} | Убрать из команды (администратор; владельца — нельзя). POST /crm/{owner}/leave — выйти самому |
| GET | /crm/{owner}/settings | Проект (project: publicId, name, isOwn), статусы, источники, этапы, команда, ЖК проекта |
| GET | /crm/{owner}/clients?q&status&source&responsible&complex&stage&sort&limit&offset | Список клиентов |
| POST | /crm/{owner}/clients | Создать клиента (name, phone|email или списки phones[]/emails[] — до 5 каждого, основной первым; messengers[telegram|max|wb], sourceId, complexIds, apartments[{apartmentId, stage, bookedUntil}]) |
| GET / PATCH / DELETE | /crm/{owner}/clients/{number} | Карточка (phones[], emails[] — все контакты, phone/email — основной), правка (phones/emails целиком; одиночный phone/email меняет только основной, "" снимает его, последний контакт снять нельзя; phone вместе с phones — становится основным перед списком), в корзину (30 дней); POST …/restore |
| POST | /crm/{owner}/clients/{number}/comments | Заметка / звонок / встреча в ленту |
| POST | /crm/{owner}/clients/{number}/tasks | Задача (text, assigneePublicId, dueAt); PATCH /crm/{owner}/tasks/{id}. dueAt — ISO 8601; без пояса — местное время CRM, одна дата — до 18:00 этого дня |
| GET | /crm/{owner}/tasks?assignee=me|all&status=open|today|overdue|done | Задачи |
| POST | /crm/{owner}/tasks | Задача из раздела «Задачи» (text, dueAt, assigneePublicId, clientNumber — необязателен: задача может быть не привязана к клиенту) |
| GET | /crm/{owner}/deals?complexId&stageId&responsibleId&purchaseType&q&staleDays&withClosed | Доска сделок: этапы со счётчиком и суммой, сделки (клиент, квартира, этап, сумма, вид покупки). Сделка — квартира с суммой и видом покупки; интересы и брони клиента сюда не попадают |
| POST | /crm/{owner}/deals | Новая сделка (clientNumber, apartmentId, amount, purchaseType, terms, force). Квартира прикрепится к клиенту, если её у него не было |
| PATCH | /crm/{owner}/deals/{linkId} | Этап (stageId), сумма, вид покупки, условия, заметка в ленту (comment), force — этап задаёт и стадию квартиры. stage (booked/deal/won/lost) меняет стадию напрямую, apartmentId переносит сделку на другую квартиру: старая возвращается в продажу, условия и дата сделки переезжают |
| POST | /crm/{owner}/deals/bulk | Массовые действия над отмеченными (ids + любое из stageId, purchaseType, amount, comment; force) → moved, failed[] |
| PUT | /crm/{owner}/settings/deal-stages | Этапы сделок (администратор CRM): stages[{id, name, color, kind: deal|won|lost, isDefault}]; нужны все три вида, по умолчанию — только deal |
| POST | /crm/{owner}/clients/{number}/apartments | Интерес или бронь квартиры (apartmentId, stage, bookedUntil) |
| PATCH / DELETE | /crm/{owner}/clients/{number}/apartments/{linkId} | Стадия (booked | deal | won | lost), сумма, вид покупки, условия |
| POST | /crm/{owner}/clients/bulk | Массовые действия над выбранными (numbers, action: responsible | status | source | tags | task | comment | delete | restore) |
| GET | /crm/{owner}/summary?period=week|month|quarter|year или ?from=YYYY-MM-DD&to=YYYY-MM-DD | Сводка: воронка, источники, сделки, задачи, брони, по менеджерам |
| GET | /crm/{owner}/export | Excel «Клиенты» (администратор CRM) |
| POST | /crm/{owner}/clients/{number}/pd-request | Требование по 152-ФЗ: {"kind": "access|rectify|delete", "receivedOn": "YYYY-MM-DD", "channel": "email|letter|phone|office|other", "note": "…", "deleteNow": true}. Срок ответа — в рабочих днях (сведения и удаление — 10, уточнение — 7). delete с deleteNow (по умолчанию) удаляет карточку и заявки сразу, без корзины (право «удаляет») |
| GET | /crm/{owner}/pd-requests?status=open|closed|all | Журнал требований (администратор CRM): срок, status (open, overdue, done, refused), кто записал и закрыл, итог |
| POST | /crm/{owner}/pd-requests/{id}/close | Закрыть: {"outcome": "done|refused", "note": "…"}; для отказа причина обязательна |
| POST | /crm/{owner}/pd-requests/{id}/extend | Продлить срок на 5 рабочих дней — один раз, с причиной (note); уточнение не продлевается |
| POST | /crm/{owner}/pd-requests/{id}/delete-data | Исполнить отложенное требование об удалении (право «удаляет») |
| PUT | /crm/{owner}/settings/timezone | Часовой пояс CRM (администратор CRM): {"timezone": "+5"} — целые часы от −12 до +14 или имя вроде Asia/Yekaterinburg; null — автоматически по ЖК. По нему «сегодня» у задач, дашборд, тихие часы и утренняя сводка; в settings — timezone: {value, auto, hours} |
| PUT | /crm/{owner}/settings/team/{publicId} | Права участника команды (администратор проекта): isAdmin, seeAll, editOthers, canDelete, canReassign, assignOthers, canChannels, canPublish, canAgentsView, canAgentsManage — только переданные поля; список members с правами приходит в settings, свои права — в rights у workspaces и settings |
| GET / POST | /complexes/{id}/apartments/{aid}/clients | Клиенты квартиры из проекта, в который входит ЖК (только его команде); прикрепить существующего или создать нового |
Смена статуса квартиры через PUT /complexes/{id}/apartments/{aid} при активной брони клиента отвечает 409 с полем crmBooking; повторите запрос с "force": true, чтобы снять бронь. Номер и имя клиента в crmBooking приходят только участнику его проекта CRM, остальным — null, а в crmName и holder — название проекта.
Агентская программа
Застройщик запускает программу по своему ЖК: условия (вознаграждение, шкала, правила закрепления клиента, что разрешено), участники — агенты и агентства (агентство — проект CRM вида agency). Агент закрепляет клиента по телефону, записывает на показ, просит бронь; застройщик решает в своей CRM. API подходит агентствам со своей CRM (amoCRM, Битрикс24 через Make или n8n): закрепление и статусы — ключом, события — вебхуками fixation.*, showing.*, booking.*, commission.*. Ключ с ограничением по ЖК работает только с условиями программ своих ЖК (/complexes/{id}/agent-program); закрепления, показы, бронь и начисления ему недоступны.
Агенту (свои закрепления; руководитель и администраторы агентства — все закрепления агентства):
| Метод | Путь | Описание |
|---|---|---|
| GET | /agent/programs | Программы и приглашения: participantId, programId, status (invited | applied | active | blocked), via (лично или агентство), ЖК, вознаграждение, что разрешено |
| GET | /agent/programs/{programId} | Условия (с индивидуальными, если есть), правила закрепления, текст застройщика, участия с прогрессом по шкале (progress) |
| GET | /agent/programs/{programId}/snapshot?profile=short|full | Шахматка ЖК — публичный снимок (только при действующем участии и включённой программе) |
| POST | /agent/participations/{participantId}/accept | decline | leave | Принять или отклонить приглашение, выйти из программы (за агентство — руководитель или администратор) |
| POST | /agent/fixations | Закрепить клиента: {"participantId", "name", "phones": [], "interest": "residential|other", "comment", "consent": true}. 201 — result: fixed | pending; 409 — code: own | taken | sales | quarantine и текст (чей клиент — не раскрывается). Если в ответе canRequestTransfer: true, клиента можно попросить передать вам: тот же запрос с "transfer": true и объяснением в comment (от 10 символов) → result: transfer, решает застройщик. Лимит проверок номеров в час — в условиях программы (429) |
| GET | /agent/fixations?program&scope=open|closed&q | Закрепления: номер, состояние (pending | active | rejected | expired | released | won | lost), этап, срок, что можно продлить |
| GET | /agent/fixations/{id} | Карточка: история, показы, запросы брони, куда перенести (личное → агентство) |
| POST | /agent/fixations/{id}/extend | release | move | Продлить (кнопкой в окне до конца срока или запросом застройщику — по условиям), снять, перенести в агентство ({"participantId"}) |
| POST | /agent/fixations/{id}/showings | Запись на показ: {"startsAt": "ISO 8601 с поясом", "format": "office|site|online", "apartmentId", "comment"}; POST /agent/showings/{sid}/accept | cancel — принять время застройщика или отменить |
| GET | /agent/fixations/{id}/slots | Расписание показов отдела продаж, если застройщик его задал: дни, слоты и сколько мест свободно (free). При расписании запись — только на startsAt свободного слота (400 — не из расписания, 409 — время уже заняли); с autoConfirm показ сразу подтверждён |
| POST | /agent/fixations/{id}/booking | Бронь объекта: {"apartmentId", "days", "comment"} — запрос застройщику или сразу, по условиям; POST /agent/bookings/{bid}/cancel |
| GET | /agent/commissions?program | Начисления и суммы по статусам (accrued | due | paid | cancelled) |
| POST | /agent/fixations/{id}/confirm-max | Ссылка на бота MAX для клиента (если бот подключён): клиент поделится номером, бот сверит его с номером в закреплении, и клиент подтвердит работу с вами. Ответ — в confirm закрепления и вебхуке fixation.confirmed |
Застройщику ({owner} — проект CRM отдела продаж; право «Агенты: видит», решения — «Агенты: управляет»; показы подтверждает и «видит»):
| Метод | Путь | Описание |
|---|---|---|
| GET / PUT | /complexes/{id}/agent-program | Программа ЖК: enabled, commission (ставка, шкала, byKind — по видам объектов, byBuilding — по корпусам, bonuses — бонусы на период), fixRules (в том числе transferRequests — запросы передачи клиента), allow (в том числе slots — расписание показов), termsText; участники; buildings — корпуса ЖК |
| POST | /complexes/{id}/agent-program/participants | Пригласить: {"kind": "user|agency", "who": "почта или ID"}; PATCH / DELETE …/participants/{pid} — статус, индивидуальная ставка, заметка |
| POST | /complexes/{id}/agent-program/invite-link | Ссылка-приглашение: {"enabled", "regenerate"} |
| GET | /crm/{owner}/agents/fixations?state=pending|active|expiring|closed&complex&q | Закрепления проекта и счётчики; GET …/fixations/{number} — карточка с историей, показами и бронями |
| POST | /crm/{owner}/agents/fixations/{number}/{action} | approve (у запроса передачи — с reason: закрепление текущего агента снимается), reject (reason), extend (days), decline_extension, shown, verify (note), confirm_link (ссылка для клиента — в карточке confirmLink.url, 14 дней, один ответ; если бот MAX подключён — ещё confirmLink.maxUrl, клиент подтвердит номером телефона), release (reason) |
| GET | /crm/{owner}/agents/showings?scope=upcoming|past | Показы; POST …/showings/{sid}/confirm | reschedule | done | no_show | cancel |
| POST | /crm/{owner}/agents/bookings/{bid}/approve | decline | Запрос брони: поставить обычную бронь CRM (days) или отклонить (comment) |
| GET / PATCH | /crm/{owner}/agents/commissions, …/commissions/{id} | Начисления: status (accrued | due | paid | cancelled), plannedAt, paidAt, корректировка amount с note |
| GET | /crm/{owner}/agents/checks, /crm/{owner}/agents/summary | Журнал проверок номеров по агентам; сводка «Агентский канал» за 30 дней |
Клиенты агентов в CRM застройщика помечены полем agent и отбираются фильтром GET /crm/{owner}/clients?agent=1. Отметка «куплена» по клиенту агента с действующим закреплением создаёт начисление вознаграждения автоматически.
Примеры
Изменить цену квартиры
curl -X PUT https://domxml.ru/api/v1/complexes/12/apartments/345 \
-H "Authorization: Bearer dxk_ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{"price": 5200000}'
Пересобрать фид Домклик
curl -X POST https://domxml.ru/api/v1/complexes/12/feeds/domclick/generate \ -H "Authorization: Bearer dxk_ВАШ_КЛЮЧ"
Вызывать generate после каждой правки не нужно: фиды пересобираются сами раз в 3 часа, если в ЖК что-то поменялось. generate — чтобы площадка получила изменения сейчас.
Готовый фид всегда доступен по постоянной ссылке https://feed.domxml.ru/{type}/complex_{id}.xml. Прежний адрес https://domxml.ru/feeds/{type}/complex_{id}.xml отдаёт тот же файл — ссылки, уже переданные площадкам, продолжают работать.
Пагинация
Большинство списков отдаётся целиком. Постранично — там, где записей может быть много: параметры limit и offset.
GET /crm/{owner}/clients—limitпо умолчанию 50, до 500; ответ{"items", "total", "limit", "offset"}.GET /crm/{owner}/tasks—limitпо умолчанию 100, до 500.GET /complexes/{id}/changelog—limitпо умолчанию 100, до 500; ответ — массив без общего числа: пришло меньшеlimit— записи кончились.
Объекты ЖК (GET /complexes/{id}/apartments) приходят все сразу. Чтобы не качать их каждый раз, берите только изменения: /apartments/delta или /changes (синхронизация).
CORS
REST API (/api/v1) — для вашего сервера, а не для браузера. Запросы со страниц чужих сайтов браузер не пропустит: CORS открыт только панели DomXML. Да и не нужно: ключ dxk_ в коде страницы увидел бы любой посетитель. Для браузера есть публичное API с ключом канала dxp_ — оно отвечает Access-Control-Allow-Origin: * и отдаёт ETag наружу.
Коды ошибок
Всегда JSON вида {"detail": "текст"}.
| Код | Когда |
|---|---|
| 400 | Запрос не имеет смысла: ревизии из snapshot?rev= ещё нет, отрицательный since, неизвестный via журнала, фиду VK или Директа не хватает данных (в тексте — чего), заявка без consent: true, когда согласие включено |
| 401 | Ключ недействителен, отозван или истёк. После 30 неудачных попыток за минуту с одного адреса сервер минуту отвечает 401 и на верный ключ |
| 403 | Не хватает уровня ключа (readonly пишет, editor удаляет), нет доступа к ЖК или ЖК вне списка ключа, путь закрыт для ключей, нет разрешения на каналы, нет права в ЖК или в CRM. В публичном API — запрос не с разрешённого домена канала |
| 404 | Не найдено; в публичном API — ещё и выключенный или удалённый канал |
| 409 | Конфликт с текущим состоянием: активная бронь CRM при смене статуса или удалении (в ответе crmBooking, повтор с force), объект куплен, фид выключен (generate), файл используется, проект CRM не пуст, время показа уже заняли |
| 413 | Закончилось место в файловом хранилище |
| 422 | Некорректное тело: тип, длина, диапазон, справочное значение — в detail массив ошибок по полям. Ещё — правила вида проекта: вид объекта или назначение здания не подходит проекту, второй объект в отдельном доме, фид площадки, недоступной виду (ctx.allowed), смена вида проекта, которой мешают объекты, здания или фиды |
| 429 | Превышен лимит: публичное API (240 в минуту с адреса, 1200 на канал), заявки (10 в час с адреса, 5 в сутки с телефона), проверки фидов для импорта (20 в час), проверки номеров агентом (по условиям программы) |
У 422 в detail — массив ошибок по полям:
{"detail": [{"type": "string_too_long", "loc": ["body", "salesPhone"],
"msg": "Не длиннее 20 символов", "input": "…"}]}
При массовом создании в loc есть номер квартиры в массиве: ["body", "apartments", 3, "price"].
Фид площадки, недоступной виду проекта:
{"detail": [{"type": "value_error", "loc": ["body", "platform"], "input": "cian",
"msg": "Циан принимает паркинги и коммерцию только в составе ЖК из своего каталога новостроек — у отдельного паркинга и гаражей доступны VK Реклама и Яндекс Директ",
"ctx": {"allowed": ["vk", "direct"]}}]}
Общего лимита числа запросов по ключу dxk_ нет; массовые операции — до 500 объектов за запрос.
Безопасность
- Секрет ключа показывается один раз, в базе хранится только его хэш. Ключ отзывается в разделе «API и MCP» — сразу.
- У каждого ключа — уровень, список ЖК и срок. Ключ не выпускает другие ключи и не выдаёт доступы.
- Правки ЖК и объектов по ключу пишутся в журнал ЖК со способом
key, через MCP —mcp; изменения каналов — в журнал канала (/channels/{id}/log). - Доступ поддержки. Поддержка не заходит в ваш аккаунт сама. Если в обращении нужна правка, вы выдаёте временный ключ — галочкой при обращении или кнопкой «Разрешить» в ответе поддержки. Он действует 5 дней, виден в «API и MCP», отзывается в любой момент и сам — при закрытии обращения. Такой ключ работает только по REST и только с вашими ЖК (чужие, к которым вам открыли доступ, он не видит), ничего не удаляет; CRM и витрины — только если вы их отметили, публиковать витрины не может. Его правки помечены в журнале ЖК как
support— «через поддержку».