Documentation

Webhooks

Send Dirstarter domain events to your own automation (n8n, Zapier, Make) with outbound webhooks

Dirstarter emits domain events (a tool is submitted, a tool changes status, a paid tier is upgraded, a report comes in) and can fan them out to two outlets: transactional emails and an optional outbound webhook. The webhook lets you drive your own automation (n8n, Zapier, Make, or any HTTP endpoint) whenever something happens in your directory.

Webhooks are off by default. Set WEBHOOK_URL and every event starts POSTing to it; leave it unset and the feature is a silent no-op.

Setup

Point WEBHOOK_URL at your receiver. An optional WEBHOOK_TOKEN is sent as a Bearer header so the receiver can verify the request came from you.

.env
WEBHOOK_URL="https://n8n.example.com/webhook/dirstarter"
WEBHOOK_TOKEN="a-shared-secret" # Optional

Delivery runs after the response is sent (after()), so it never blocks the request. Errors are logged and swallowed: there is no queue or retry, since the mutation has already committed.

Payload

Each event is delivered as a small JSON envelope. The data payload is intentionally flat: ids, enums and scalars, never a serialized model. A receiver that needs full detail looks it up by id, which is exactly how a real automation (n8n / Zapier) works.

{
  "id": "clx0abc123...",
  "event": "tool.status_changed",
  "site": "your-directory",
  "timestamp": "2026-08-27T10:00:00.000Z",
  "data": {
    "toolId": "clx0tool456...",
    "previousStatus": "Draft",
    "newStatus": "Published",
    "notifySubmitter": true
  }
}

The id is unique per delivery, so a receiver can dedupe. When WEBHOOK_TOKEN is set, the request carries Authorization: Bearer <token>.

Events

EventFires when
tool.submittedA user submits a tool
tool.status_changedA tool's status changes, including admin create, admin edit, and the publish cron. previousStatus is null when the tool was created straight into its status
tool.tier_upgradedA tool is upgraded to a paid tier via Stripe
tool.tier_downgradedA paid tool is downgraded to Free
report.createdA user reports a tool
post.status_changedA blog post's status changes, including create and the publish cron

To key off publishing (e.g. share newly published tools on socials), listen for tool.status_changed where newStatus is Published. It catches admin publishes, create-as-published, and the cron alike.

Extending

Everything lives in server/events.ts. Adding an event is one line in the EventMap plus a sendEvent("your.event", { ... }) call at the emit site. Adding an email for it is one case in server/event-emails.ts; adding another outlet (Slack, Discord) is one function in the Promise.allSettled array.

Last updated on

On this page

Join hundreds of directory builders

Build your directory, launch, earn

Don't waste time on Stripe subscriptions or designing a pricing section. Get started today with our battle-tested stack and built-in monetization features.

Get Lifetime Access