Разработчикам

API карты для разработчиков

Пять строк — и карта ЖК на сайте. Цены и квартиры в продаже у корпусов — JSON прямо в коде, данные остаются у вас. Дальше сайт управляет картой сам: выбирает корпус, ставит время, строит маршрут, прячет наши кнопки и слушает события.

Быстрый старт за 1 минуту

Вставьте код туда, где должна быть карта. Вместо dom-na-yamskoy — адрес вашего проекта: он есть в кабинете («Опубликовать» → «Код для сайта» → «JS API», там же готовый код). Карта рядом — ровно этот код.

HTML
<div id="kinjo-map" style="height:600px"></div>
<script src="https://map.kinjo.ru/widget.js"></script>
<script>
  const map = Kinjo.mount('#kinjo-map', { project: 'dom-na-yamskoy' });
  map.on('houseSelect', (house) => console.log(house?.name, house?.sales?.priceText));
</script>

Старый код с data-атрибутами работает и дальше. Тот же объект карты у него — Kinjo.mount(элемент).

Без своего JavaScript
<div data-kinjo data-project="dom-na-yamskoy" data-controls="-time,-header"></div>
<script src="https://map.kinjo.ru/widget.js" async></script>

Цены и квартиры у корпуса — передайте JSON

В карточке корпуса — «от 5,2 млн ₽», «10 квартир в продаже», примечание, свои строки и кнопка на выдачу квартир этого корпуса на вашем сайте (новая вкладка, utm_source=kinjo). Данные передаёт ваш сайт при встраивании: они остаются на странице и на наш сервер не уходят. Измените JSON и нажмите «Применить» — карточка на карте рядом обновится.

JavaScript — так это выглядит в коде
Kinjo.mount('#kinjo-map', {
  project: 'dom-na-yamskoy',
  houses: {
    "Корпус 1": {
      "priceFrom": 5200000,
      "flatsOnSale": 10,
      "url": "https://kinjo.ru/",
      "note": "Скидка 5% до 31.10",
      "button": "Выбрать квартиру",
      "lines": [
        {
          "label": "Сдача",
          "value": "IV кв. 2026"
        },
        {
          "label": "Отделка",
          "value": "White box"
        }
      ]
    },
    "Корпус 2": {
      "priceFrom": 7850000,
      "flatsOnSale": 4
    }
  },
});
ПолеЧто это
priceFrom«Цена от», ₽: число или строка «5 200 000» → «от 5,2 млн ₽»
flatsOnSaleквартир в продаже, целое → «10 квартир в продаже»
urlссылка «Смотреть квартиры», только https
noteпримечание под ценой, до 200 знаков
buttonподпись кнопки, до 40 знаков
linesсвои строки, до 6: [{ label, value }]

Ключ — ID дома из кабинета (k1) или название ('Корпус 1'). Всё необязательно; что не передано — не показываем. Данные со страницы главнее заполненного в кабинете, null убирает поле кабинета. Всё выводится текстом, не HTML; неподходящее (http-ссылка, лишнее поле) пропускается с предупреждением в консоли.

Карточка корпуса на телефоне: от 5,2 млн ₽, 10 квартир в продаже, кнопка «Смотреть квартиры»
Что видит покупатель

Без своего JavaScript

JSON — прямо внутри блока карты, например, из шаблона CMS:

HTML
<div data-kinjo data-project="dom-na-yamskoy">
  <script type="application/json" data-kinjo-houses>
    { "Корпус 1": { "priceFrom": 5200000, "flatsOnSale": 10, "url": "https://ваш-сайт.ru/flats?k=1" } }
  </script>
</div>
<script src="https://map.kinjo.ru/widget.js" async></script>

На лету

JavaScript
// сайт сам взял цены из своей CRM — передаёт карте на лету
const prices = await fetch('/api/my-prices').then((r) => r.json());
await map.setHouses({
  k1: { priceFrom: prices.k1.min, flatsOnSale: prices.k1.count },
  k2: { priceFrom: prices.k2.min, flatsOnSale: prices.k2.count },
});

Свой iframe — Kinjo.connect(iframe).setHouses({...}). В событии houseSelect приходит итог: house.sales.priceText, flatsText, note, lines.

Страница квартиры

Рядом с планировкой — дом квартиры в ЖК: только сам ЖК с подсвеченным домом, без мест, категорий, солнца, шапки и карточек. Камера сама встаёт так, чтобы дом был в центре и целиком и его не заслоняли соседи. Карту можно вращать и приближать: на компьютере — мышью (колесо — с Ctrl или ⌘), на телефоне — двумя пальцами. Грузится быстро: места, маршруты и зоны в этом режиме не загружаются; на слабом телефоне — 2D с подсветкой.

Кнопка «Открыть карту» в углу открывает полную карту поверх страницы: все элементы, тот же дом выбран, его карточка открыта (с ценами из houses, если вы их передали). Закрыть — ✕, Esc, «назад» или свайп вниз; фокус вернётся на кнопку. Попробуйте:

HTML
<div id="flat-map" style="height:420px"></div>
<script src="https://map.kinjo.ru/widget.js"></script>
<script>
  Kinjo.mount('#flat-map', {
    project: 'dom-na-yamskoy',
    house: 'Корпус 2',   // дом квартиры: ID, название или подпись
    view: 'house',
  });
</script>
Без своего JavaScript
<div data-kinjo data-project="dom-na-yamskoy" data-house="Корпус 2" data-view="house"
     data-open-label="Дом на карте" style="height:420px"></div>
<script src="https://map.kinjo.ru/widget.js" async></script>

Дом — как в selectHouse: ID из кабинета, ID части, название или подпись. section (data-section) подсветит секцию или подъезд, если дом в модели из частей. openLabel (data-open-label) — своя подпись кнопки, false ("0") — без неё. Высота — у блока, без неё — 420 px. Цены и квартиры (houses, data-kinjo-houses) передаются и в полную карту. События mapOpen и mapClose — когда карту открыли и закрыли.

Только iframe
<iframe src="https://map.kinjo.ru/?project=dom-na-yamskoy&house=%D0%9A%D0%BE%D1%80%D0%BF%D1%83%D1%81%202&view=house&embed=1"
        style="width:100%;height:420px;border:0" title="Дом на карте ЖК"></iframe>

Без widget.js кнопка открывает полную карту в новой вкладке (данные houses туда не попадут — их передаёт widget.js). Ключи API не нужны.

Параметры

Kinjo.mount(el, options) — el элемент или селектор. Возвращает объект карты: методы-обещания и события.

ПараметрЗначенияПо умолчанию
projectадрес проекта (slug), обязателен—
theme'light', 'dark', 'mono', 'warm', 'brand'как в проекте
mode'2d' — быстрее, '3d' — солнце и теникак в проекте
layout'dock', 'sidebar', 'sidebar:theme'как в проекте
dock'icons', 'legend' — категории на компьютерекак в проекте
logo'full', 'logo', 'none' — шапкакак в проекте
isochrones[15, 30] или 'off' — «пешком за N минут»как в проекте
pinShape'pin' — значок с точкой, 'badge' — значок, 'dot' — меткакак в проекте
pinRadius0–50 — скругление пинов, %: 0 — квадрат, 50 — кругкак в проекте
pinSize's', 'm', 'l' — размер пиновкак в проекте
uiRadius0–24 — скругление кнопок, карточек и панелей, px; 24 — капсулыкак в проекте
dockSize'm' — стандартный, 's' — маленький, 'xs' — очень маленький доккак в проекте
timeOpentrue — время суток открыто сразу (лента часов над доком), false — по нажатию на «☀»как в проекте
heightpx или 'auto'560
housesцены, квартиры и строки карточек корпусов (ниже)—
controlsчто из наших кнопок показывать (ниже)все
lazytrue — грузить, когда блок долистаютсразу
view'house' — страница квартиры: ЖК с подсвеченным домом и кнопкой «Открыть карту» (ниже)полная карта
houseдом квартиры для view: 'house' — ID, название или подпись, как в selectHouse—
sectionсекция или подъезд дома для view: 'house', если дом из частейвесь дом
openLabelподпись кнопки «Открыть карту»; false — без кнопки'Открыть карту'

Элементы управления

Спрячьте наши кнопки, если ставите свои. Переключайте — карта рядом меняется, а ниже — код, который получится.

JavaScript
Kinjo.mount('#kinjo-map', {
  project: 'dom-na-yamskoy',
});

Без JavaScript — атрибут data-controls="none" или "-time,-header"; у iframe — &ui=none.

Вид под стиль сайта

Форма и размер пинов мест, скругление элементов карты — дока, кнопок, карточек, плашек, панелей и листа на телефоне — и размер дока. Обычно это настраивают в кабинете: «Настройки проекта» → «Карта на сайте» → «Вид элементов». Параметры встраивания переопределяют проект для одного сайта.

JavaScript
Kinjo.mount('#kinjo-map', {
  project: 'dom-na-yamskoy',
  pinShape: 'badge',  // значок без точки ('pin' — с точкой, 'dot' — метка)
  pinRadius: 0,       // квадратные пины (50 — круглые)
  pinSize: 'm',       // 's', 'm', 'l'
  uiRadius: 0,        // прямые углы у кнопок, карточек и панелей (24 — капсулы)
  dockSize: 's',      // док поменьше: 'm' — стандартный, 'xs' — очень маленький
});
Без своего JavaScript
<div data-kinjo data-project="dom-na-yamskoy" data-pin-shape="badge" data-pin-radius="0" data-ui-radius="0"></div>

У iframe — &pinShape=badge&pinRadius=0&pinSize=m&uiRadius=0&dockSize=s. Цвета пинов — по категориям из проекта. Смена параметров через Kinjo.update(el, {'{'} uiRadius: 12 {'}'}) перезагружает карту.

Методы

Все методы возвращают Promise. Команды, отправленные до загрузки карты, ждут её. Ошибка — Error с полем code: unknown_house, bad_args, unavailable, route_failed, origin_not_allowed, timeout.

selectHouse(ref)

Выбрать дом по ID, названию или подписи: откроется карточка, камера подлетит. Ответ — сведения о доме, вместе с продажами.

карта загружается…
Код
const house = await map.selectHouse('Корпус 1');
console.log(house.sales?.priceText); // «от 5,2 млн ₽»

setHouses(houses) · updateHouse(ref, house)

Данные корпусов со страницы на лету: setHouses — заменить всё, updateHouse — один корпус поверх прежнего (null — убрать). Например, сайт подтянул цены из своей CRM уже в браузере.

карта загружается…
Код
await map.setHouses({ 'Корпус 2': { priceFrom: 7850000, flatsOnSale: 4 } });
await map.updateHouse('Корпус 2', { note: 'Последние 4 квартиры' });
await map.updateHouse('Корпус 2', null);

setTime(time) · setDate(date)

«13:00» — время суток, Date — день и время по часовому поясу ЖК. Солнце и тени видны в 3D.

карта загружается…
Код
await map.setTime('22:30');      // ночь: окна светятся
await map.setDate('2026-12-21');  // зима
await map.setTime(new Date());    // сейчас

setMode(mode) · setTheme(theme)

Плоская карта или 3D; тема карты. Камера и выбранный дом сохраняются.

карта загружается…
Код
await map.setMode('2d');
await map.setTheme('dark');

routeTo(to, { mode })

Маршрут от ЖК до адреса (первая подсказка поиска по городу ЖК) или до точки. Ответ — минуты и километры.

карта загружается…
Код
const r = await map.routeTo({ address: 'Тюмень, ул. Республики, 1' });
console.log(r.minutes, r.km, r.mode); // 23 1.7 'walk'

await map.routeTo({ lngLat: [65.534, 57.153], label: 'Офис продаж' }, { mode: 'drive' });
await map.clearRoute();

showCategories(list) · showAllPlaces()

Только эти категории мест: edu — школы и сады, shops — магазины, health — здоровье, transport — транспорт, leisure — спорт и отдых.

карта загружается…
Код
await map.showCategories(['edu', 'health']);
await map.showAllPlaces();

setWalkZone(minutes) · openCity()

Зона «пешком за N минут» (какие есть — в ready.walkZones) и «Город» — сколько ехать до аэропорта, вокзала, центра.

карта загружается…
Код
await map.setWalkZone(15);
await map.setWalkZone(null);
await map.openCity();

flyTo(camera) · resetView()

Камера: центр [lng, lat], масштаб, поворот, наклон, длительность в мс. resetView — начальный вид проекта.

карта загружается…
Код
await map.flyTo({ center: [65.5059, 57.1645], zoom: 18, bearing: 60, pitch: 62 });
await map.resetView();

setControls('none')

Спрятать наши кнопки и поставить свои — или вернуть. При встраивании то же самое — параметр controls.

карта загружается…
Код
await map.setControls('none');            // только карта
await map.setControls({ time: true });     // вернуть время
await map.setControls('all');

Ещё: getState() — режим, выбранный дом, время; destroy() — убрать карту.

События

Подписка — map.on(name, fn), map.off, map.once. Те же события приходят на блок карты как kinjo:<name>. Нажмите что-нибудь на карте — события появятся здесь.

  1. Пока тихо: выберите корпус на карте или нажмите «Выполнить» у метода.
СобытиеКогда и что приходит
readyкарта загрузилась: дома, категории, зоны «пешком», есть ли «Город» и маршрут
houseSelectвыбрали дом (на карте или командой); null — выбор сняли. Вместе с продажами
placeSelectоткрыли место рядом: название, категория, «≈ 7 мин пешком»; у места прямо в ЖК — inComplex: true и без времени
routeBuiltпостроили маршрут: куда, пешком или на машине, минуты, километры
routeClearмаршрут убрали
timeChangeвремя на карте (3D), не чаще 4 раз в секунду
modeChangeпереключили 2D / 3D
flatsClickнажали «Смотреть квартиры» в карточке корпуса
mapOpenстраница квартиры (view: 'house'): нажали «Открыть карту»
mapCloseстраница квартиры: полную карту закрыли
errorпроект не найден, сайт не в списке, карта не отвечает
JavaScript
map.on('ready', (info) => console.log(info.houses));
map.on('houseSelect', (house) => {
  if (!house) return;                         // выбор сняли
  showMyCard(house.name, house.sales?.priceText, house.url);
});
map.on('routeBuilt', (r) => console.log(r.to, r.minutes, r.mode));
map.on('flatsClick', (h) => ym(XXXXXX, 'reachGoal', 'kinjo_flats'));

Свой iframe

Если на сайте уже стоит iframe с картой, подключитесь к нему — тот же объект карты. Наши кнопки у iframe задаёт параметр ui: none — только карта, -time,-header — без перечисленных.

HTML
<iframe id="kinjo-map" src="https://map.kinjo.ru/?project=dom-na-yamskoy&embed=1&ui=none"
        style="width:100%;height:600px;border:0" allow="fullscreen"></iframe>
<script src="https://map.kinjo.ru/widget.js"></script>
<script>
  const map = Kinjo.connect('#kinjo-map');
  map.ready.then(() => map.selectHouse('Корпус 1'));
</script>

Ограничение по сайтам

Кабинет → «Настройки проекта» → «Сайт и API» → «Сайты, где можно управлять картой». Если список задан, команды с других сайтов отклоняются (origin_not_allowed) и события туда не идут. Пусто — с любого. https://www.site.ru и https://site.ru — разные сайты.

Через API доступны только действия с картой: никаких данных кабинета, черновиков и ключей. Карта принимает команды только от страницы, в которую встроена, и отвечает только ей.

Типы TypeScript

Методы, параметры и события описаны в kinjo.d.ts: положите файл в проект — window.Kinjo станет типизированным.

TypeScript
// скачайте https://map.kinjo.ru/kinjo.d.ts в проект (например, types/kinjo.d.ts)
import type { KinjoMap, KinjoHouse } from './types/kinjo';

const map: KinjoMap = Kinjo.mount('#kinjo-map', { project: 'dom-na-yamskoy' });
map.on('houseSelect', (house: KinjoHouse | null) => { /* … */ });
React
useEffect(() => {
  const map = window.Kinjo.mount(ref.current, { project: 'dom-na-yamskoy' });
  map.on('houseSelect', setHouse);
  return () => map.destroy();
}, []);
Для CRM и без разработчика (необязательно)

Если сайт не передаёт цены сам, их можно задать у нас — тогда они видны везде, где стоит карта, и тоже без публикации.

Кабинет: блок «Продажи» в свойствах корпуса
Кабинет: свойства корпуса → «Продажи»

В кабинете

Редактор модели → клик по корпусу → «Продажи (по желанию)»: ссылка, цена, число квартир, предпросмотр карточки. Там же ID дома для API с кнопкой копирования.

HTTP API для CRM

Ключ: кабинет → «Настройки проекта» → «Сайт и API» → «Расширенно: ключи API для CRM» → «Создать ключ». Ключ показывается один раз, у нас хранится только его хэш. Держите его на сервере, не в коде страницы.

PUT …/houses/{houseId}/sales · curl
curl -X PUT https://api.kinjo.ru/api/v1/projects/vash-zhk/houses/k1/sales \
  -H "Authorization: Bearer kj_live_…" \
  -H "Content-Type: application/json" \
  -d '{"priceFrom": 5200000, "flatsOnSale": 12, "url": "https://ваш-сайт.ru/flats?korpus=1"}'

Поля необязательные: priceFrom — ₽, целое; flatsOnSale — целое; url — только https://. PUT заменяет продажи корпуса целиком, пустое тело {} их убирает. houseId — ID дома из кабинета (ID части дома тоже подходит).

Ответ 200
{
  "house": { "id": "k1", "name": "Корпус 1" },
  "sales": { "url": "https://ваш-сайт.ru/flats?korpus=1", "priceFrom": 5200000, "flatsOnSale": 12,
             "updatedAt": "2026-10-19T09:00:00.000Z" },
  "live": true
}
Убрать продажи и список домов
# убрать продажи корпуса
curl -X DELETE https://api.kinjo.ru/api/v1/projects/vash-zhk/houses/k1/sales -H "Authorization: Bearer kj_live_…"

# ID домов, названия и текущие продажи
curl https://api.kinjo.ru/api/v1/projects/vash-zhk/houses -H "Authorization: Bearer kj_live_…"
КодКогда
200сохранено; в ответе — дом и продажи
400не JSON или поле не прошло проверку, в issues — что не так
401нет ключа, ключ неверный или отозван
403ключ от другого проекта
404нет такого проекта или дома
413тело больше 8 КБ
429больше 120 запросов в минуту с ключом или много неверных ключей с одного адреса; Retry-After — через сколько секунд

Ошибки — JSON { "message": "…" } по-русски. Лимит — 120 запросов в минуту на ключ. Данные со страницы сайта (JSON выше) главнее этих.

Вопросы

Не нашли ответа — напишите на hello@kinjo.ru, ответим в течение рабочего дня.

Куда вставлять код на Тильде?

Блок «Другое» → T123 «HTML-код»: вставьте код целиком (div и оба script). Высоту задайте в style у div. Скрипт можно один раз положить в «Настройки сайта» → «Ещё» → «HTML-код для вставки внутрь head».

Куда вставлять код в 1С-Битрикс?

В визуальном редакторе страницы переключитесь в режим «Код» (PHP/HTML) и вставьте блок. Если это шаблон компонента — в template.php карточки ЖК; widget.js можно подключить в header.php шаблона сайта.

Куда вставлять код в WordPress?

В редакторе блоков добавьте блок «Произвольный HTML» и вставьте код. В Elementor — виджет «HTML». Если тема вырезает script, подключите widget.js через плагин вставки кода в шапку (например, WPCode).

Сайт на React, Vue, Next или Nuxt — как быть?

Подключите widget.js один раз, а Kinjo.mount вызывайте в onMounted / useEffect и map.destroy() при уходе со страницы. Блоки, которые появились и пропали при переходах, widget.js подхватывает и сам.

Обязательно ли что-то программировать?

Нет. Код из кабинета работает без строчки своего JavaScript. API нужен, если сайт хочет свои кнопки, связать карту с шахматкой или выдачей квартир, слушать события.

Что будет с картой, если сменится проект или мы обновим модель?

Код на сайте менять не нужно: карта всегда показывает опубликованную версию проекта, а продажи обновляются сразу, без публикации.