JK
JustKalm
Developer Tools

Webhook Debugging

Test, inspect, and debug webhook deliveries. Verify signatures, replay events, and troubleshoot integration issues.

Request inspector
Event replay
Test events

Recent Deliveries

Event IDTypeStatusResponseDuration
evt_abc123valuation.completeddelivered200127ms
evt_def456valuation.failedfailed5005023ms
evt_ghi789product.updateddelivered20089ms
evt_jkl012webhook.testpending——

Request Inspector

View the full request headers and body sent to your webhook endpoint.

Webhook Request
# Webhook Request Headers
POST /webhooks/justkalm HTTP/1.1
Host: yourapp.com
Content-Type: application/json
X-JustKalm-Signature: t=1702651965,v1=abc123...
X-JustKalm-Event-Id: evt_abc123xyz
X-JustKalm-Event-Type: valuation.completed
X-JustKalm-Webhook-Id: wh_endpoint123
X-Request-Id: req_xyz789
User-Agent: JustKalm-Webhooks/1.0

# Webhook Request Body
{
  "id": "evt_abc123xyz",
  "object": "event",
  "type": "valuation.completed",
  "created": 1702651965,
  "data": {
    "object": {
      "id": "val_xyz789",
      "object": "valuation",
      "status": "completed",
      "estimated_value": {
        "amount": 45000,
        "currency": "usd"
      },
      "confidence": 0.94
    }
  }
}

Signature Verification

Verify webhook authenticity by checking the signature against your signing secret.

Python Verification
import hmac
import hashlib

def verify_webhook_signature(payload: bytes, signature: str, secret: str) -> bool:
    """
    Verify JustKalm webhook signature.
    
    Args:
        payload: Raw request body (bytes, not parsed JSON)
        signature: X-JustKalm-Signature header value
        secret: Your webhook signing secret
    
    Returns:
        True if signature is valid
    """
    # Parse the signature header
    # Format: t=timestamp,v1=signature
    parts = dict(part.split('=', 1) for part in signature.split(','))
    timestamp = parts.get('t')
    expected_sig = parts.get('v1')
    
    if not timestamp or not expected_sig:
        return False
    
    # Check timestamp to prevent replay attacks (5 min tolerance)
    import time
    if abs(time.time() - int(timestamp)) > 300:
        return False
    
    # Compute expected signature
    signed_payload = f"{timestamp}.{payload.decode('utf-8')}"
    computed_sig = hmac.new(
        secret.encode('utf-8'),
        signed_payload.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    
    # Constant-time comparison
    return hmac.compare_digest(computed_sig, expected_sig)

CLI Testing

Test webhooks locally using the JustKalm CLI.

CLI Commands
# Send a test webhook event
justkalm webhooks test \
  --endpoint https://yourapp.com/webhooks/justkalm \
  --event valuation.completed

# Trigger specific event type
justkalm webhooks trigger valuation.completed \
  --data '{"valuation_id": "val_test123"}'

# Forward webhooks to localhost for development
justkalm webhooks listen --forward-to localhost:3000/webhooks

# Replay a specific event
justkalm webhooks replay evt_abc123xyz

# View recent webhook deliveries
justkalm webhooks deliveries --limit 10

Common Issues

Signature Mismatch

The computed signature doesn't match the X-JustKalm-Signature header.

Solution: Ensure you're using the raw request body (not parsed JSON) and the correct signing secret.

Timeout Errors

Webhook delivery times out after 30 seconds.

Solution: Process webhooks asynchronously. Return 200 immediately and queue for processing.

Duplicate Events

Receiving the same event multiple times.

Solution: Implement idempotency using the event ID. Store processed event IDs and skip duplicates.

4xx/5xx Responses

Your endpoint returns an error status code.

Solution: Check your server logs. We retry failed deliveries with exponential backoff.

Retry Schedule

Exponential Backoff

Failed webhooks are retried up to 8 times over 3 days.

Retry 1Immediately→
Retry 21 min→
Retry 35 min→
Retry 430 min→
Retry 52 hours→
Retry 68 hours→
Retry 724 hours→
Retry 872 hours

Test Your Webhooks

Use the dashboard to send test events and inspect deliveries.

Open Webhook Console

© 2026 JustKalm. Debug with confidence.