Appearance
Testing Webhooks
Updated Feb 2026Since webhooks require Firecrawl to reach your server from the internet, you need a strategy for testing during local development. This page covers tools for exposing your local server, debugging payloads, and troubleshooting common issues.
Local Development
Your local development server (e.g., localhost:3000) is not accessible from the internet. You need a tunnel service to create a public URL that forwards traffic to your local machine.
Using Cloudflare Tunnels (Recommended)
Cloudflare Tunnels provide a free, no-account-required way to expose your local server without opening firewall ports:
bash
# Install cloudflared (macOS)
brew install cloudflare/cloudflare/cloudflared
# Install cloudflared (Windows - via winget)
winget install Cloudflare.cloudflared
# Start a tunnel to your local server
cloudflared tunnel --url localhost:3000You will get a public URL like https://abc123.trycloudflare.com. Use this in your webhook configuration:
json
{
"webhook": {
"url": "https://abc123.trycloudflare.com/webhook/firecrawl",
"events": ["started", "page", "completed"]
}
}Tunnel URL Changes
Cloudflare quick tunnels generate a new random URL each time you restart cloudflared. For persistent URLs, set up a named tunnel with a Cloudflare account.
Using ngrok
ngrok is another popular option with a dashboard for inspecting payloads:
bash
# Install ngrok
npm install -g ngrok
# Start a tunnel
ngrok http 3000ngrok provides a web inspection interface at http://localhost:4040 where you can see all incoming webhook requests, their headers, and bodies.
Using webhook.site
For quick payload inspection without running any local code, use webhook.site:
- Visit webhook.site -- you get a unique URL immediately
- Use that URL as your webhook endpoint
- All incoming requests are logged in the browser with full headers and body
This is ideal for verifying that Firecrawl is sending webhooks correctly before writing any handler code.
Debugging Payloads
Minimal Logging Server
Create a simple server that logs every webhook payload to the console:
javascript
import express from 'express';
const app = express();
app.use(express.json());
app.post('/webhook/firecrawl', (req, res) => {
console.log('--- Webhook Received ---');
console.log('Headers:', JSON.stringify(req.headers, null, 2));
console.log('Type:', req.body.type);
console.log('Success:', req.body.success);
console.log('Job ID:', req.body.id);
console.log('Data count:', req.body.data?.length || 0);
console.log('Metadata:', JSON.stringify(req.body.metadata, null, 2));
if (req.body.error) {
console.error('Error:', req.body.error);
}
console.log('------------------------');
res.status(200).send('ok');
});
app.listen(3000, () => {
console.log('Webhook debug server running on port 3000');
});Python Logging Server
python
from flask import Flask, request
app = Flask(__name__)
@app.route('/webhook/firecrawl', methods=['POST'])
def webhook():
event = request.get_json()
print(f"\n--- Webhook Received ---")
print(f"Type: {event.get('type')}")
print(f"Success: {event.get('success')}")
print(f"Job ID: {event.get('id')}")
print(f"Data items: {len(event.get('data', []))}")
if event.get('error'):
print(f"Error: {event['error']}")
print(f"------------------------\n")
return 'ok', 200
if __name__ == '__main__':
app.run(port=3000, debug=True)Retry Behavior
Understanding retry behavior is essential for testing. When your endpoint fails to respond:
| Scenario | Firecrawl Behavior |
|---|---|
Your server returns 200-299 | Delivery successful, no retry |
Your server returns 4xx or 5xx | Retry after 1 min, then 5 min, then 15 min |
| Connection timeout (>10 seconds) | Retry after 1 min, then 5 min, then 15 min |
| DNS resolution failure | Retry after 1 min, then 5 min, then 15 min |
| All 3 retries fail | Webhook marked as failed, no more attempts |
Testing Retries
To test retry behavior, intentionally return a 500 status from your endpoint for the first few requests, then switch to 200. You should see the retried deliveries arrive at the expected intervals.
Testing Checklist
Use this checklist when setting up webhooks for the first time:
- [ ] Endpoint accessible -- Verify your URL is reachable from the internet (try
curlfrom an external machine) - [ ] Using HTTPS -- Webhook URLs must use HTTPS, not HTTP
- [ ] Correct events filter -- Check the
eventsarray in your webhook config matches what you expect - [ ] Response time -- Ensure your endpoint responds within 10 seconds
- [ ] Signature verification -- If implementing security, test with the correct raw body approach
- [ ] Idempotency -- Handle the possibility of receiving the same event more than once (retries can cause duplicates)
- [ ] Error handling -- Test with failed events (
extract.failed,agent.failed) to ensure your handler processes errors gracefully
Troubleshooting
Webhooks Not Arriving
| Symptom | Solution |
|---|---|
| No requests at all | Verify your server is publicly reachable and firewalls allow incoming HTTPS connections |
Using http:// URL | Change to https:// -- Firecrawl requires HTTPS |
| Events missing | Check the events filter in your webhook config. Remove the filter to receive all events. |
| Tunnel URL expired | Restart your tunnel service and update the webhook URL |
Signature Verification Failing
The most common cause is using the parsed JSON body instead of the raw request body:
javascript
// WRONG -- parsed body may differ from raw bytes
const hash = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(req.body))
.digest('hex');
// CORRECT -- use raw body middleware
app.use('/webhook', express.raw({ type: 'application/json' }));
app.post('/webhook', (req, res) => {
const hash = crypto
.createHmac('sha256', secret)
.update(req.body) // Raw buffer
.digest('hex');
});Other Common Issues
| Issue | Solution |
|---|---|
| Wrong secret | Verify you are using the correct secret from your account settings |
| Timeout errors | Ensure your endpoint responds within 10 seconds. Return 200 immediately and process async. |
| Duplicate events | Implement idempotency using the id field to deduplicate. Retries can cause the same event to arrive multiple times. |
Related Pages
- Webhooks Overview -- Configuration and setup
- Webhook Events -- Full event type reference
- Webhook Security -- HMAC-SHA256 signature verification