Skip to content

API Overview

WebHooker exposes an HTTP API via Nitro on Cloudflare Workers.

Base URL

https://your-worker.workers.dev

Endpoints

MethodPathAuthDescription
GET/healthNoneHealth check
POST/webhookHMAC signatureGitHub / Gitea / custom webhook ingestion (provider auto-detected)
POST/webhook/:groupIdPer-group secretPer-group webhook ingress (only that group's routes fire)
POST/discord/interactionsEd25519 signatureDiscord interactions (slash commands, buttons, modals)
POST/telegram/webhookSecret tokenTelegram updates (bot /gh commands)
GET/api/richheaderNoneOpen Graph page for the Telegram avatar link-preview card
GET/auth/githubNoneStart GitHub OAuth flow
GET/auth/github/callbackNoneOAuth callback
GET/auth/github/installAdmin sessionPost-install choice page: bind the installation to a group
POST/auth/github/install/bindAdmin sessionProvision the chosen installation binding
DELETE/auth/token/:userIdAdmin sessionRevoke user token
POST/api/commentBearer tokenCreate issue comment
POST/api/mergeBearer tokenMerge pull request
POST/api/closeBearer tokenClose pull request
POST/api/reactBearer tokenAdd reaction to issue
GET/adminAdmin sessionConfig console UI
GET/admin/loginNoneStart admin sign-in (GitHub OAuth)
GET/admin/logoutAdmin sessionSign out and destroy the session
GET/admin/inviteAdmin sessionAccept a group invite (browser page, ?token=…)

The /admin/api/* endpoints (routes, groups, members, invites, webhook secrets, send logs, audit log) are documented separately in the Admin API.

Admin Console

See Configuration → Web UI for setup, and the Admin API reference for all management endpoints. Admin endpoints require a session cookie obtained via GET /admin/login (GitHub OAuth); the signed-in user must be listed in ADMIN_USER_IDS or manage a group.

Health Check

GET /health

Response:

json
{
  "status": "ok"
}

Webhook Ingestion

POST /webhook

Accepts GitHub webhook payloads. Requires valid X-Hub-Signature-256 header.

Headers:

HeaderRequiredDescription
X-Hub-Signature-256YesHMAC-SHA256 signature
X-GitHub-EventYesEvent type name
X-GitHub-DeliveryNoUnique delivery ID (used for dedup when present)

Request Body: GitHub webhook JSON payload (max 1MB).

Response:

json
{
  "ok": true
}

When X-GitHub-Delivery is present and the same delivery was already processed within the last 5 minutes, the worker responds 200 { "ok": true, "duplicate": true } without re-dispatching.

Error Responses:

StatusBodyCause
401{"error": "Invalid signature"}Signature verification failed
400{"error": "Invalid event"}Missing event header or malformed body
413{"error": "Request too large"}Body exceeds 1MB limit

Per-Group Webhook (POST /webhook/:groupId)

Verifies the payload against the group's secret (KV tenant:{groupId}, generated from the console — Webhook endpoint panel) instead of the global secrets, and dispatches only into that group's routes. Works for GitHub (X-Hub-Signature-256), Gitea (X-Gitea-Signature) and custom (X-WebHooker-Signature) senders. Returns 404 when the group does not exist or has no secret configured.

Custom Webhooks

Any JSON payload signed with X-WebHooker-Signature: sha256=<hex> (HMAC-SHA256 of the raw body, group or global secret) becomes a custom event. Route it with a route whose filter is event: custom. Optional X-WebHooker-Timestamp + X-WebHooker-Nonce headers enable replay protection (signature over {timestamp}.{nonce}.{body}, ±5 min window, nonce dedup). Payload schema: see Configuration → Custom webhooks.

GitHub App Installation Events

installation webhook events (created, ...) are auto-provisioned as a fallback: a group named after the installing account (inst-{installationId}, bound via installationId) is created automatically, or existing groups whose owners match the installing account are bound to the installation. See Configuration → GitHub App tenant isolation.

The primary flow is the App's Setup URL — set it to {BASE_URL}/auth/github/install. After a user installs the App, the browser lands on:

MethodPathDescription
GET/auth/github/installChoice page: bind the installation to a new group or an existing group the signed-in user owns
POST/auth/github/install/bindProvisions the binding (owner role re-checked) and redirects to /admin?install=ok

Error Format

All error responses follow the format:

json
{
  "error": "Description of the error"
}

Released under the MIT License.