API Base URL: https://hookpipe.app
API keys authenticate you for hook management. The key is shown once at creation — save it.
curl -X POST https://hookpipe.app/api/auth/keys \
-H "Content-Type: application/json" \
-d '{"name": "my-key"}'
A hook defines a receive endpoint, optional transform rules, and a destination URL.
curl -X POST https://hookpipe.app/api/hooks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "github-events",
"destinationUrl": "https://your-app.com/webhook",
"transformConfig": {
"fieldMapping": {
"repo": "repository.name",
"actor": "sender.login"
}
}
}'
The response includes an id — that's your hook ID for the receive URL.
Use https://hookpipe.app/hooks/YOUR_HOOK_ID as the webhook URL in whatever service you're integrating.
# Example: test it manually
curl -X POST https://hookpipe.app/hooks/YOUR_HOOK_ID \
-H "Content-Type: application/json" \
-d '{"repository": {"name": "my-repo"}, "sender": {"login": "dev"}}'
Detailed walkthroughs for specific use-cases. View all guides →
Transform rules are optional. If you don't set transformConfig, the payload is forwarded as-is.
Extract nested fields into a flat structure using dot notation:
"fieldMapping": {
"repo": "repository.name", // payload.repository.name → result.repo
"actor": "sender.login", // payload.sender.login → result.actor
"action": "action" // payload.action → result.action (top-level)
}
Only forward payloads that match conditions. If a filter doesn't match, the payload is dropped (HTTP 200 returned to sender, nothing forwarded).
"filters": [
{"field": "action", "operator": "equals", "value": "opened"},
{"field": "repository.name", "operator": "contains", "value": "prod"}
]
Supported operators: equals, notEquals, contains, notContains, exists, notExists, greaterThan, lessThan.
"renames": {
"old_field_name": "new_field_name"
}
Add constant values by including them directly in fieldMapping. Use a non-dot-notation key with a literal string:
"fieldMapping": {
"repo": "repository.name",
"source": "github",
"version": "1.0"
}
All /api/* endpoints require an API key in the Authorization header:
Authorization: Bearer YOUR_API_KEY
The webhook receive endpoint (POST /hooks/:hookId) is public — no auth required.
POST /api/auth/keys
Create a new API key. No authentication required.
| Body | Type | Description |
|---|---|---|
| name | string | A label for the key |
POST /api/hooks
Create a new hook. Requires auth.
| Body | Type | Description |
|---|---|---|
| name | string | Hook name |
| destinationUrl | string | URL to forward transformed payloads to |
| transformConfig | object | Optional. See Transform Rules |
GET /api/hooks
List all hooks. Requires auth.
GET /api/hooks/:id
Get a specific hook. Requires auth.
DELETE /api/hooks/:id
Delete a hook. Requires auth.
GET /api/hooks/:id/logs
Get request logs for a hook. Requires auth.
| Query | Type | Default | Description |
|---|---|---|---|
| limit | number | 100 | Max entries to return |
| offset | number | 0 | Skip entries |
GET /api/hooks/:id/payloads
List stored payloads for a hook (most recent first). Requires auth.
| Query | Type | Default | Description |
|---|---|---|---|
| limit | number | 50 | Max entries (max 200) |
| offset | number | 0 | Skip entries |
Response includes rawBody (original payload) and transformedBody (after transform rules, if any).
GET /api/hooks/:id/payloads/:payloadId
Get a single stored payload with full body. Requires auth.
POST /api/hooks/:id/payloads/:payloadId/replay
Re-run the transform → forward pipeline for a stored payload. Useful when the original forward failed (destination was down) and you want to retry. Requires auth.
The replayed request includes an X-Replay: true header so your destination can distinguish replays from original deliveries.
POST /hooks/:hookId
Receive a webhook. Public — no auth required. This is the URL you give to external services.
Payload is validated, stored, transformed (if rules exist), and forwarded to the hook's destination URL. Returns a payloadId for later inspection or replay.
GET /health
Health check. Returns {"status": "healthy"} with uptime.
Verify that incoming webhooks are authentic by checking their HMAC signatures. Supports GitHub, Stripe, and generic HMAC providers.
curl -X PATCH https://hookpipe.app/api/hooks/HOOK_ID/signature \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"provider": "github",
"secrets": ["your-webhook-secret"],
"debug": true
}'
Supported providers:
X-Hub-Signature-256 (SHA-256) with fallback to X-Hub-Signature (SHA-1)Stripe-Signature header with timestamp validation (rejects replays >5 min old)algorithm (e.g., "sha256") and headerName (e.g., "X-Signature")Free tier: 1 signing secret per hook. Pro tier: Up to 5 secrets for key rotation — all secrets are tried until one matches.
Set "debug": true during setup to see detailed error messages in 401 responses. Set to false for production (generic error only).
curl -X DELETE https://hookpipe.app/api/hooks/HOOK_ID/signature \
-H "Authorization: Bearer YOUR_API_KEY"
Failed forwarding attempts are retried automatically with exponential backoff.
curl -X PATCH https://hookpipe.app/api/hooks/HOOK_ID/retry \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"maxRetries": 7, "intervalMs": 5000}'
| Feature | Free | Pro ($9/mo) |
|---|---|---|
| Rate limit | 20 req/min per hook | 1,000 req/min per hook |
| Hooks | 5 | Unlimited |
| Retries | 3 (fixed 1s backoff) | Up to 10 (configurable interval) |
| Signature secrets | 1 per hook | 5 per hook (key rotation) |
| Log retention | 7 days | 30 days |
| Payload retention | 7 days | 30 days |
RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset headers