Webhooki
Zaktualizowano Aug 2026 · API v3Zarejestruj endpoint HTTPS, a pon zawoła Ciebie, gdy coś się wydarzy — bez pętli pollingu, bez zmarnowanych requestów. Webhookami zarządzasz na my.pon.app → Webhooki albo przez API.
Topiki
| Topic | Kiedy się uruchamia |
|---|---|
list.changed |
Cokolwiek w liście się zmieniło (zgrubne, łączone — wartość domyślna) |
item.added |
Produkt trafił na listę |
item.removed |
Produkt został usunięty |
item.checked |
Produkt został odhaczony podczas zakupów (cofnięcie odhaczenia uruchamia tylko list.changed) |
list.members.changed |
Ktoś dołączył do listy albo ją opuścił |
Subskrybuj to, czego faktycznie potrzebujesz. Opcjonalny filtr listIds
(do 50, tylko Twoje własne listy — nieznane id odpowiadają 400 z
invalidListIds) zawęża dostawy do konkretnych list.
Rejestracja
POST /v3/webhooks
curl -X POST https://api.pon.app/v3/webhooks \
-H "Authorization: Bearer pon_pat_XXXX" \
-H "Content-Type: application/json" \
-d '{ "url": "https://hooks.example.com/pon",
"events": ["item.checked"],
"listIds": ["LIST_ID"] }'
Odpowiedź zawiera Twój sekret do podpisów (whsec_…) — pokazany raz.
Ponowna rejestracja tego samego URL-a aktualizuje subskrypcję i zachowuje
sekret. Do 5 webhooków na konto.
Rejestracja od razu pinguje Twój URL.
pon wysyła podpisany eventping i oczekuje 2xx — odpowiedz na niego, zanim sprawdzisz podpis (sekret przychodzi dopiero w odpowiedzi). Martwy URL zostaje odrzucony z 422 WEBHOOK_UNREACHABLE.Dostawy
Każda dostawa to POST z nagłówkami PON-Event: <topic> i
PON-Signature: sha256=<hmac>:
{ "event": "item.checked", "listId": "6led…", "cursor": 123, "at": "2026-08-09T19:00:00.000Z" }
Dostawy są best-effort, bez ponowień — jeśli Twój endpoint leży, kolejny event (albo fetch po Twojej stronie) nadrobi zaległości. Przekierowania nie są śledzone. Kilka pasujących zmian w jednym zapisie łączy się w jedną dostawę na subskrybowany topic.
Weryfikacja podpisu
Policz HMAC-SHA256 z surowego body requestu swoim sekretem i porównaj go — w stałym czasie — z nagłówkiem:
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(rawBody, header, secret) {
const expected = "sha256=" +
createHmac("sha256", secret).update(rawBody).digest("hex");
return (
header.length === expected.length &&
timingSafeEqual(Buffer.from(header), Buffer.from(expected))
);
}import hashlib, hmac
def verify(raw_body: bytes, header: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(
secret.encode(), raw_body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(header, expected)Circuit breaker
2xx potwierdza dostawę. Po 20 kolejnych niepowodzeniach (cokolwiek
innego, łącznie z timeoutami) webhook automatycznie się pauzuje
(status: paused, pausedReason: auto_failures). Napraw endpoint, a potem
reaktywuj go na my.pon.app albo przez PATCH
/v3/webhooks/{id} z { "status": "active" } — reaktywacja zeruje
licznik. Ręczny testowy ping to POST
/v3/webhooks/{id}/pings (nigdy nie liczy się jako niepowodzenie).
Webhooki wygrywają z pollingiem — zawsze.
Pętla pollingu co 5 minut robi ~8 600 requestów miesięcznie i liczy się jako intensywne użycie na wskaźniku fair use. Webhook robi ich dokładnie tyle, ile razy zmieniają się Twoje listy.