developers  · docsAccount
Ottieni il tuo token
Docs · Webhook

Webhooks

Aggiornato Aug 2026 · API v3

Registra un endpoint HTTPS e pon chiama te quando succede qualcosa — niente loop di polling, niente richieste sprecate. Gestisci i webhook su my.pon.app → Webhooks o via API.

Topic

Topic Scatta quando
list.changed Qualcosa in una lista è cambiato (grossolano, accorpato — il default)
item.added Un articolo è finito su una lista
item.removed Un articolo è stato eliminato
item.checked Un articolo è stato spuntato durante la spesa (togliere la spunta fa scattare solo list.changed)
list.members.changed Qualcuno è entrato o uscito da una lista

Iscriviti a ciò che ti serve davvero. Un filtro listIds opzionale (fino a 50, solo le tue liste — id sconosciuti rispondono 400 con invalidListIds) restringe le consegne a liste specifiche.

Registrazione

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"] }'

La risposta contiene il tuo segreto di firma (whsec_…) — mostrato una sola volta. Registrare di nuovo lo stesso URL aggiorna la sottoscrizione e mantiene il segreto. Fino a 5 webhook per account.

La registrazione pinga subito il tuo URL.

pon invia un evento ping firmato e si aspetta un 2xx — rispondi prima di controllare la firma (il segreto arriva solo nella risposta). Un URL morto viene rifiutato con 422 WEBHOOK_UNREACHABLE.

Consegne

Ogni consegna è una POST con gli header PON-Event: <topic> e PON-Signature: sha256=<hmac>:

{ "event": "item.checked", "listId": "6led…", "cursor": 123, "at": "2026-08-09T19:00:00.000Z" }

Le consegne sono best-effort, senza retry — se il tuo endpoint è giù, l’evento successivo (o un fetch dalla tua parte) ti rimette in pari. I redirect non vengono seguiti. Più cambiamenti corrispondenti in una stessa scrittura si accorpano in una sola consegna per topic sottoscritto.

Verificare la firma

Calcola un HMAC-SHA256 sul body grezzo della richiesta con il tuo segreto e confrontalo — in tempo costante — con l’header:

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

Un 2xx conferma una consegna. Dopo 20 fallimenti consecutivi (qualsiasi altra cosa, timeout inclusi) il webhook si mette in pausa da solo (status: paused, pausedReason: auto_failures). Sistema il tuo endpoint, poi riattivalo su my.pon.app o via PATCH /v3/webhooks/{id} con { "status": "active" } — la riattivazione azzera il contatore. Un ping di test manuale è POST /v3/webhooks/{id}/pings (non conta mai come fallimento).

I webhook battono il polling — sempre.

Un loop di polling da 5 minuti fa circa 8.600 richieste al mese e conta come uso intensivo sull’indicatore fair-use. Un webhook ne fa esattamente quante volte cambiano le tue liste.