# Testing (/webhooks/testing)

<!-- agent-signals: reading_time_min: 1 · est_tokens: 479 · updated: 2026-07-30 -->
Related: [Overview](/webhooks/overview.md), [Event Types](/webhooks/events.md), [Security](/webhooks/security.md), [Open Source vs Cloud](/contributing/open-source-or-cloud.md)

Verify that your webhook integration works before deploying to production. This page covers how to receive webhooks on your local machine and how to diagnose common delivery and verification failures.

## Local Development [#local-development]

Webhooks require a publicly reachable URL, so you need to expose your local server to the internet during development.

### Using Cloudflare Tunnels [#using-cloudflare-tunnels]

[Cloudflare Tunnels](https://github.com/cloudflare/cloudflared/releases) provide a free way to expose your local server without opening firewall ports:

```bash
cloudflared tunnel --url localhost:3000
```

You'll get a public URL like `https://abc123.trycloudflare.com`. Use this in your webhook config:

```json
{
  "url": "https://abc123.trycloudflare.com/webhook"
}
```

## Troubleshooting [#troubleshooting]

### Webhooks Not Arriving [#webhooks-not-arriving]

* **Endpoint not accessible** - Verify your server is publicly reachable and firewalls allow incoming connections
* **Using HTTP** - Webhook URLs must use HTTPS
* **Wrong events** - Check the `events` filter in your webhook config
* **Timeout errors** - Ensure your endpoint responds within 10 seconds

### Signature Verification Failing [#signature-verification-failing]

The most common cause is using the parsed JSON body instead of the raw request body. A second cause is using the wrong secret, so confirm yours matches the value in your [account settings](https://www.firecrawl.dev/app/settings?tab=advanced).

```javascript
// Wrong - using parsed body
const signature = crypto
  .createHmac('sha256', secret)
  .update(JSON.stringify(req.body))
  .digest('hex');

// Correct - using raw body
app.use('/webhook', express.raw({ type: 'application/json' }));
app.post('/webhook', (req, res) => {
  const signature = crypto
    .createHmac('sha256', secret)
    .update(req.body) // Raw buffer
    .digest('hex');
});
```
