API синхронизации

Версия v2. Базовый адрес https://metersync.ru/api/v2/. Все запросы — по HTTPS, тело в JSON, кодировка UTF-8.

Авторизация

Каждый узел (УСПД, шлюз, интеграция) получает свой ключ в кабинете. Ключ передаётся заголовком X-Node-Key и действует только для привязанного узла — компрометация одного шлюза не открывает остальные.

X-Node-Key: ms_node_8f21c0a4e7b3
Content-Type: application/json

Приём показаний

POST /api/v2/sync/readings — основной метод. Пакет до 5000 показаний за запрос.

curl -X POST https://metersync.ru/api/v2/sync/readings \
  -H "X-Node-Key: $METERSYNC_NODE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"node":"uspd-4412","ts":"2026-07-28T09:00:00+03:00",
    "readings":[{"serial":"41250087","t1":18432.71,"t2":9014.05}]}'
import os, requests

r = requests.post(
  "https://metersync.ru/api/v2/sync/readings",
  headers={"X-Node-Key": os.environ["METERSYNC_NODE_KEY"]},
  json={"node": "uspd-4412", "ts": ts, "readings": batch},
  timeout=10,
)
r.raise_for_status()
print(r.json()["batch_id"])
const res = await fetch("https://metersync.ru/api/v2/sync/readings", {
  method: "POST",
  headers: {
    "X-Node-Key": process.env.METERSYNC_NODE_KEY,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ node, ts, readings })
});
const { batch_id, rejected } = await res.json();
Соединение = Новый HTTPСоединение("metersync.ru", 443, , , , , Новый ЗащищенноеСоединениеOpenSSL);
Запрос = Новый HTTPЗапрос("/api/v2/sync/readings");
Запрос.Заголовки.Вставить("X-Node-Key", КлючУзла);
Запрос.Заголовки.Вставить("Content-Type", "application/json");
Запрос.УстановитьТелоИзСтроки(ТелоJSON, КодировкаТекста.UTF8);
Ответ = Соединение.ОтправитьДляОбработки(Запрос);

Поля показания

ПолеТипОписание
serialstringЗаводской номер прибора. Обязательное.
t1…t4numberПоказания по тарифным зонам, кВт·ч / м³ / Гкал.
tsstringВремя съёма, ISO 8601 со смещением. По умолчанию — время пакета.
statusstringok, no_link, tamper, stale.

Идемпотентность

Повторная отправка того же пакета не задваивает данные. Ключ идемпотентности — пара node + ts, либо явный заголовок Idempotency-Key. При повторе возвращается исходный batch_id и "duplicate": true.

# повтор после обрыва связи — безопасен
-H "Idempotency-Key: uspd-4412-2026-07-28T09"

Выгрузка срезов

GET /api/v2/export/slices — часовые или суточные срезы за период.

curl -G https://metersync.ru/api/v2/export/slices \
  -H "X-Node-Key: $METERSYNC_NODE_KEY" \
  --data-urlencode "from=2026-07-01" \
  --data-urlencode "to=2026-07-28" \
  --data-urlencode "granularity=day" \
  --data-urlencode "format=csv"

Поддерживаемые форматы: json, csv, xml80020.

События приборов

СобытиеКогда
meter.no_linkПрибор не отвечает дольше порога опроса.
meter.tamperОтметка вскрытия корпуса или магнитного воздействия.
meter.rollbackПоказание меньше предыдущего (обратный ход или замена).
node.offlineУСПД не выходил на связь дольше двух интервалов.

События доставляются вебхуком с подписью X-MS-Signature (HMAC-SHA256 тела) и повторами по экспоненте до 24 часов.

Коды ошибок

КодHTTPЧто делать
node_key_missing401Не передан заголовок X-Node-Key.
node_key_revoked401Ключ отозван — выпустить новый в кабинете.
meter_unknown200Прибор не заведён; показание в rejected.
reading_rollback200Показание меньше предыдущего — требуется акт замены.
batch_too_large413Больше 5000 показаний — разбить пакет.
rate_limited429Подождать Retry-After секунд.

Лимиты

ТарифЗапросов/сПоказаний в пакетеХранение срезов
Старт25003 месяца
Базовый2050003 года
Промышленныйпо договору5000от 5 лет