MIGI / MTM · Integration Docs

Partner Lead API

Документация для внешнего парсера или CRM, который передаёт объекты недвижимости в MIGI. Лиды попадают в Partner Leads и далее проходят общую модерацию перед Lead Market.
API v1JSONдо 100 лидов / запросдинамические поляidempotency + dedup
Быстрый стартPayloadПоляExcel / русские колонкиDynamic fieldsПримерыОтветыОшибки

Быстрый старт

Base URL
https://m2m.eco/api/partner-ingest/v1
Authorization
Authorization: Bearer <API_KEY>
API key выдаёт администратор MIGI. Ключ привязан на сервере к конкретному партнёру, поэтому передавать partner_client_id в payload не нужно и нельзя подменить.
MethodEndpointНазначение
GET/healthПроверить ключ и соединение
GET/schemaПолучить актуальный machine-readable контракт полей
POST/leadsПередать один лид или batch
GET/statsСтатистика интеграции
GET/leads/:externalId?source=ss.geПроверить статус конкретного лида

POST /leads

Поддерживаются 4 формы запроса: один объект, {lead:{...}}, {leads:[...]} или JSON-массив.

POST https://m2m.eco/api/partner-ingest/v1/leads
Authorization: Bearer <API_KEY>
Content-Type: application/json
Idempotency-Key: unique-delivery-id

{
  "leads": [
    {
      "external_id": "36854194",
      "source": "ss.ge",
      "source_listing_id": "36854194",
      "property_group_id": "20609",
      "source_url": "https://home.ss.ge/ru/real-estate/36854194",
      "seller_type": "собственник",
      "seller_confidence_pct": 70,
      "seller_confidence_reason": "отметка площадки: physical",
      "property_type": "квартира",
      "property_price_usd": 130000,
      "price": 130000,
      "currency": "USD",
      "property_area_m2": 83,
      "rooms": 4,
      "bedrooms": 3,
      "floor": "2/8",
      "condition": "старый ремонт",
      "city": "Батуми",
      "district": "Багратиони",
      "address": "М. Комахидзе 97",
      "cadastral_number": "05.31.01.551",
      "contact_phone": "+995558239392",
      "masked_phone": "558239***",
      "contact_name": "Alex",
      "source_seller_type": "physical",
      "seller_listings_count": 2,
      "phone_listings_count": 1,
      "photos": ["https://static.ss.ge/1.jpg"],
      "photo_count": 1,
      "published_at": "2026-09-30T10:06:00+04:00",
      "found_at": "2026-09-30T10:14:00+04:00",
      "title": "Продается 4-комнатная квартира",
      "description": "Полное описание объявления",
      "duplicate_urls": ["https://www.myhome.ge/ru/pr/26164619"],
      "custom_fields": {
        "balcony_type": "open",
        "parser_score": 0.93
      }
    }
  ]
}

Для каждого лида нужен стабильный идентификатор: лучше external_id. Если его нет, API использует source_listing_id, затем property_group_id. Также нужен хотя бы один из title, description, source_url.

Канонические поля

FieldTypeMeaning
external_idstringСтабильный ID объявления/лида
sourcestringss.ge, myhome.ge, korter.ge и т.д.
source_listing_idstringID объявления на площадке
source_urlstringСсылка на исходное объявление
property_group_idstringID одного объекта, если он найден на нескольких площадках
duplicate_urlsstring[]Ссылки на этот же объект на других площадках
seller_typestringсобственник / агент / другое
seller_confidence_pctnumberУверенность классификации 0–100
seller_confidence_reasonstringПочему сделан такой вывод
titlestringЗаголовок
descriptionstringПолное описание
property_typestringквартира / дом / участок / коммерция
transaction_typestringsale / rent / другое
property_price_usdnumberЦена, нормализованная в USD
pricenumberЦена в исходной валюте
currencystringUSD / GEL / EUR
property_area_m2numberПлощадь объекта
land_area_m2numberПлощадь участка
roomsnumberКомнаты
bedroomsnumberСпальни
floorstringНапример 2/8
conditionstringСостояние/ремонт
residential_complexstringЖК
citystringГород
districtstringРайон
addressstringАдрес
map_urlstringСсылка на карту
cadastral_numberstringКадастровый номер
contact_phonestringОсновной телефон
duplicate_phonestringТелефон из дубля
masked_phonestringТелефон-маска
contact_namestringИмя продавца
source_seller_typestringМетка площадки: physical / Individual
seller_listings_countnumberОбъявлений у продавца
phone_listings_countnumberОбъявлений на телефоне
contact_telegramstringTelegram
contact_whatsappstringWhatsApp
photosstring[]URL фотографий, максимум 40
photo_countnumberКоличество фото
published_atstringКогда опубликовано
found_atstringКогда найдено парсером
metadataobjectСлужебные данные парсера
custom_fieldsobjectЛюбые дополнительные поля

Совместимость с текущей Excel-выгрузкой

Можно отправлять даже текущие русские названия колонок. API сам сопоставит их с канонической схемой.

ExcelAPI
Тип продавцаseller_type
Уверенностьseller_confidence_pct
Почемуseller_confidence_reason
ID квартирыproperty_group_id
Площадкаsource
IDsource_listing_id
Ссылкаsource_url
Эта же квартира на других площадкахduplicate_urls
Типproperty_type
Цена, $property_price_usd
Ценаprice
Валютаcurrency
Площадь, м²property_area_m2
Участок, м²land_area_m2
Комнатrooms
Спаленbedrooms
Этажfloor
Состояниеcondition
ЖКresidential_complex
Городcity
Районdistrict
Адресaddress
Картаmap_url
Кадастрcadastral_number
Телефонcontact_phone
Телефон из дубляduplicate_phone
Телефон (маска)masked_phone
Продавецcontact_name
Отметка площадкиsource_seller_type
Объявлений у продавцаseller_listings_count
Объявлений на телефонеphone_listings_count
Фото (все ссылки)photos
Фото, штphoto_count
Опубликованоpublished_at
Найденоfound_at
Заголовокtitle
Описаниеdescription

Dynamic fields

Если у партнёра появится новая колонка, интеграцию не нужно останавливать. Новые значения можно сразу отправлять в custom_fields. Неизвестные top-level ключи тоже сохраняются автоматически.

{
  "external_id": "36854194",
  "source": "ss.ge",
  "source_url": "https://home.ss.ge/...",
  "custom_fields": {
    "balcony_type": "open",
    "view_direction": "sea",
    "owner_detection_model": "v3",
    "owner_detection_features": ["physical", "single_phone"],
    "parser_score": 0.94
  }
}

Оригинальный входящий JSON хранится целиком. Максимум: 64 KiB на один lead, до 40 URL фото, до 100 leads в batch.

Примеры интеграции

JavaScript

const baseUrl = 'https://m2m.eco/api/partner-ingest/v1'
const apiKey = process.env.MIGI_PARTNER_API_KEY

async function sendLeads(leads, deliveryId) {
  const response = await fetch(`${baseUrl}/leads`, {
    method: 'POST',
    headers: {
      'content-type': 'application/json',
      'authorization': `Bearer ${apiKey}`,
      'idempotency-key': deliveryId,
    },
    body: JSON.stringify({ leads }),
  })
  const body = await response.json()
  if (!response.ok) throw new Error(`${response.status}: ${body.code || body.error}`)
  return body
}

Python

import os, requests, uuid

BASE = "https://m2m.eco/api/partner-ingest/v1"
API_KEY = os.environ["MIGI_PARTNER_API_KEY"]

payload = {"leads": [{
    "external_id": "36854194",
    "source": "ss.ge",
    "source_url": "https://home.ss.ge/ru/real-estate/36854194",
    "title": "Продается квартира",
    "city": "Батуми"
}]}

r = requests.post(
    BASE + "/leads",
    json=payload,
    headers={
        "Authorization": f"Bearer {API_KEY}",
        "Idempotency-Key": str(uuid.uuid4())
    },
    timeout=30,
)
r.raise_for_status()
print(r.json())

Что происходит после отправки

Принятый lead создаётся со статусом imported. Дальше MIGI проводит модерацию и может перевести его в review, on_sale, sold или rejected.

{
  "ok": true,
  "apiVersion": "v1",
  "batchId": "...",
  "accepted": 1,
  "duplicates": 0,
  "rejected": 0,
  "total": 1,
  "items": [{
    "externalId": "36854194",
    "source": "ss.ge",
    "accepted": true,
    "duplicate": false,
    "partnerLeadId": "...",
    "status": "imported",
    "qualityScore": 100,
    "warnings": []
  }]
}

Batch может быть принят частично. Некорректные элементы возвращаются с rejected:true, code и error, а корректные элементы из того же batch сохраняются.

Ошибки и правила

CodeMeaning
API_KEY_INVALIDКлюч отсутствует, неверный или отозван
LEADS_REQUIREDНет лидов в запросе
BATCH_TOO_LARGEБольше 100 лидов
IDEMPOTENCY_CONFLICTОдин Idempotency-Key использован для разных payload
EXTERNAL_ID_REQUIREDНет external/source listing/property group ID
LEAD_CONTENT_REQUIREDНет title, description и source_url
SOURCE_NOT_ALLOWEDЭтот API key не разрешён для такой площадки
LEAD_TOO_LARGEОдин JSON lead больше 64 KiB
RATE_LIMITEDСлишком много запросов

Рекомендации

Используйте batch по 20–50 лидов, хотя hard limit — 100. Для каждой отправки создавайте уникальный Idempotency-Key. Один и тот же объект повторно не создаст новый lead: dedup работает в рамках партнёра по source + external_id.

Чек-лист подключения

  1. Получить API key от MIGI.
  2. Вызвать GET /health.
  3. При желании прочитать GET /schema.
  4. Отправить один тестовый объект через POST /leads.
  5. Проверить ответ accepted: 1.
  6. Проверить статус через GET /leads/:externalId?source=....
  7. После теста включить batch-синхронизацию.
Copied