Tier-2 reconciliation client for Hookon.
Call hookon.ack(event.id) inside your webhook handler. Hookon polls your
provider's deliveries API and cross-references your acks; an event the provider
says was delivered but that never acked here is a silent drop.
npm install @hookon/sdk
Zero runtime dependencies. Works on Node 18+, Bun, Deno, and Cloudflare Workers.
import { Hookon } from '@hookon/sdk';
const hookon = new Hookon({
apiKey: process.env.HOOKON_API_KEY!,
endpoint: 'prod-stripe-handler', // human label, optional
});
// In your webhook handler
app.post('/webhooks/stripe', async (req, res) => {
const event = verifyStripeSignature(req);
await handleEvent(event);
hookon.ack(event.id); // one line
res.status(200).end();
});The call is synchronous and never throws. Acks are batched in the background (50 per request or 2 seconds, whichever comes first).
new Hookon({
apiKey: string, // required, from Settings · API keys
endpoint?: string, // human label for the handler; auto-created on first ack
baseUrl?: string, // default https://api.hookon.dev
fetch?: typeof fetch, // test-only override
})hookon.ack(eventId, { receivedAt? })— queue an ack. Never throws.await hookon.flush()— force-send pending acks. Useful in serverless handlers.await hookon.close()— stop accepting new acks and flush.
- Idempotent. Same
eventIdtwice is a no-op. Hookon keys on(workspace, providerEventId). - Forward-tolerant. If the SDK acks an event before our 60-second poll has seen it, we create a placeholder row; the next poll heals it with the real event metadata.
- Silent on failure. Auth and transport errors are warned to
console.warnat most once per failure mode. - Never throws from
ack(). A broken Hookon must never break your webhook handler.
- Docs: https://hookon.dev/docs/sdk/typescript
- Dashboard: https://hookon.dev
- Issues: https://github.com/hookondev/sdk-typescript/issues
MIT