Documentation Index
Fetch the complete documentation index at: https://docs.nedzo.ai/llms.txt
Use this file to discover all available pages before exploring further.
Fires when an external system sends an HTTP POST request to the workflow’s unique webhook URL. Use this to connect Nedzo to any external tool — Zapier, Make, n8n, your own backend, or anything that can send HTTP requests.
When it fires
The trigger fires immediately when a valid POST request hits the webhook URL. Each request creates one workflow execution. Unlike other triggers, webhook triggers are not deduplicated — every request runs the workflow.
Configuration
When you add a webhook trigger, Nedzo generates two things:
| Field | Description |
|---|
| Webhook URL | The unique URL to send requests to. This stays the same even if you regenerate the token or change auth. |
| Webhook token | A 64-character secret embedded in the URL path. Cryptographically identifies the caller. |
Regenerating the token
Click Regenerate in the trigger settings to create a new token. The old token stops working immediately. The URL stays the same.
Authorization
The 64-character token in the URL authenticates the caller by itself. For extra protection, configure an additional authorization scheme from the trigger settings.
| Scheme | How it works |
|---|
| None (default) | Token in the URL is the only credential. Fine for most integrations — the token is 256 bits of entropy. |
| HMAC | Caller signs each request with a shared secret using HMAC-SHA256. Timestamp-bound so replayed requests are rejected. Recommended if you need tamper-proof payloads. |
| Bearer | Caller sends a static token in the Authorization: Bearer <token> header. |
| Basic | Caller sends Authorization: Basic <base64(user:pass)> using HTTP Basic auth. |
Failed auth attempts are rate-limited per trigger. After too many bad attempts in a short window the trigger returns 401 until the cooldown ends.
HMAC details
When HMAC is selected, Nedzo gives you a shared secret and two header names (defaults: X-Nedzo-Signature, X-Nedzo-Timestamp). To sign a request:
- Take the current Unix timestamp in seconds (e.g.
1730000000).
- Build the signed string:
{timestamp}.{rawRequestBody}.
- Compute
HMAC-SHA256(secret, signedString) and hex-encode the result (64 characters).
- Send the hex digest in the signature header and the timestamp in the timestamp header.
Example (Node.js):
import crypto from 'crypto';
const timestamp = Math.floor(Date.now() / 1000);
const body = JSON.stringify({ firstName: 'John', phone: '+14155551234' });
const signature = crypto
.createHmac('sha256', SHARED_SECRET)
.update(`${timestamp}.${body}`)
.digest('hex');
await fetch(webhookUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Nedzo-Timestamp': String(timestamp),
'X-Nedzo-Signature': signature,
},
body,
});
Requests with a timestamp more than 5 minutes off from the server clock are rejected. Each signature can only be used once inside the tolerance window (replay protection).
Sample payload
The trigger UI lets you capture a sample payload. Send a test request to the webhook URL, and Nedzo captures the payload structure. This is used to:
- Show available fields in the condition builder
- Provide autocomplete for variable references in actions
- Auto-detect contact fields (email, phone) for downstream contact-scoped actions
If your workflow has a Make phone call, Send SMS, or Send email action set to “Contact” recipient, the webhook payload itself supplies the contact data — there’s no contact in scope at trigger time.
The trigger config shows a Contact fields section with one row per required field (Email, Phone), based on which actions you’ve added downstream. For each field, Nedzo:
- Auto-detects common field names from the captured sample payload —
email / emailAddress / email_address for Email, and phone / phoneNumber / phone_number for Phone. Auto-detection is case-insensitive and works on top-level fields.
- Falls back to a dropdown of every string-valued path in the sample payload, so you can map a non-standard field. Useful for nested values like
data.lead.cell or aliases like mobile.
If a required field can’t be resolved (no auto-detect match, no explicit mapping, no contactId in the payload), the Publish button is disabled with a tooltip explaining what’s missing, and the webhook trigger node shows an attention indicator on the canvas. Once every required field is resolvable, Publish becomes available.
If your payload includes a contactId that matches an existing contact, that takes precedence — the Email and Phone mapping is bypassed entirely and the contact is loaded from the database. Useful when the upstream system already knows the Nedzo contact ID.
{
"contactId": "a1b2c3d4-..."
}
Sending a request
Send an HTTP POST with a JSON body. The 64-character token is part of the URL path:
curl -X POST "https://api.nedzo.ai/webhooks/trigger/{webhook-token}" \
-H "Content-Type: application/json" \
-d '{
"firstName": "John",
"lastName": "Doe",
"phone": "+14155551234",
"email": "john@example.com",
"dealValue": 5000,
"source": "website-form"
}'
If the trigger is configured with HMAC, Bearer, or Basic auth, add the required headers as well — see the Authorization section above.
Request requirements
| Requirement | Details |
|---|
| Method | POST only |
| Content-Type | application/json |
| Body | Valid JSON, max 1 MB |
| Extra auth headers | Only required if the trigger has HMAC/Bearer/Basic enabled |
Data available
Every field you send in the request body is available as a variable using the {{trigger.webhook.body.*}} pattern.
For the example payload above:
| Variable | Value |
|---|
{{trigger.webhook.body.firstName}} | John |
{{trigger.webhook.body.lastName}} | Doe |
{{trigger.webhook.body.phone}} | +14155551234 |
{{trigger.webhook.body.email}} | john@example.com |
{{trigger.webhook.body.dealValue}} | 5000 |
{{trigger.webhook.body.source}} | website-form |
If you include a contactId in the payload and it matches an existing contact, the contact’s standard fields ({{firstName}}, {{phone}}, etc.) are also loaded. Otherwise, contact-scoped actions resolve the contact from the email/phone fields you mapped in the trigger config — see Contact field mapping above.
Use case examples
Connect a Zapier Zap to send form data to Nedzo and call the lead.
- In Zapier: Create a Zap with your form tool as trigger, and a Webhook action pointing to your Nedzo webhook URL
- Map fields: firstName, lastName, phone, email
- In Nedzo:
- Trigger: Webhook
- Action: Update contact — Create contact from webhook data
- First name:
{{trigger.webhook.body.firstName}}
- Phone:
{{trigger.webhook.body.phone}}
- Tags: “website-lead”
- Action: Wait — 2 minutes
- Action: Voice call — Sales agent
Trigger from your backend on deal close
Your app sends a POST when a deal closes.
- Trigger: Webhook
- Action: Send SMS
- Message: “Congrats
{{trigger.webhook.body.firstName}}, your deal is confirmed! We’ll be in touch with next steps.”
- Action: Slack message — #wins
- Message: “Deal closed:
{{trigger.webhook.body.firstName}} {{trigger.webhook.body.lastName}} — ${{trigger.webhook.body.dealValue}}”
Trigger from Make (Integromat)
Use a Make HTTP module to call the webhook URL after any automation step.
- In Make: Add an HTTP “Make a request” module
- URL: Your Nedzo webhook URL
- Method: POST
- Body: JSON with your data
- In Nedzo: Build any workflow using the incoming data
Manual trigger via API
Use the webhook URL from your own code or Postman for testing or custom integrations.
const response = await fetch(webhookUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
contactId: 'existing-contact-id',
customData: 'anything you need'
})
});