Troubleshooting
This guide helps you diagnose and resolve common webhook issues in Hookbase. Use it to debug delivery failures, signature verification errors, and event processing problems.
Common Issues
Webhooks Not Arriving
If your source is not receiving webhooks:
Check Source Status
- Verify the source is Active in the dashboard
- Inactive sources reject all incoming webhooks
Verify Ingestion URL
- Ensure the provider is sending to
https://api.hookbase.app/ingest/{orgSlug}/{sourceSlug} - Check that both
orgSlugandsourceSlugmatch your organization and source exactly (case-sensitive) - Test the URL manually with curl:
curl -X POST https://api.hookbase.app/ingest/{orgSlug}/{sourceSlug} \
-H "Content-Type: application/json" \
-d '{"test": "event"}'Review IP Filtering
- If IP filtering is enabled on the source, verify the provider's IPs are whitelisted
- Check the source configuration:
hookbase sources get 11111111-1111-4111-8111-11111111000bCheck Rate Limits
- Free plan: 1,000 events/month, 10 requests/second
- Starter plan: 25,000 events/month, 50 requests/second
- Exceeded rate limits return HTTP 429 responses
Review Event Quota
- Check your current usage in the dashboard under Settings → Billing
- Events exceeding your plan quota are rejected
Tip
Enable Request Logging on your source to see all incoming requests, even those that fail validation.
Signature Verification Failures
If webhooks are rejected due to invalid signatures:
Wrong Secret
- Verify you're using the correct signing secret from your provider
- Update the source configuration:
hookbase sources update 11111111-1111-4111-8111-11111111000b --secret "whsec_new_secret"Wrong Algorithm
- Ensure the verification algorithm matches your provider:
- Stripe uses HMAC-SHA256 with timestamp
- GitHub uses HMAC-SHA256
- Shopify uses HMAC-SHA256 (Base64)
- Twilio uses HMAC-SHA1
- Slack uses HMAC-SHA256
Clock Skew
- Some providers include timestamps in signatures and reject requests older than 5 minutes
- Verify your server time is synchronized with NTP
- Check the
X-Signature-Timestampheader (if present) against current time
Encoding Issues
- Some providers send signatures in hex, others in Base64
- Verify the encoding matches your provider's documentation
- Hookbase auto-detects encoding for built-in integrations
Bypass for Testing
- Temporarily disable signature verification:
hookbase sources update 11111111-1111-4111-8111-11111111000b --no-verifyWarning
Only disable signature verification in development. Always enable it in production to prevent spoofed webhooks.
Delivery Failures
If events are received but deliveries fail:
Destination URL Unreachable
- Verify the destination URL is publicly accessible
- Test manually:
curl -X POST https://your-destination.com/webhook \
-H "Content-Type: application/json" \
-d '{"test": "delivery"}'Timeouts
- Default timeout: 30 seconds
- If your endpoint takes longer, increase the timeout:
hookbase destinations update 22222222-2222-4222-8222-22222222000e --timeout 60HTTP Error Codes
- 4xx errors (Client Error): No retries. Check payload format and authentication
- 5xx errors (Server Error): Automatic retries with exponential backoff
- Review delivery response in dashboard or via API:
curl https://api.hookbase.app/api/organizations/{orgId}/deliveries/aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaa0007 \
-H "Authorization: Bearer YOUR_TOKEN"SSL Certificate Issues
- Ensure destination uses valid SSL certificate
- Self-signed certificates are rejected by default
- Use
verifySSL: falsefor development only:
hookbase destinations update 22222222-2222-4222-8222-22222222000e --no-verify-sslRetry Behavior
- Failed deliveries retry up to 5 times with exponential backoff: 1s, 2s, 4s, 8s, 16s
- After 5 failures, delivery status becomes
failed - Manually replay failed deliveries:
hookbase deliveries replay aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaa0007Events Not Being Delivered
If events arrive but don't trigger deliveries:
Route Disabled
- Check route status:
hookbase routes get 44444444-4444-4444-8444-44444444000b- Enable the route:
hookbase routes update 44444444-4444-4444-8444-44444444000b --enabledFilter Blocking Events
- Filters evaluate before delivery queuing
- Test a filter against an event payload:
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/filters/test \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"conditions": [
{ "field": "type", "operator": "equals", "value": "order.created" }
],
"logic": "AND",
"payload": { "type": "order.created", "amount": 5000 }
}'The test endpoint evaluates conditions you pass in the body; it does not take a filter ID. Copy the conditions off the stored filter to test what it will do.
- Review filter logic in the dashboard, or update it through the API:
curl -X PATCH https://api.hookbase.app/api/organizations/{orgId}/filters/{filterId} \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"conditions": [
{ "field": "type", "operator": "equals", "value": "order.created" }
]
}'The CLI has filters create, get, list and delete, but no filters update — edit filters in
the dashboard or with the PATCH above.
Circuit Breaker Open
- The circuit breaker lives on the route, not the destination, and opens once the route's
consecutive failures reach its
circuitFailureThreshold(default 5) - Check circuit breaker state:
hookbase routes circuit-status {routeId}- Reset the circuit breaker:
hookbase routes reset-circuit {routeId}Destination Inactive
- Verify destination status:
hookbase destinations get 22222222-2222-4222-8222-22222222000e- Activate destination:
hookbase destinations update 22222222-2222-4222-8222-22222222000e --activeTip
Use the Event Trace view in the dashboard to see why an event didn't match any routes.
Duplicate Deliveries
If the same event is delivered multiple times:
Retries After Timeout
- If your endpoint takes longer than the timeout to respond, Hookbase retries
- Solution: Respond with 2xx immediately, then process asynchronously
- Increase timeout if needed:
hookbase destinations update 22222222-2222-4222-8222-22222222000e --timeout 60Deduplication Not Enabled
- Enable deduplication on the source using provider's ID field:
hookbase sources update 11111111-1111-4111-8111-11111111000b \
--dedup-enabled \
--dedup-key "id" \
--dedup-window 86400Idempotency Key Handling
- Use idempotency keys in your endpoint to handle duplicate deliveries
- Hookbase includes
X-Hookbase-Delivery-Idheader in all requests - Store delivery IDs to detect duplicates
High Latency
If webhook delivery is slow:
Queue Backlog
- Check queue depth in dashboard under Monitoring
- Upgrade plan for higher throughput
- Consider batching deliveries if destination supports it
Large Payloads
- Payloads >1MB take longer to process
- Use transforms to strip unnecessary fields:
{
"event": event,
"type": type,
"data": data.{
"id": id,
"status": status
}
}Slow Destination
- Monitor destination response times in dashboard
- Optimize your endpoint or increase timeout
- Use async processing with immediate 200 OK response
Transform Complexity
- Complex JSONata transforms add processing time
- Test transform performance:
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/transforms/test \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"code": "{ \"id\": id }",
"payload": { "id": "evt_1" },
"transformType": "jsonata"
}'As with filters, the endpoint tests code you send in the body rather than a stored transform ID.
- Simplify transform logic where possible
Error Code Reference
Ingest Errors
HTTP status codes returned when webhooks are sent to your ingestion URL:
| Code | Error | Cause | Solution |
|---|---|---|---|
| 400 | Bad Request | Invalid JSON or missing required fields | Check payload format |
| 401 | Unauthorized | Invalid signature | Verify signing secret and algorithm |
| 403 | Forbidden | IP not whitelisted | Add provider IP to source IP filter |
| 404 | Not Found | Invalid orgSlug or sourceSlug | Verify ingestion URL |
| 413 | Payload Too Large | Payload exceeds 10MB limit | Reduce payload size or contact support |
| 429 | Too Many Requests | Rate limit exceeded | Slow down request rate or upgrade plan |
Delivery Errors
Status values on delivery records:
| Status | Meaning | Cause | Solution |
|---|---|---|---|
timeout | Destination didn't respond within timeout | Slow endpoint or network issue | Increase timeout or optimize endpoint |
connection_refused | Destination refused connection | URL unreachable or port closed | Verify destination URL and firewall |
dns_error | DNS lookup failed | Invalid domain name | Check destination hostname |
ssl_error | SSL certificate invalid | Self-signed or expired cert | Use valid SSL cert or disable verification (dev only) |
http_4xx | Client error (400-499) | Bad request format or auth | Check payload and authentication |
http_5xx | Server error (500-599) | Destination server error | Fix destination endpoint or wait for recovery |
transform_error | Transform failed | Invalid JSONata expression | Test and fix transform |
schema_failed | Schema validation failed | Payload doesn't match schema | Update payload or schema |
API Errors
Status codes from Hookbase API:
| Code | Error | Cause | Solution |
|---|---|---|---|
| 401 | Unauthorized | Missing or invalid token | Authenticate with valid API key or JWT |
| 403 | Forbidden | Insufficient permissions | Check organization role (admin/editor/viewer) |
| 404 | Not Found | Resource doesn't exist | Verify resource ID and organization |
| 409 | Conflict | Resource already exists | Use different name or slug |
| 422 | Validation Error | Invalid request body | Check request against API documentation |
| 429 | Rate Limited | Too many API requests | Implement exponential backoff |
Debugging Workflows
Tracing an Event End-to-End
Follow an event through the entire pipeline:
1. Find the Event
By event ID:
hookbase events get bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbb0003Or by query:
hookbase events list --source 11111111-1111-4111-8111-11111111000b --status processed --limit 10Via API:
curl https://api.hookbase.app/api/organizations/{orgId}/events/bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbb0003 \
-H "Authorization: Bearer YOUR_TOKEN"2. Check Deliveries
List deliveries for the event:
curl "https://api.hookbase.app/api/organizations/{orgId}/deliveries?eventId=bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbb0003" \
-H "Authorization: Bearer YOUR_TOKEN"Or via CLI:
hookbase deliveries list --event bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbb00033. Inspect Delivery Details
Get full delivery record:
hookbase deliveries get aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaa0007View response body — it is part of the delivery record, there is no separate /response
sub-resource:
curl https://api.hookbase.app/api/organizations/{orgId}/deliveries/aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaa0007 \
-H "Authorization: Bearer YOUR_TOKEN"4. Replay if Needed
Retry a failed delivery:
hookbase deliveries replay aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaa0007Tip
Use the dashboard's Event Inspector to see the visual trace with routes, filters, transforms, and delivery attempts.
Checking Circuit Breaker State
The circuit breaker lives on the route, not the destination — two routes to the same destination trip independently. Read its state with:
curl https://api.hookbase.app/api/routes/{routeId}/circuit-status \
-H "Authorization: Bearer YOUR_TOKEN"Response:
{
"circuitState": "open",
"circuitOpenedAt": "2026-02-11T10:30:00Z",
"cooldownSeconds": 300,
"probeAttempts": 0,
"probeSuccessThreshold": 2,
"failureThreshold": 5,
"consecutiveFailures": 12,
"timeUntilProbeSeconds": 240
}circuitState is closed, open or half_open. timeUntilProbeSeconds counts down to the
next half-open probe and is null unless the circuit is open.
Reset it back to closed:
curl -X POST https://api.hookbase.app/api/routes/{routeId}/reset-circuit \
-H "Authorization: Bearer YOUR_TOKEN"Returns {"success": true, "circuitState": "closed", "previousState": "open"}.
Or via CLI:
hookbase routes circuit-status {routeId}
hookbase routes reset-circuit {routeId}Info
Circuit breakers require a Pro or Business plan. Both endpoints and both CLI commands return 403 on the free and starter plans.
Verifying Filter Configuration
Test a filter against sample payload:
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/filters/test \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"conditions": [
{ "field": "amount", "operator": "greater_than", "value": 1000 },
{ "field": "currency", "operator": "equals", "value": "USD" }
],
"logic": "AND",
"payload": {
"type": "order.created",
"amount": 5000,
"currency": "USD"
}
}'Both conditions and payload are required; logic defaults to AND. Response:
{
"matches": true,
"logic": "AND",
"results": [
{
"field": "amount",
"operator": "greater_than",
"value": 1000,
"fieldValue": 5000,
"passed": true
},
{
"field": "currency",
"operator": "equals",
"value": "USD",
"fieldValue": "USD",
"passed": true
}
]
}results has one entry per condition, so a filter that does not match tells you which condition
failed and what the payload actually held in fieldValue.
Update the filter if needed:
curl -X PATCH https://api.hookbase.app/api/organizations/{orgId}/filters/{filterId} \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"conditions": [
{ "field": "amount", "operator": "greater_than", "value": 1000 },
{ "field": "currency", "operator": "equals", "value": "USD" }
],
"logic": "AND"
}'Checking Transform Output
Test a transform before applying:
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/transforms/test \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"code": "{ \"event\": type, \"orderId\": order.id, \"itemCount\": $count(order.items) }",
"transformType": "jsonata",
"payload": {
"type": "order.created",
"order": {
"id": "ord_123",
"items": [{"sku": "ABC", "quantity": 2}]
}
}
}'code and payload are the two things that matter; transformType defaults to jsonata, and
inputFormat/outputFormat both default to json. Response:
{
"success": true,
"result": {
"event": "order.created",
"orderId": "ord_123",
"itemCount": 2
},
"contentType": "application/json"
}A transform that throws still returns HTTP 200, with success: false and the message in error —
check success rather than the status code. There is no executionTime in the response.
Update the transform — the CLI has no transforms update, so use the API:
curl -X PATCH https://api.hookbase.app/api/organizations/{orgId}/transforms/{transformId} \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"code": "{ \"event\": type, \"orderId\": order.id, \"itemCount\": $count(order.items) }"
}'CLI Debugging
Quick commands for debugging common issues:
List Failed Events
hookbase events list --status failed --limit 20Get Delivery Details
hookbase deliveries get aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaa0007Replay Failed Delivery
hookbase deliveries replay aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaa0007Follow Events in Real-Time
hookbase events followEnable Debug Logging
HOOKBASE_DEBUG=1 hookbase events followCheck Recent Deliveries
hookbase deliveries list --status failed --limit 50Test Filter Matching
There is no hookbase routes test. Test the route's filter conditions against a sample payload
with the filters test endpoint shown in
Verifying Filter Configuration above.
View Audit Logs
hookbase audit-logs list --action delivery.replayed --limit 50Audit logs record actions a user or API key took — sources, destinations, routes, keys, members,
and deliberate replays as delivery.replayed. They do not record automatic delivery outcomes, so
there is no delivery.failed action to filter on; use hookbase deliveries list --status failed
for those. hookbase audit-logs list with no --action shows everything, and
GET /api/organizations/{orgId}/audit-logs/actions lists the action names you can filter by.
Tip
Set HOOKBASE_DEBUG=1 environment variable to see detailed HTTP requests and responses from the CLI.
Getting Help
If you're still experiencing issues:
Dashboard
- Visit app.hookbase.app to view real-time event traces and delivery logs
API Documentation
- Review the API Reference for endpoint specifications and examples
Support
- Email: support@hookbase.app
- Live chat: Available in dashboard (Pro and Business plans)
- Status page: status.hookbase.app
Community
- Discord: discord.gg/hookbase
- GitHub Issues: github.com/hookbase/hookbase/issues
When contacting support, include:
- Event ID or Delivery ID
- Organization ID and Source/Destination slugs
- Timestamp of the issue
- Error messages or HTTP status codes
- Steps to reproduce