A webhook bin service built with CloudFlare Workers, Hono framework and CloudFlare Durable Objects. Capture, inspect and debug HTTP webhooks with ease.
The EchoHook API is live at: https://echohook.dev
- API Development: Test webhooks during development
- Third-party Integration: Debug webhooks from services like GitHub, Stripe, PayPal
- API Monitoring: Monitor webhook delivery and payloads
- Development Testing: Create temporary endpoints for testing
- Webhook Inspection: Analyze webhook structure and content
- β Token Authentication: Secure API access with Bearer tokens
- β Webhook Capture: Capture any HTTP method and payload
- β Request Inspection: View headers, body, query parameters and metadata
- β Bin Management: Create, update and delete webhook bins
- β Structured Logging: JSON-formatted logs for monitoring and debugging
- β TypeScript: Fully typed with modern TypeScript
- β CloudFlare Durable Objects: Serverless stateful storage with strong consistency
- β Hono Framework: Fast and lightweight web framework
- β Real-time: Instant webhook capture and viewing
- β CORS: Cross-Origin Resource Sharing enabled
All API endpoints (except root / and token creation) require authentication using Bearer tokens.
- Create an API Token:
curl -X POST https://echohook.dev/api/auth/token \
-H "Content-Type: application/json" \
-d '{"name": "My Token", "description": "Token for webhook testing"}'- Use the token in all requests:
curl -H "Authorization: Bearer YOUR_TOKEN" https://echohook.dev/api/binsnpm run devcurl -X POST https://echohook.dev/api/auth/token \
-H "Content-Type: application/json" \
-d '{"name": "My API Token", "description": "For testing"}'Response:
{
"success": true,
"data": {
"id": "token-uuid",
"token": "your-64-char-token",
"name": "My API Token",
"description": "For testing",
"created_at": "2025-06-10T12:00:00.000Z",
"is_active": true
}
}# Set your token
TOKEN="your-64-char-token"
# List webhook bins
curl -H "Authorization: Bearer $TOKEN" \
https://echohook.dev/api/bins
# Create a webhook bin
curl -X POST https://echohook.dev/api/bins \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "My Webhook Bin", "description": "Test bin"}'
# Capture a webhook
curl -X POST https://echohook.dev/api/webhook/your-bin-id \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"message": "Hello webhook!"}'GET /- Landing page with documentation (no auth required)GET /api- API health check (no auth required)
POST /api/auth/token- Create new API token (no auth required)DELETE /api/auth/tokens/:tokenId- Delete an API token
GET /api/bins- List all webhook binsGET /api/bins/:binId- Get single bin detailsPOST /api/bins- Create new webhook binPUT /api/bins/:binId- Update bin detailsDELETE /api/bins/:binId- Delete bin and all its captured requests
GET /api/bins/:binId/requests- Get all captured requests for a binPOST /api/webhook/:binId- Capture webhook (accepts any HTTP method)
{
"name": "My API Token",
"description": "Optional description",
"expiresIn": "365"
}{
"name": "My Webhook Bin",
"description": "Optional description"
}{
"success": true,
"data": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "My Webhook Bin",
"description": "Optional description",
"created_at": "2024-06-01T12:00:00.000Z",
"updated_at": "2024-06-01T12:00:00.000Z",
"request_count": 5,
"last_request_at": "2024-06-01T12:30:00.000Z"
}
}{
"success": true,
"data": [
{
"id": "req-123e4567-e89b-12d3-a456-426614174000",
"bin_id": "123e4567-e89b-12d3-a456-426614174000",
"method": "POST",
"url": "https://echohook.dev/webhook/123e4567-e89b-12d3-a456-426614174000",
"headers": {
"content-type": "application/json",
"user-agent": "GitHub-Hookshot/abc123"
},
"body": "{\"action\":\"push\",\"repository\":{\"name\":\"my-repo\"}}",
"query_params": {
"source": "github"
},
"ip_address": "192.168.1.1",
"user_agent": "GitHub-Hookshot/abc123",
"content_type": "application/json",
"content_length": 45,
"received_at": "2024-06-01T12:30:00.000Z"
}
]
}pnpm installpnpm run devThis starts the development server at http://localhost:8787
The landing page HTML is managed in index.html. To sync changes to the worker:
npm run sync-htmlThis copies the content from index.html to src/html.ts for deployment.
pnpm run build # Syncs HTML and deploys
# or
pnpm run deploy # Deploys without syncingNote: Durable Objects automatically handle storage without requiring database setup or migrations.
curl -X POST https://echohook.dev/api/bins \
-H "Content-Type: application/json" \
-d '{"name": "GitHub Webhooks", "description": "Capture GitHub webhook events"}'# Any HTTP method is supported
curl -X POST https://echohook.dev/api/webhook/YOUR_BIN_ID \
-H "Content-Type: application/json" \
-H "X-GitHub-Event: push" \
-d '{"action": "push", "repository": {"name": "my-repo"}}'curl https://echohook.dev/api/bins/YOUR_BIN_ID/requestscurl https://echohook.dev/api/binscurl https://echohook.dev/api/bins/YOUR_BIN_IDcurl -X PUT https://echohook.dev/api/bins/YOUR_BIN_ID \
-H "Content-Type: application/json" \
-d '{"name": "Updated Bin Name", "description": "New description"}'curl -X DELETE https://echohook.dev/api/bins/YOUR_BIN_ID