Back to The Times of Claw

DenchClaw Webhook Integrations: Connect Any Tool

DenchClaw webhook integrations let you connect any external tool to your local CRM. Set up incoming and outgoing webhooks, secure them, and automate your workflow.

Mark Rachapoom
Mark Rachapoom
·6 min read
DenchClaw Webhook Integrations: Connect Any Tool

DenchClaw Webhook Integrations: Connect Any Tool

Webhooks are the fastest way to connect DenchClaw with the rest of your stack. Whether you're pushing form submissions into your CRM, firing Slack alerts when a deal moves, or syncing data from external APIs, DenchClaw's webhook system handles it without requiring a third-party integration platform.

This guide covers the full webhook setup: incoming webhooks that receive data, outgoing webhooks that send events, securing payloads with secret tokens, and real-world examples you can copy directly.

How DenchClaw Webhooks Work#

DenchClaw supports two webhook directions:

  • Incoming webhooks: External tools POST data to a DenchClaw endpoint. DenchClaw parses the payload and creates or updates CRM entries automatically.
  • Outgoing webhooks: DenchClaw POSTs data to a URL you specify when CRM events occur (entry created, field updated, status changed, etc.).

Both are configured through the CLI or via Action fields inside DenchClaw itself. No dashboard required.

Setting Up Incoming Webhooks#

Incoming webhooks let external tools push data into DenchClaw. Common use cases: form submissions creating contacts, payment events creating deals, support tickets creating people entries.

Step 1: Register an incoming webhook endpoint#

npx denchclaw webhook create --direction incoming --object people --name "Typeform Contact Form"

This returns a unique URL like:

https://your-denchclaw-instance.com/webhooks/incoming/abc123xyz

Step 2: Map payload fields to CRM fields#

DenchClaw uses a field mapping config to translate incoming JSON keys to your DuckDB schema:

{
  "field_mappings": {
    "first_name": "name",
    "email_address": "email",
    "company": "company_name",
    "phone": "phone"
  }
}

Save this as webhook-mappings/typeform-contact.json in your workspace, then attach it to the webhook:

npx denchclaw webhook update abc123xyz --mapping ./webhook-mappings/typeform-contact.json

Step 3: Test with curl#

curl -X POST https://your-denchclaw-instance.com/webhooks/incoming/abc123xyz \
  -H "Content-Type: application/json" \
  -H "X-Webhook-Secret: your-secret-token" \
  -d '{
    "first_name": "Sarah",
    "email_address": "sarah@example.com",
    "company": "Acme Corp",
    "phone": "+1-555-0123"
  }'

DenchClaw will insert a new row into the entries table for the people object, with all mapped fields written to entry_fields.

Setting Up Outgoing Webhooks#

Outgoing webhooks fire when something changes in DenchClaw. You can trigger them on:

  • Entry created
  • Entry updated
  • Field value changed (specific fields)
  • Status changed
  • Entry deleted

Step 1: Create an outgoing webhook#

npx denchclaw webhook create \
  --direction outgoing \
  --object deals \
  --event status_changed \
  --url https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK \
  --name "Deal Status → Slack"

Step 2: Configure the payload template#

DenchClaw sends a default JSON payload, but you can customize it with a template:

{
  "text": "Deal updated: {{entry.name}} moved to {{entry.status}}",
  "attachments": [
    {
      "fields": [
        { "title": "Deal Value", "value": "{{entry.value}}", "short": true },
        { "title": "Owner", "value": "{{entry.owner}}", "short": true }
      ]
    }
  ]
}

Step 3: Test the outgoing webhook#

npx denchclaw webhook test --id outgoing-webhook-id-here

This fires a test payload to your configured URL so you can verify the connection before going live.

Securing Webhooks with Secret Tokens#

Always authenticate your webhooks. DenchClaw supports HMAC-SHA256 signature verification for both incoming and outgoing webhooks.

For incoming webhooks#

Set a secret when creating the webhook:

npx denchclaw webhook create --direction incoming --object people \
  --secret "your-32-char-secret-here"

In your receiving server, verify the signature:

const crypto = require('crypto');
 
function verifyDenchClawWebhook(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(payload))
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(`sha256=${expected}`),
    Buffer.from(signature)
  );
}
 
// Express.js example
app.post('/webhook', express.json(), (req, res) => {
  const sig = req.headers['x-denchclaw-signature'];
  
  if (!verifyDenchClawWebhook(req.body, sig, process.env.WEBHOOK_SECRET)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }
  
  // Process the webhook payload
  console.log('Received:', req.body);
  res.json({ received: true });
});

For outgoing webhooks#

DenchClaw signs outgoing requests with the same HMAC-SHA256 pattern. The signature is in the X-DenchClaw-Signature header. Verify it on the receiving end using the same method above.

Using Action Fields to Trigger Webhooks#

Action fields are a no-code way to trigger webhooks from inside DenchClaw. You can create a button field on any object that fires a webhook when clicked.

Create an Action field#

npx denchclaw field create \
  --object deals \
  --name "Notify Team" \
  --type action \
  --webhook-url https://hooks.slack.com/services/YOUR/HOOK \
  --webhook-payload '{"text": "Deal {{entry.name}} needs attention!"}'

Now "Notify Team" appears as a clickable button on every deal entry. When clicked (via chat or the web UI), it fires the webhook with the current entry's data interpolated into the payload.

Real-World Example: Form Submission → Contact Entry#

Here's a complete Typeform → DenchClaw integration using incoming webhooks.

1. Set up the webhook in DenchClaw#

npx denchclaw webhook create \
  --direction incoming \
  --object people \
  --name "Typeform Lead Capture" \
  --secret "tf-secret-abc123"

2. Configure Typeform#

In Typeform → Connect → Webhooks, paste the DenchClaw webhook URL and set the secret.

3. Create the field mapping#

{
  "field_mappings": {
    "answers[0].text": "name",
    "answers[1].email": "email",
    "answers[2].text": "company_name",
    "hidden.utm_source": "lead_source"
  },
  "default_fields": {
    "status": "Lead",
    "source": "Typeform"
  }
}

4. Test end-to-end#

Submit a test response in Typeform. Query DenchClaw to verify:

SELECT * FROM v_people ORDER BY created_at DESC LIMIT 5;

Real-World Example: Deal Update → Slack Notification#

When a deal moves to "Closed Won", fire a Slack message to your #wins channel.

npx denchclaw webhook create \
  --direction outgoing \
  --object deals \
  --event field_changed \
  --field status \
  --filter "status = 'Closed Won'" \
  --url https://hooks.slack.com/services/YOUR/HOOK \
  --name "Closed Won Alert" \
  --template '{"text": "🎉 Closed Won: {{entry.name}} — ${{entry.value}}"}'

Every time a deal's status field changes to "Closed Won", Slack gets a notification automatically.

Webhook Payload Format#

Every DenchClaw webhook (incoming and outgoing) follows this envelope format:

{
  "event": "entry.created",
  "object": "deals",
  "entry_id": "uuid-here",
  "timestamp": "2026-03-26T18:00:00Z",
  "data": {
    "name": "Acme Corp Deal",
    "status": "Proposal",
    "value": 15000,
    "owner": "mark@company.com"
  },
  "previous": {
    "status": "Qualified"
  }
}

The previous field is only included on update events and contains the prior values of changed fields.

FAQ#

Can I have multiple outgoing webhooks for the same event? Yes. You can create multiple webhooks on the same object and event. All of them fire when the trigger condition is met.

What happens if a webhook endpoint is down? DenchClaw retries failed outgoing webhooks 3 times with exponential backoff (1min, 5min, 30min). After that, it logs the failure and moves on. Check npx denchclaw webhook logs for failed deliveries.

Can I filter outgoing webhooks to specific field values? Yes, use the --filter flag when creating the webhook. Supports basic comparison operators: =, !=, >, <, contains.

Do incoming webhooks support idempotency? Yes. Pass an X-Idempotency-Key header with a unique ID per request. DenchClaw will skip duplicate requests with the same key within a 24-hour window.

How do I debug a webhook that isn't firing? Run npx denchclaw webhook logs --id <webhook-id> to see recent delivery attempts, response codes, and error messages.

Ready to try DenchClaw? Install in one command: npx denchclaw. Full setup guide →

Mark Rachapoom

Written by

Mark Rachapoom

Building the future of AI CRM software.

Continue reading

DENCH

© 2026 DenchHQ · San Francisco, CA