Webhook Receiver
Public endpoint for receiving webhooks
The Webhooks endpoint is a public endpoint that receives incoming webhooks and stores them for inspection.
Webhook Receiver
Endpoint
POST/GET/PUT/DELETE/PATCH https://hooksdash.ibadsiddiqui.dev/api/h/{slug}
This endpoint accepts ALL HTTP methods.
Authentication
No authentication required. This is a public endpoint designed to receive webhooks from external services.
Basic Usage
Simple Webhook
Send a webhook to your endpoint:
curl -X POST https://hooksdash.ibadsiddiqui.dev/api/h/my-webhook \ -H "Content-Type: application/json" \ -d '{"event": "user.created", "userId": "123"}'
Response:
{ "success": true, "data": { "received": true, "requestId": "cmlo...", "timestamp": "2026-01-01T00:00:00.000Z" } }
With Path
You can include additional path segments after the slug:
curl -X POST https://hooksdash.ibadsiddiqui.dev/api/h/my-webhook/users/created \ -H "Content-Type: application/json" \ -d '{"userId": "123"}'
The path /users/created will be captured and stored with the request.
With Query Parameters
Include query parameters in the URL:
curl -X POST "https://hooksdash.ibadsiddiqui.dev/api/h/my-webhook?source=email&campaign=123" \ -H "Content-Type: application/json" \ -d '{"event": "click"}'
Query parameters are stored separately and can be inspected in the dashboard.
HTTP Methods
All HTTP methods are supported:
GET
curl -X GET "https://hooksdash.ibadsiddiqui.dev/api/h/my-webhook?test=true"
POST
curl -X POST https://hooksdash.ibadsiddiqui.dev/api/h/my-webhook \ -H "Content-Type: application/json" \ -d '{"data": "value"}'
PUT
curl -X PUT https://hooksdash.ibadsiddiqui.dev/api/h/my-webhook \ -d "param=value"
DELETE
curl -X DELETE https://hooksdash.ibadsiddiqui.dev/api/h/my-webhook
PATCH
curl -X PATCH https://hooksdash.ibadsiddiqui.dev/api/h/my-webhook \ -H "Content-Type: application/json" \ -d '{"update": "partial"}'
Content Types
The webhook receiver accepts all content types:
JSON
curl -X POST https://hooksdash.ibadsiddiqui.dev/api/h/my-webhook \ -H "Content-Type: application/json" \ -d '{"event": "test"}'
Form Data
curl -X POST https://hooksdash.ibadsiddiqui.dev/api/h/my-webhook \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "key1=value1&key2=value2"
XML
curl -X POST https://hooksdash.ibadsiddiqui.dev/api/h/my-webhook \ -H "Content-Type: application/xml" \ -d '<event><type>test</type></event>'
Plain Text
curl -X POST https://hooksdash.ibadsiddiqui.dev/api/h/my-webhook \ -H "Content-Type: text/plain" \ -d "This is a plain text webhook"
Multipart Form Data
curl -X POST https://hooksdash.ibadsiddiqui.dev/api/h/my-webhook \ -F "file=@document.pdf" \ -F "description=Test upload"
Headers
All request headers are captured and stored, including:
Content-TypeUser-AgentAuthorization(if present)- Custom headers (e.g.,
X-Stripe-Signature,X-Hub-Signature)
Example:
curl -X POST https://hooksdash.ibadsiddiqui.dev/api/h/my-webhook \ -H "Content-Type: application/json" \ -H "X-Custom-Header: custom-value" \ -H "X-API-Version: 2024-01-01" \ -d '{"event": "test"}'
All these headers will be visible in the request inspector.
Response Codes
Success
200 OK
{ "success": true, "data": { "received": true, "requestId": "cmlo...", "timestamp": "2026-01-01T00:00:00.000Z" } }
Endpoint Not Found
404 Not Found
{ "statusCode": 404, "message": "Endpoint not found", "error": "Not Found" }
Possible causes:
- Slug doesn't exist
- Endpoint was deleted
Endpoint Inactive
403 Forbidden
{ "statusCode": 403, "message": "Endpoint is inactive", "error": "Forbidden" }
Possible causes:
- Endpoint was manually deactivated
- Endpoint was auto-deactivated due to inactivity
Rate Limit Exceeded
429 Too Many Requests
{ "statusCode": 429, "message": "Rate limit exceeded", "error": "Too Many Requests" }
Rate limits by tier:
| Tier | Requests per Minute |
|---|---|
| Free | 10 |
| Starter | 60 |
| Pro | 300 |
| Enterprise | 1000 |
Captured Data
Each webhook request captures:
| Field | Description |
|---|---|
| Method | HTTP method (GET, POST, etc.) |
| Path | Path after the slug |
| Query | Query parameters |
| Headers | All request headers |
| Body | Request body (any format) |
| IP | Source IP address |
| User Agent | User-Agent header |
| Timestamp | ISO 8601 timestamp of receipt |
Integration Examples
Stripe Webhooks
Configure in Stripe Dashboard → Developers → Webhooks:
https://hooksdash.ibadsiddiqui.dev/api/h/stripe-prod
Test webhook:
curl -X POST https://hooksdash.ibadsiddiqui.dev/api/h/stripe-prod \ -H "Content-Type: application/json" \ -H "Stripe-Signature: t=1234567890,v1=abc123..." \ -d '{ "id": "evt_123", "object": "event", "type": "payment_intent.succeeded", "data": { "object": { "id": "pi_123", "amount": 5000, "currency": "usd" } } }'
GitHub Webhooks
Configure in GitHub → Settings → Webhooks:
Payload URL: https://hooksdash.ibadsiddiqui.dev/api/h/github-prod
Content type: application/json
Test webhook:
curl -X POST https://hooksdash.ibadsiddiqui.dev/api/h/github-prod \ -H "Content-Type: application/json" \ -H "X-GitHub-Event: push" \ -H "X-Hub-Signature-256: sha256=abc123..." \ -d '{ "ref": "refs/heads/main", "repository": { "name": "my-repo", "full_name": "user/my-repo" }, "commits": [...] }'
Twilio Webhooks
Configure in Twilio Console → Phone Numbers → Webhook URLs:
https://hooksdash.ibadsiddiqui.dev/api/h/twilio-prod
Twilio sends form data:
curl -X POST https://hooksdash.ibadsiddiqui.dev/api/h/twilio-prod \ -d "MessageSid=SM123" \ -d "From=+1234567890" \ -d "Body=Hello World"
SendGrid Event Webhook
Configure in SendGrid → Settings → Mail Settings → Event Webhook:
https://hooksdash.ibadsiddiqui.dev/api/h/sendgrid-prod
Test webhook:
curl -X POST https://hooksdash.ibadsiddiqui.dev/api/h/sendgrid-prod \ -H "Content-Type: application/json" \ -d '[ { "email": "user@example.com", "event": "delivered", "timestamp": 1234567890 } ]'
Shopify Webhooks
Configure in Shopify Admin → Settings → Notifications → Webhooks:
https://hooksdash.ibadsiddiqui.dev/api/h/shopify-prod
Test webhook:
curl -X POST https://hooksdash.ibadsiddiqui.dev/api/h/shopify-prod \ -H "Content-Type: application/json" \ -H "X-Shopify-Topic: orders/create" \ -H "X-Shopify-Shop-Domain: mystore.myshopify.com" \ -d '{ "id": 12345, "email": "customer@example.com", "total_price": "100.00", "line_items": [...] }'
Local Development
Use the HooksDash CLI to forward webhooks to your local development server:
# Start your local server npm run dev # Running on http://localhost:3000 # In another terminal, start the tunnel hooksdash forward --port 3000 --endpoint my-webhook
Now webhooks sent to https://hooksdash.ibadsiddiqui.dev/api/h/my-webhook will be forwarded to http://localhost:3000.
See CLI Documentation for more details.
Testing Webhooks
Manual Testing
Use cURL or any HTTP client:
curl -X POST https://hooksdash.ibadsiddiqui.dev/api/h/my-webhook \ -H "Content-Type: application/json" \ -d '{"test": true, "timestamp": 1234567890}'
Automated Testing
// Node.js example const axios = require('axios'); async function sendTestWebhook() { try { const response = await axios.post( 'https://hooksdash.ibadsiddiqui.dev/api/h/my-webhook', { event: 'test', data: { value: 123 }, }, { headers: { 'Content-Type': 'application/json', 'X-Test-Header': 'test-value', }, } ); console.log('Webhook sent:', response.data); } catch (error) { console.error('Error:', error.message); } } sendTestWebhook();
Testing Different Formats
# JSON curl -X POST https://hooksdash.ibadsiddiqui.dev/api/h/test-endpoint \ -H "Content-Type: application/json" \ -d '{"format": "json"}' # Form data curl -X POST https://hooksdash.ibadsiddiqui.dev/api/h/test-endpoint \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "format=form&key=value" # XML curl -X POST https://hooksdash.ibadsiddiqui.dev/api/h/test-endpoint \ -H "Content-Type: application/xml" \ -d '<data><format>xml</format></data>' # Plain text curl -X POST https://hooksdash.ibadsiddiqui.dev/api/h/test-endpoint \ -H "Content-Type: text/plain" \ -d "Plain text data"
Security Considerations
Public Endpoint
- The webhook endpoint is public and doesn't require authentication
- Anyone with the slug can send webhooks to your endpoint
- Use long, random slugs for production endpoints (e.g.,
stripe-prod-a1b2c3d4)
Request Validation
HooksDash stores the raw request data, including signature headers (e.g., X-Stripe-Signature). You should:
- Validate webhook signatures when replaying to your application
- Check the source IP address if the service provides it
- Implement idempotency to handle duplicate webhooks
Rate Limiting
Rate limits are applied per-endpoint to prevent abuse:
- Free: 10 requests/minute
- Starter: 60 requests/minute
- Pro: 300 requests/minute
- Enterprise: 1000 requests/minute
If you need higher limits, upgrade your tier or contact support.
Sensitive Data
⚠️ Warning: Do not send sensitive data (passwords, tokens, full credit card numbers) through webhooks. HooksDash stores request data in plain text.
If you receive webhooks containing sensitive data:
- Use webhook signature verification
- Fetch the actual sensitive data from the service's API using the webhook as a notification
- Delete requests after inspection
Best Practices
-
Use descriptive slugs: Use meaningful slugs that indicate the service and environment (e.g.,
stripe-prod,github-staging) -
Separate endpoints for different services: Don't reuse the same endpoint for multiple services
-
Test before production: Use a test endpoint to verify webhook format before configuring in production
-
Monitor rate limits: Check your dashboard to see if you're approaching rate limits
-
Clean up test data: Delete test requests regularly to keep your dashboard clean
-
Use unique slugs for production: Add random suffixes to production slugs for security
-
Document your webhooks: Add descriptions to your endpoints explaining what they receive
Troubleshooting
Webhooks not appearing
Check:
- Endpoint exists and slug is correct
- Endpoint is active (
isActive: true) - Not hitting rate limits
- Service is configured with correct URL
Rate limit errors
Solutions:
- Reduce webhook frequency at source
- Upgrade to higher tier
- Use multiple endpoints to distribute load
Missing request data
Check:
- Request body size (large bodies may be truncated)
- Content-Type header is set correctly
- Data is actually being sent by the service
Signature validation failing
Possible causes:
- Clock skew between services
- Request was modified during replay
- Signature header is missing or incorrect
Solution:
- Preserve all headers when replaying
- Use original request without modifications for signature validation
- Check service documentation for signature verification requirements