Webhookd
Why trust online webhook services with your data when you can run your own webhooks? π£
Install / Use
/learn @4thel00z/WebhookdREADME
<div align="center">
<h1>webhookd</h1>
<p>
<img src="logo.png" alt="webhookd logo" width="320" />
</p>
<p><strong>Self-hosted webhook generator</strong> β create a webhook, get a URL, serve static JSON with custom headers.</p>
<p>
<a href="https://github.com/4thel00z/webhookd/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/4thel00z/webhookd/actions/workflows/ci.yml/badge.svg?branch=master" /></a>
<a href="https://github.com/4thel00z/webhookd/actions/workflows/release-please.yml"><img alt="release-please" src="https://github.com/4thel00z/webhookd/actions/workflows/release-please.yml/badge.svg?branch=master" /></a>
<a href="https://github.com/4thel00z/webhookd/actions/workflows/goreleaser.yml"><img alt="goreleaser" src="https://github.com/4thel00z/webhookd/actions/workflows/goreleaser.yml/badge.svg" /></a>
<a href="https://github.com/4thel00z/webhookd/releases"><img alt="Release" src="https://img.shields.io/github/v/release/4thel00z/webhookd?sort=semver" /></a>
<a href="COPYING"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-informational" /></a>
<a href="https://github.com/4thel00z/webhookd/pkgs/container/webhookd"><img alt="GHCR" src="https://img.shields.io/badge/ghcr-webhookd-blue" /></a>
</p>
</div>
What is this?
webhookd is a small daemon that lets you:
- create a webhook (
POST /v1/webhooks) - invoke it at a stable URL (
/v1/hooks/{id}) with the configured method - deactivate it (
DELETE /v1/webhooks/{id})
The HTTP layer is built with Fiber and documented with Huma (OpenAPI + JSON Schema). The CLI uses Fang.
Quickstart
Run locally (Go)
go run ./cmd/webhookd --port 1337
Or explicitly:
go run ./cmd/webhookd serve --port 1337
Run with Docker (GHCR)
docker run --rm -p 1337:1337 ghcr.io/4thel00z/webhookd:latest --host 0.0.0.0 --port 1337
API
Create a webhook
curl -s -X POST http://localhost:1337/v1/webhooks \
-H 'content-type: application/json' \
-d '{"method":"GET","body":"hello","headers":{}}'
Response contains the id and path (Huma also adds $schema):
{"$schema":"http://localhost:1337/schemas/Post-v1-webhooksResponse.json","id":"...","path":"/v1/hooks/..."}
Invoke it
curl -s http://localhost:1337/v1/hooks/<id>
Deactivate it
curl -s -X DELETE http://localhost:1337/v1/webhooks/<id>
OpenAPI / docs
- Docs UI:
GET /docs - OpenAPI:
GET /openapi.jsonandGET /openapi.yaml - JSON Schemas:
GET /schemas/*
Configuration
By default, webhookd looks for .webhookdrc.json. If it doesnβt exist, it starts with defaults.
Example:
{
"enable_auth_on_options": false,
"token_extractors": ["headers", "params"],
"oauth_json_web_key_sets_url": "https://example.com/.well-known/jwks.json",
"oauth_issuer": "https://example.com/",
"oauth_audience": "my-audience"
}
OpenTelemetry
Tracing is disabled by default. Enable it by setting either:
WEBHOOKD_OTEL_ENABLED=true, orOTEL_EXPORTER_OTLP_ENDPOINT/OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
Useful env vars:
WEBHOOKD_OTEL_ENABLED:true|falseWEBHOOKD_OTEL_EXPORTER_OTLP_ENDPOINT: OTLP HTTP endpoint (full URL orhost:port). Example:http://localhost:4318WEBHOOKD_OTEL_EXPORTER_OTLP_HEADERS: comma-separatedk=vpairsWEBHOOKD_OTEL_EXPORTER_OTLP_INSECURE: when usinghost:port, prefixes withhttp://instead ofhttps://WEBHOOKD_OTEL_TRACES_SAMPLER_RATIO:0..1(default1)WEBHOOKD_OTEL_SERVICE_NAME: override service name (defaultwebhookd)WEBHOOKD_ENV/ENV: setsdeployment.environment.name
Development
go test ./...
License
MIT β see COPYING.
