This document describes all HTTP endpoints provided by the Webhook server.
By default, the Webhook server runs on port 9000. The base URL format is:
http://your-server:9000
You can customize the IP address and port using the -ip and -port command-line arguments or environment variables.
Reserved paths and path conflicts: Do not set -openapi-path or -config-ui-path to a path that conflicts with reserved endpoints. Reserved paths include /, /health, /livez, /readyz, /version, /metrics, and the hook base path (e.g. /hooks). If a conflict is detected at startup, the server will skip registering that route and log a warning.
Endpoint: GET /
Description: Simple health check endpoint that returns "OK".
Response:
- Status Code:
200 OK - Content-Type:
text/plain - Body:
OK
Example:
curl http://localhost:9000/Endpoint: GET /health
Description: Health check endpoint that returns server status in JSON format.
Response:
- Status Code:
200 OK - Content-Type:
application/json - Body:
{
"status": "ok"
}Example:
curl http://localhost:9000/healthNote: The exact JSON structure is defined by the health check library (e.g. it may include multiple check results). For the precise schema, see the OpenAPI spec when -openapi is enabled.
Endpoints: GET /livez, GET /readyz
Description: Kubernetes-style liveness and readiness probes. /livez indicates the process is running; /readyz reports whether the server is ready to accept traffic (e.g. after loading hooks).
Response:
- Status Code:
200 OKwhen healthy/ready; non-2xx when not. - Content-Type:
application/json - Body: Implementation-defined JSON (see OpenAPI spec for schema when
-openapiis enabled).
Example:
curl http://localhost:9000/livez
curl http://localhost:9000/readyzEndpoint: GET /version
Description: Returns server version and build information in JSON format, with optional X--prefixed response headers for version details.
Response:
- Status Code:
200 OK - Content-Type:
application/json - Body: JSON with version fields (e.g.
version,commit,buildDate,branch). Exact structure is defined by the version library; use the OpenAPI spec when-openapiis enabled for the full schema.
Example:
curl http://localhost:9000/versionEndpoint: GET /metrics
Description: Prometheus metrics endpoint for monitoring and observability.
Response:
- Status Code:
200 OK - Content-Type:
text/plain; version=0.0.4; charset=utf-8 - Body: Prometheus metrics in text format
Example:
curl http://localhost:9000/metricsAvailable Metrics:
webhook_http_requests_total: Total number of HTTP requestswebhook_http_request_duration_seconds: HTTP request duration histogramwebhook_hook_executions_total: Total number of hook executionswebhook_hook_execution_duration_seconds: Hook execution duration histogramwebhook_system_memory_bytes: System memory usagewebhook_system_cpu_percent: System CPU usage percentage
Endpoint: GET /openapi (or custom path via -openapi-path)
Availability: Only when the server is started with the -openapi flag (or OPENAPI_ENABLED=true). Not exposed by default. Recommend use only for debugging or intranet.
Description: Returns the OpenAPI 3.0.x specification (JSON) for the webhook HTTP API. Use with Swagger UI, Swagger Editor, or client code generators.
Response:
- Status Code:
200 OK - Content-Type:
application/json; charset=utf-8 - Body: OpenAPI 3.0.3 document describing
/,/health,/livez,/readyz,/version,/metrics, and/hooks/{id}(or custom hook prefix).
Example:
# Start server with OpenAPI enabled
./webhook -hooks hooks.json -openapi
# Fetch the spec
curl http://localhost:9000/openapiYou can also print the spec to stdout at startup with -openapi-print (e.g. ./webhook -openapi -openapi-print > openapi.json).
Endpoints: GET /config-ui, GET /config-ui/, POST /config-ui/api/generate (or custom path via -config-ui-path)
Availability: Config UI is mounted on the webhook server when -config-ui is enabled (path via -config-ui-path, default /config-ui). Not exposed by default; recommend use only for debugging or intranet.
Description: Web UI and API for generating hook configuration (YAML/JSON) and call examples.
- GET
{config-ui-path}or{config-ui-path}/: Returns the config generator HTML page. - GET
{config-ui-path}/static/*: Static assets (CSS, JS). - POST
{config-ui-path}/api/generate: Accepts JSON body with form fields (e.g.id,execute-command,response-message,trigger-rule). Returns{ "yaml", "json", "callUrl", "curlExample" }on success, or{ "error": "..." }with 4xx on validation error. - GET
{config-ui-path}/api/capabilities: Returns{ "saveToDir": true|false }. Whentrue, the UI shows a "Save to directory" option (directory mode: default./hooksor explicit-hooks-dir). - POST
{config-ui-path}/api/save: Writes generated config to hooks directory. Body:{ "filename": "name.yaml", "content": "...", "format": "yaml|json" }. Returns{ "ok": "<absolute-path>" }on success, or{ "error": "..." }with 4xx when disabled or invalid (e.g. path traversal, format mismatch, invalid hook config). Filename must have extension.json,.yaml, or.yml.
Example:
# Enable Config UI on webhook server (default port 9000)
./webhook -config-ui
# Open http://localhost:9000/config-ui in a browserEndpoint: POST|GET|PUT|DELETE /hooks/{hook-id}
Description: Execute a configured hook. The HTTP methods allowed depend on the hook configuration and the -http-methods flag.
URL Parameters:
hook-id(required): The ID of the hook to execute, as defined in your hooks configuration file.
Request Headers:
Content-Type: Optional. Can beapplication/json,application/x-www-form-urlencoded,multipart/form-data, ortext/plain.X-Request-Id: Optional. If provided and-x-request-idis enabled, this will be used as the request ID for logging.
Request Body: The request body can contain:
- JSON data
- Form data (URL-encoded or multipart)
- Plain text
- Query parameters (for GET requests)
Response:
-
Status Code:
200 OK: Hook executed successfully400 Bad Request: Invalid request (e.g., malformed JSON, missing required parameters)404 Not Found: Hook ID not found405 Method Not Allowed: HTTP method not allowed for this hook408 Request Timeout: Request timeout429 Too Many Requests: Rate limit exceeded (if rate limiting is enabled)500 Internal Server Error: Server error during hook execution503 Service Unavailable: Server is shutting down- Custom status code: As configured in
success-http-response-codeortrigger-rule-mismatch-http-response-code
-
Content-Type:
text/plain(default)application/json(if error occurs)- As configured in
response-headers
-
Response Body:
- Success: Custom message from
response-message, command output (ifinclude-command-output-in-responseis enabled), or default message - Error: JSON error response with details
- Success: Custom message from
Error Response Format:
{
"error": "Error Type",
"message": "Error message",
"request_id": "request-id-here",
"hook_id": "hook-id-here"
}Example - Successful Execution:
# POST request with JSON body
curl -X POST http://localhost:9000/hooks/redeploy-webhook \
-H "Content-Type: application/json" \
-d '{"branch": "main", "commit": "abc123"}'
# GET request with query parameters
curl "http://localhost:9000/hooks/redeploy-webhook?branch=main&commit=abc123"Example - Hook Not Found:
curl -X POST http://localhost:9000/hooks/non-existent-hookResponse:
{
"error": "Not Found",
"message": "Hook not found.",
"request_id": "req-123",
"hook_id": "non-existent-hook"
}Example - Method Not Allowed:
# If hook only allows POST, but we send GET
curl -X GET http://localhost:9000/hooks/post-only-hookResponse:
{
"error": "Method Not Allowed",
"message": "HTTP GET method not allowed for hook \"post-only-hook\"",
"request_id": "req-456",
"hook_id": "post-only-hook"
}Webhook automatically generates a unique request ID for each request. This ID is used for:
- Logging and tracing
- Error responses
- Request correlation
You can customize the request ID behavior:
- Use
-x-request-idto use theX-Request-Idheader if present - Use
-x-request-id-limitto limit the length of theX-Request-Idheader
The request ID appears in:
- Server logs
- Error responses
- Debug output
You can set custom response headers using the -header flag:
webhook -header "X-Custom-Header=value" -header "X-Another-Header=another-value"These headers will be included in all responses.
You can also configure response headers per hook in your hooks configuration:
{
"id": "my-hook",
"execute-command": "/path/to/script.sh",
"response-headers": [
{
"name": "X-Custom-Header",
"value": "custom-value"
}
]
}If rate limiting is enabled (via -rate-limit-enabled, -rate-limit-rps, and -rate-limit-burst), the server will return 429 Too Many Requests when the rate limit is exceeded.
Response Headers:
X-RateLimit-Limit: Maximum number of requests allowedX-RateLimit-Remaining: Number of requests remaining in the current windowX-RateLimit-Reset: Time when the rate limit resets
To enable CORS, use the -header flag to set CORS headers:
webhook -header "Access-Control-Allow-Origin=*" \
-header "Access-Control-Allow-Methods=GET,POST,OPTIONS" \
-header "Access-Control-Allow-Headers=Content-Type"The server has configurable timeouts:
-read-header-timeout-seconds: Time to read request headers (default: 5 seconds)-read-timeout-seconds: Time to read request body (default: 10 seconds)-write-timeout-seconds: Time to write response (default: 30 seconds)-idle-timeout-seconds: Time to keep idle connections (default: 90 seconds)-hook-timeout-seconds: Time for hook execution (default: 30 seconds)
If a timeout occurs, the server will return an appropriate error response.
If a hook has stream-command-output enabled, the command's stdout and stderr are streamed in real-time to the HTTP response. This is useful for long-running commands.
Example:
curl -X POST http://localhost:9000/hooks/long-running-hookThe response will stream the command output as it is produced.
| Status Code | Description |
|---|---|
| 200 | Success |
| 400 | Bad Request - Invalid request format or parameters |
| 404 | Not Found - Hook ID not found |
| 405 | Method Not Allowed - HTTP method not allowed for this hook |
| 408 | Request Timeout |
| 429 | Too Many Requests - Rate limit exceeded |
| 500 | Internal Server Error - Server error during execution |
| 503 | Service Unavailable - Server is shutting down |
-
Use HTTPS: Always use a reverse proxy (nginx, Traefik, etc.) to provide HTTPS in production.
-
Set Request Timeouts: Configure appropriate timeouts based on your use case.
-
Enable Rate Limiting: Use rate limiting to prevent abuse.
-
Use Request IDs: Include
X-Request-Idheaders for better traceability. -
Monitor Metrics: Use the
/metricsendpoint for monitoring and alerting. -
Handle Errors Gracefully: Check status codes and parse error responses appropriately.
-
Use Health Checks: Monitor the
/healthendpoint for service availability.