Zapier webhooks enable custom integrations between your applications and thousands of apps. Understanding webhook URLs helps you build reliable automated workflows.
Key Takeaways
- 1Catch hooks receive data via unique Zapier URLs
- 2Webhook triggers send data to your endpoints
- 3Each Zap gets a unique webhook URL
- 4Test mode requires sample data before going live
- 5Webhook responses can pass data to subsequent steps
“Webhooks by Zapier lets you trigger workflows from any app that supports webhooks, or send data to any URL that accepts HTTP requests.”
Webhook Types
Zapier supports different webhook patterns depending on whether data flows into Zapier or out to your systems. Understanding the distinction between catch hooks and webhook actions helps you design effective automation flows.
| Type | Direction | Use Case |
|---|---|---|
| Catch Hook | Receive data INTO Zapier | Custom app triggers |
| Webhooks by Zapier | Send data FROM Zapier | Custom actions |
| REST Hook | Managed subscription | App integrations |
Catch Hooks are trigger URLs that start Zaps when they receive data. Webhooks by Zapier is an action that sends data from Zapier to external URLs. REST Hooks are the managed subscription model used by native app integrations to automatically register and unregister webhooks.
Catch Hook URLs are unique endpoints that Zapier generates for each Zap. When you send data to these URLs, Zapier processes it and passes the data to subsequent steps in your automation workflow.
Catch Hook URLs
# Zapier Catch Hook URL structure
https://hooks.zapier.com/hooks/catch/{account_id}/{hook_id}/
# Example
https://hooks.zapier.com/hooks/catch/123456/abcdef/
# With query parameters (passed as fields)
https://hooks.zapier.com/hooks/catch/123456/abcdef/?source=website&priority=high
# Silent mode (no response body)
https://hooks.zapier.com/hooks/catch/123456/abcdef/silent/Each catch hook URL contains your account ID and a unique hook ID. The silent endpoint variation suppresses the response body, which can be useful when you do not need confirmation of receipt. Query parameters on the URL become additional fields in your Zap trigger data.
You can send data to catch hooks using various formats including JSON, form data, or query parameters. Zapier accepts all standard HTTP methods but POST is recommended for sending payload data.
Sending Data to Catch Hooks
// POST data to Zapier catch hook
const zapierWebhookUrl = 'https://hooks.zapier.com/hooks/catch/123456/abcdef/';
// JSON payload
await fetch(zapierWebhookUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: 'user@example.com',
name: 'John Doe',
event: 'signup',
timestamp: new Date().toISOString(),
metadata: {
source: 'website',
campaign: 'summer_2026'
}
})
});
// Form data
const formData = new FormData();
formData.append('email', 'user@example.com');
formData.append('name', 'John Doe');
await fetch(zapierWebhookUrl, {
method: 'POST',
body: formData
});
// Query string parameters (GET or POST)
const urlWithParams = new URL(zapierWebhookUrl);
urlWithParams.searchParams.set('email', 'user@example.com');
urlWithParams.searchParams.set('name', 'John Doe');
await fetch(urlWithParams.toString(), { method: 'POST' });The code demonstrates three approaches to sending data. JSON payloads are cleanest for structured data. FormData works well for simple key-value pairs. Query string parameters are useful when your sending system cannot set request bodies, though they expose data in logs and have length limitations.
When Zapier is the sender rather than receiver, you configure a Webhooks by Zapier action step. This lets you push data to any URL-based API or webhook endpoint as part of your automation workflow.
Sending Webhooks FROM Zapier
# Configure "Webhooks by Zapier" action
# URL field
https://yourapp.com/webhooks/zapier
# Method
POST, GET, PUT, PATCH, or DELETE
# Payload Type
JSON, Form, Raw
# Data fields (dynamic from trigger)
{
"email": "{{email}}",
"name": "{{name}}",
"zap_id": "{{zap_id}}",
"timestamp": "{{zap_meta_utc_iso}}"
}
# Headers (optional)
Authorization: Bearer your-api-key
Content-Type: application/json
X-Webhook-Source: zapierThis configuration shows the key settings for a webhook action. The double-brace syntax references data from earlier steps in your Zap. You can add custom headers for authentication or identification, and choose the payload format that your receiving endpoint expects.
When your application receives webhooks from Zapier, you can respond with data that becomes available to subsequent Zap steps. This enables bidirectional data flow within a single Zap execution.
Receiving Zapier Webhooks
// Express endpoint to receive Zapier webhook
const express = require('express');
const app = express();
app.use(express.json());
app.post('/webhooks/zapier', (req, res) => {
const data = req.body;
console.log('Received from Zapier:', data);
// Process the data
// e.g., create user, send notification, update database
// Respond with data for subsequent Zap steps
res.json({
success: true,
processed_at: new Date().toISOString(),
// Include data you want available in next Zap step
result: {
user_id: '12345',
status: 'created'
}
});
});
// For Zapier polling trigger (if building custom integration)
app.get('/api/zapier/items', (req, res) => {
// Return array of items, newest first
// Zapier deduplicates by 'id' field
res.json([
{ id: '3', email: 'new@example.com', created_at: '2026-01-15T10:00:00Z' },
{ id: '2', email: 'recent@example.com', created_at: '2026-01-14T10:00:00Z' },
{ id: '1', email: 'old@example.com', created_at: '2026-01-13T10:00:00Z' }
]);
});Your response JSON becomes available as fields in the next Zap step. Include a success indicator and any result data you want passed along. The polling endpoint example shows the pattern for custom Zapier integrations where Zapier periodically checks for new items rather than receiving push notifications.
Testing webhook URLs is essential before enabling a Zap in production. Zapier requires sample data to map fields for subsequent steps, and the test confirms your endpoint is accessible and responding correctly.
Testing Webhook URLs
// Test catch hook with sample data
async function testZapierWebhook(webhookUrl) {
const testData = {
email: 'test@example.com',
name: 'Test User',
event: 'test',
timestamp: new Date().toISOString()
};
try {
const response = await fetch(webhookUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(testData)
});
const result = await response.json();
console.log('Response:', result);
// Zapier returns:
// { "status": "success", "attempt": "...", "id": "...", "request_id": "..." }
return result.status === 'success';
} catch (error) {
console.error('Webhook test failed:', error);
return false;
}
}
// Validate your receiving endpoint
async function validateEndpoint() {
// Zapier may send a test request during setup
// Return 200 status with any valid JSON
}
// Note: Zapier requires successful test before enabling Zap
// Send sample data matching your expected formatThe test function sends sample data and checks for Zapier's success response. After testing, Zapier captures the payload structure so you can reference individual fields in later Zap steps. Make sure your test data represents the full structure of real payloads so all fields are available for mapping.
Sometimes you need to pass data via URL parameters rather than request body. This is common when integrating with systems that can only make GET requests or cannot customize request bodies. Zapier treats query parameters as additional data fields.
URL Parameters as Data
// Pass data via URL parameters
const baseUrl = 'https://hooks.zapier.com/hooks/catch/123456/abcdef/';
function buildZapierUrl(data) {
const url = new URL(baseUrl);
// Add each field as a query parameter
Object.entries(data).forEach(([key, value]) => {
if (typeof value === 'object') {
url.searchParams.set(key, JSON.stringify(value));
} else {
url.searchParams.set(key, String(value));
}
});
return url.toString();
}
// Usage
const webhookUrl = buildZapierUrl({
action: 'new_order',
order_id: '12345',
total: 99.99,
items: ['SKU-001', 'SKU-002']
});
// Result:
// https://hooks.zapier.com/hooks/catch/123456/abcdef/?action=new_order&order_id=12345&total=99.99&items=%5B%22SKU-001%22%2C%22SKU-002%22%5D
// Zapier receives these as individual fields
// Can use GET or POST requestThe buildZapierUrl function converts an object of data into URL query parameters. Complex values like arrays are JSON-stringified before encoding. The resulting URL can be called with either GET or POST, making this approach flexible for various integration scenarios where body customization is limited.