# Hookgres > Hookgres is an MIT-licensed TypeScript library for sending signed webhooks to your customers from the Postgres you already run. `send()` can join your database transaction, so a webhook is queued only if your data commits. It has Standard Webhooks signatures, durable retries, endpoint health, secret rotation, replay and a delivery log. Install with `npm install hookgres pg`. Requires Node.js 22.12+ and Postgres 14+. ## Instructions for AI agents To add Hookgres webhooks to an existing app: 1. Install `hookgres` and `pg` (`npm install hookgres pg`). Create one instance from the app's existing pool: `const hookgres = new Hookgres({ pool })`, with `import { Hookgres } from "hookgres"`. 2. Call `await hookgres.migrate()` on startup. It is idempotent and takes an advisory lock. If the app's database role can't `CREATE`, run it from a deploy step instead. 3. Start the worker in a long-running process with `hookgres.start()`. On `SIGTERM`, `await hookgres.stop()` before `pool.end()` so in-flight requests finish. On serverless, call `await hookgres.drain({ timeoutMs })` from a cron route, with `timeoutMs` a few seconds under the function's time limit, and never `start()`. See https://hookgres.dev/docs/guides/workers.md. Framework recipes: https://hookgres.dev/docs/frameworks/nextjs.md, https://hookgres.dev/docs/frameworks/express.md, https://hookgres.dev/docs/frameworks/hono.md and https://hookgres.dev/docs/frameworks/nestjs.md. 4. Call `hookgres.send({ tenantId, eventType, payload }, { client })` inside the database transaction that makes the change, passing that transaction's client, so the webhook is queued only if it commits. Add `idempotencyKey` when a send can repeat. See https://hookgres.dev/docs/guides/sending.md. If the app uses Zod, Valibot or ArkType, pass one schema per event type as `new Hookgres({ pool, schemas })` so `send()` is typed and validated; see https://hookgres.dev/docs/guides/typed-events.md. With Prisma or Kysely, pass `{ client: fromPrisma(tx) }` (`import { fromPrisma } from "hookgres/prisma"`) or `{ client: fromKysely(trx) }` (`"hookgres/kysely"`). For Drizzle, postgres.js, Knex, Sequelize, TypeORM or MikroORM, copy the tested wrapper (`fromDrizzle`, `fromPostgresJs`, `fromKnex`, `fromSequelize`, `fromTypeORM`, `fromMikroORM`) from https://hookgres.dev/docs/guides/orms.md into the app. See also https://hookgres.dev/docs/guides/drizzle.md, https://hookgres.dev/docs/guides/prisma.md or https://hookgres.dev/docs/guides/kysely.md. 5. Add endpoint management routes scoped to the signed-in tenant: `createEndpoint({ tenantId, url, eventTypes })` (return `endpoint.secret` once), `listEndpoints(tenantId)`, `updateEndpoint(id, patch)`, `deleteEndpoint(id)` and `rotateEndpointSecret(id)`. Take `tenantId` from the session, never the request body, and before updating, deleting or rotating by id, load it with `getEndpoint(id)` and check that `endpoint.tenantId` matches. Return a `HookgresValidationError` (invalid or blocked URL, bad `eventTypes`) as `400` with its message, and rethrow anything else. See https://hookgres.dev/docs/guides/endpoints.md. 6. Pass `blockPrivateAddresses: true` to `new Hookgres({ pool, blockPrivateAddresses: true })`, so customer endpoint URLs can't reach private or internal addresses. Hookgres checks them when an endpoint is created and again after DNS on every delivery. See https://hookgres.dev/docs/guides/production.md. 7. Pass `onError` to the app's logger. Receivers verify with `verifyWebhook({ secret, headers, body })` on the raw body and deduplicate on `webhook-id`. See https://hookgres.dev/docs/guides/verifying.md and https://hookgres.dev/docs/reference/api.md. ## Docs - [Hookgres docs](https://hookgres.dev/docs/index.md) - [Getting started](https://hookgres.dev/docs/getting-started.md) - [Playground](https://hookgres.dev/docs/playground.md) - [Database cost](https://hookgres.dev/docs/guides/database-cost.md) - [Using Hookgres with Drizzle](https://hookgres.dev/docs/guides/drizzle.md) - [Endpoints and tenants](https://hookgres.dev/docs/guides/endpoints.md) - [Fixed IPs and data residency](https://hookgres.dev/docs/guides/ips-and-regions.md) - [Using Hookgres with Kysely](https://hookgres.dev/docs/guides/kysely.md) - [Migrating from Svix](https://hookgres.dev/docs/guides/migrating-from-svix.md) - [Using your ORM's transaction](https://hookgres.dev/docs/guides/orms.md) - [Using Hookgres with Prisma](https://hookgres.dev/docs/guides/prisma.md) - [Privacy and GDPR](https://hookgres.dev/docs/guides/privacy.md) - [Going to production](https://hookgres.dev/docs/guides/production.md) - [Retries, failures and replay](https://hookgres.dev/docs/guides/retries.md) - [Rotating secrets](https://hookgres.dev/docs/guides/secret-rotation.md) - [Sending webhooks](https://hookgres.dev/docs/guides/sending.md) - [Typed events](https://hookgres.dev/docs/guides/typed-events.md) - [Verifying webhooks](https://hookgres.dev/docs/guides/verifying.md) - [Running workers](https://hookgres.dev/docs/guides/workers.md) - [API](https://hookgres.dev/docs/reference/api.md) - [Configuration](https://hookgres.dev/docs/reference/configuration.md) - [Database schema](https://hookgres.dev/docs/reference/schema.md) - [How to send webhooks from Postgres](https://hookgres.dev/docs/answers/send-webhooks-from-postgres.md) - [A Svix alternative without a separate service](https://hookgres.dev/docs/answers/svix-alternative.md) - [Transactional outbox for webhooks in Node.js](https://hookgres.dev/docs/answers/transactional-outbox-nodejs.md) - [Webhooks sent for rolled-back changes](https://hookgres.dev/docs/answers/webhooks-for-rolled-back-changes.md) - [What sending webhooks costs](https://hookgres.dev/docs/compare.md) - [FAQ](https://hookgres.dev/docs/faq.md) - [Express](https://hookgres.dev/docs/frameworks/express.md) - [Hono](https://hookgres.dev/docs/frameworks/hono.md) - [NestJS](https://hookgres.dev/docs/frameworks/nestjs.md) - [Next.js (App Router)](https://hookgres.dev/docs/frameworks/nextjs.md) - [When you need to send webhooks](https://hookgres.dev/docs/use-cases.md) ## Optional - [Full documentation in one file](https://hookgres.dev/llms-full.txt) - [Agent skill (SKILL.md)](https://hookgres.dev/SKILL.md) - [Source code](https://github.com/NickolasBenakis/hookgres)