Публичное API

API шахматки: версия, дельты и вебхуки

Интеграция для тех, кому нужна не готовая вставка, а свои страницы. Данные отдаются так, чтобы их не приходилось выкачивать целиком: короткая версия, снимок с ETag, дельты и события на ваш адрес.

Ключ создаётся в панели за минуту, авторизация для чтения не нужна

Терминал — curl
$ curl https://domxml.ru/api/public/v1/dxp_…/version \ -H "Origin: https://zarechye.ru"{ "contract": "1", "version": "0da94d56a6ca41f7", "changedAt": "2026-09-28T09:41:12Z", "complexes": [ { "complexId": 5627431, "rev": 12, "apartments": { "available": 412, "reserved": 96, "sold": 144, "total": 652 } } ], "snapshotUrl": "/api/public/v1/dxp_…/apartments?v=0da94d56a6ca41f7"}​$ curl -i "https://domxml.ru/api/public/v1/dxp_…/apartments?v=0da94d56a6ca41f7" \ -H "Origin: https://zarechye.ru" \ -H 'If-None-Match: W/"v1-dxp_…-0da94d56a6ca41f7-short"'HTTP/2 304etag: "v1-dxp_…-0da94d56a6ca41f7-short"cache-control: public, max-age=31536000, immutable
1

Ключ и домен канала

Ключ dxp_… открывает только ЖК канала, а запрос не с разрешённого домена получит 403.

2

Версия — сотни байт

Хэш версии и счётчики по статусам: видно, изменилось ли что-то, без каталога.

3

ETag снимка

Адрес снимка из snapshotUrl содержит версию и кэшируется навсегда; ETag возвращайте как есть, с W/.

4

304 без тела

Ничего не изменилось — ответ пустой, трафика почти нет.

Как это работает

Как встроить за один вечер

1

Создайте канал

Раздел «Публикация» → канал с типом «виджет»: он даёт публичный ключ и список разрешённых доменов.

2

Спросите версию

GET /version — хэш шахматки и счётчики по каждому ЖК. Дёшево настолько, что можно звать часто.

3

Заберите снимок

GET /apartments с профилем short или full. Ответ кэшируется и проверяется по ETag.

4

Подпишитесь на события

Вебхук с подписью HMAC приходит при изменении цен, статусов и состава квартир.

Преимущества

Что сделано ради вашего трафика

Версия вместо каталога

Проверка изменений — несколько сотен байт. Не нужно качать тысячу квартир, чтобы понять, что не поменялось ничего.

ETag и 304

Адрес снимка из snapshotUrl содержит версию и не меняется — кэш на стороне клиента и CDN. Повтор с ETag в If-None-Match стоит одного заголовка.

Дельты по ревизии

?since=1234567:11 вернёт только изменившиеся и удалённые квартиры. Журнал изменений ведут триггеры базы, а не приложение.

Вебхуки с подписью

HMAC-SHA256 по строке «метка времени.тело», в заголовке с префиксом sha256=. Повторы 1/5/30/120/360 минут, автоотключение после 20 неудач подряд.

CORS без фокусов

Публичные ручки отвечают Allow-Origin: * и отдают ETag наружу, поэтому запрос можно делать прямо из браузера.

Контракт версии 1

Поля публичного ответа отделены от внутренних: переименование колонки в панели не ломает ваш код.

Чем это отличается от выгрузки XML

XML-фид — формат для площадок: он собирается по расписанию, содержит объявления целиком и не умеет отвечать на вопрос «что изменилось с прошлого раза». Для сайта это неудобно: чтобы показать актуальные цены, приходится либо скачивать фид целиком, либо мириться с задержкой.

Публичное API устроено под инкрементальное обновление. Версия шахматки меняется, только когда действительно поменялись данные ЖК: за этим следят триггеры в базе, а не ручные вызовы из кода. Поэтому клиент может спрашивать версию хоть каждую минуту и почти всегда получать «ничего не изменилось» за сотни байт.

Каналами можно управлять не только руками: те же настройки доступны по API и через MCP — нейросеть создаёт канал, меняет оформление и показывает предпросмотр. Публикация при этом остаётся отдельным разрешением, которое выдаётся ключу осознанно.

Что отдаёт API

  • Версию шахматки и счётчики по статусам
  • Снимок квартир: профиль short или full
  • Дельты изменений от известной ревизии
  • Карточку ЖК: адрес, класс, сроки, инфраструктуру
  • Планировки, фото и виды из окна
  • Скидки и акции по квартирам
  • Приём заявок с вашей формы в CRM
  • События на ваш адрес: цены, статусы, заявки

Примеры

Три запроса, которые всё решают

Сначала спрашиваем версию — это несколько сотен байт. Если version совпал с сохранённым у вас, дальше идти некуда. Браузер сам присылает заголовок Origin, а в curl его нужно передать: если у канала задан список доменов, запрос без Origin и Referer получит 403:

curl https://domxml.ru/api/public/v1/$KEY/version \
     -H 'Origin: https://ваш-сайт.ru'
# {"contract":"1","version":"0da94d56a6ca41f2","complexes":[
#   {"complexId":5627431,"rev":12,"apartments":{"total":50,"available":37}}],
#  "snapshotUrl":"/api/public/v1/dxp_…/apartments?v=0da94d56a6ca41f2"}

Изменилось — забираем снимок по snapshotUrl из ответа. В адресе — версия, содержимое по нему уже не изменится, поэтому он отдаётся с immutable: браузер и CDN второй раз его не скачают. Есть и ETag — верните его в If-None-Match как есть, вместе с W/, если сервер сжал ответ, и при той же версии придёт 304 без тела:

curl -i "https://domxml.ru/api/public/v1/$KEY/apartments?v=0da94d56a6ca41f2" \
     -H 'Origin: https://ваш-сайт.ru'
# HTTP/2 200
# cache-control: public, max-age=31536000, immutable
# etag: W/"v1-dxp_…-0da94d56a6ca41f2-short"

curl -i "https://domxml.ru/api/public/v1/$KEY/apartments?v=0da94d56a6ca41f2" \
     -H 'Origin: https://ваш-сайт.ru' \
     -H 'If-None-Match: W/"v1-dxp_…-0da94d56a6ca41f2-short"'
# HTTP/2 304

Если у вас уже есть прошлый снимок, весь каталог качать незачем — спрашиваем дельту от известной ревизии:

curl "https://domxml.ru/api/public/v1/$KEY/changes?since=5627431:11" \
     -H 'Origin: https://ваш-сайт.ru'
# {"contract":"1","version":"0da94d56a6ca41f2","complexes":[{
#   "complexId":5627431,"rev":12,"since":11,"changed":true,
#   "items":[{"id":812,"price":8990000.0,"status":"reserved"}],"deleted":[]}]}

Ответ приходит по каждому ЖК отдельно: items — изменившиеся квартиры, deleted — удалённые. Если журнал не помнит вашу ревизию, придёт fullRequired — тогда забирайте снимок целиком.

А чтобы не опрашивать вовсе — подпишитесь на события. Подпись приходит в заголовке X-DomXML-Signature с префиксом sha256=, проверяют её так:

const signed = `${req.headers['x-domxml-timestamp']}.${rawBody}`;
const mine = 'sha256=' + crypto.createHmac('sha256', secret).update(signed).digest('hex');
if (mine !== req.headers['x-domxml-signature']) return res.sendStatus(401);

FAQ

Частые вопросы

Как часто можно опрашивать API?

Ограничение — 240 запросов в минуту с одного адреса и 1200 на канал. Этого хватает с запасом: правильный цикл спрашивает версию раз в минуту и идёт за данными, только когда хэш изменился.

Зачем дельты, если есть снимок?

Снимок ЖК на тысячу квартир — это сотни килобайт, а типичное изменение за день — несколько лотов. Дельта возвращает только их, поэтому обновление стоит трафика меньше, чем одна фотография.

Как проверить подпись вебхука?

Считайте HMAC-SHA256 от строки «метка времени, точка, тело запроса» на своём секрете, добавьте спереди «sha256=» и сравните с заголовком X-DomXML-Signature. Секрет показывается один раз при создании подписки.

Нужен ли ключ и что он открывает?

Для чтения — только публичный ключ канала: он открывает ровно те ЖК, которые вы в этот канал добавили. Для управления каналами нужен API-ключ с отдельным разрешением «Управление витриной и виджетами».

Что будет, если я удалю канал?

Ключ перестанет отвечать: и вставка на сайте, и ваши запросы получат 404. По ключу нельзя отличить «канала не было» от «канал выключен» — это сделано специально.

Заберите данные к себе на сайт

Создайте канал, скопируйте ключ и сделайте первый запрос — API бесплатное

Начать бесплатно