UK

Тема

Колір акценту

Тема й колір збережуться на satelit.md і в застосунку.

Панель Обрати тариф

Webhooks

Замість того щоб опитувати API щохвилини, ви отримуєте POST, коли є щось нове. Адрес на тарифі: 2 на Creator, 10 на Pro, 50 на Business.

Події

  • news.publishedНова новина із серйозністю щонайменше як min_gravity адреси, за замовчуванням 50.
  • law.digestЗаконодавчий дайджест дня готовий.
  • fuel.capANRE опублікувала нову граничну ціну.
  • rates.updatedBNM опублікував курс дня.
  • price.changedЦіна відстежуваного товару змінилася в магазині. Адреса може містити до 500 товарів у items. Порівняння виконується кожні 30 хвилин.

Що ви отримуєте

POST з JSON і двома заголовками: Satelit-Event і Satelit-Signature.

POST
{
  "id": "evt_01J9ZK3Q",
  "type": "price.changed",
  "created_at": "2026-11-02T13:30:00+02:00",
  "data": {
    "item": 18342,
    "store": "kaufland",
    "old": 17.19,
    "new": 16.05,
    "at": "2026-11-02T13:12:00+02:00"
  }
}

Перевірте підпис

Заголовок виглядає так: t=<unix>,v1=<підпис>. Підпис це HMAC-SHA256 із секретом адреси над рядком t.body: момент, крапка й точне, незмінене тіло. Відхиляйте момент, старший за 5 хвилин, щоб зупиняти повторні надсилання.

Секрет показується лише один раз, коли ви створюєте адресу в панелі. Зберігайте його на своєму сервері.

import { createHmac, timingSafeEqual } from "node:crypto";

// rawBody: the request body exactly as it arrived, before any JSON parsing
export function verify(rawBody, header, secret, tolerance = 300) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > tolerance) return false;
  const expected = Buffer.from(createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex"));
  const given = Buffer.from(parts.v1 ?? "");
  return expected.length === given.length && timingSafeEqual(expected, given);
}
import hashlib
import hmac
import time


# raw_body: the request body exactly as it arrived, as bytes
def verify(raw_body, header, secret, tolerance=300):
    parts = dict(p.split("=", 1) for p in header.split(","))
    t = int(parts.get("t", 0))
    if abs(time.time() - t) > tolerance:
        return False
    signed = f"{t}.".encode() + raw_body
    expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts.get("v1", ""))
<?php
// $rawBody: the request body exactly as it arrived: file_get_contents("php://input")
function verify(string $rawBody, string $header, string $secret, int $tolerance = 300): bool {
    $parts = [];
    foreach (explode(",", $header) as $part) {
        [$k, $v] = array_pad(explode("=", $part, 2), 2, "");
        $parts[$k] = $v;
    }
    $t = (int) ($parts["t"] ?? 0);
    if (abs(time() - $t) > $tolerance) {
        return false;
    }
    $expected = hash_hmac("sha256", $t . "." . $rawBody, $secret);
    return hash_equals($expected, $parts["v1"] ?? "");
}

Як доставляється

  • Лише HTTPS, на публічні адреси. Перенаправлення не виконуються.
  • Ми чекаємо 5 секунд. Відповідь 2xx означає, що отримано.
  • Три спроби за 15 хвилин.
  • Після 20 невдач поспіль адреса зупиняється. Ви вмикаєте її знову з панелі.
  • Кожна подія має id. Зберігайте його, щоб ігнорувати дублікати.

Перевірка

З панелі ви надсилаєте тестову подію й бачите останні доставки зі статусами.

Webhooks