Webhooks Management
API reference for managing Nodukan webhook endpoints — create, update, delete, and test webhook subscriptions.
Webhooks Management API
The Webhooks API lets you programmatically manage your webhook endpoint subscriptions — create endpoints, update their event subscriptions, and test delivery.
For information on receiving and verifying webhooks, see Webhooks.
Endpoints#
| Method | Path | Scope | Description |
|---|---|---|---|
GET | /webhooks | webhooks:read | List all webhook endpoints |
POST | /webhooks | webhooks:write | Create a webhook endpoint |
PUT | /webhooks/:id | webhooks:write | Update a webhook endpoint |
DELETE | /webhooks/:id | webhooks:write | Delete a webhook endpoint |
POST | /webhooks/:id/test | webhooks:write | Send a test event |
GET /webhooks#
Returns all registered webhook endpoints for the account.
curl https://api.nodukan.com/v1/webhooks \
-H "Authorization: Bearer NDK_live_..."
const res = await fetch('https://api.nodukan.com/v1/webhooks', {
headers: { Authorization: `Bearer ${process.env.NODUKAN_API_KEY}` },
});
const { data } = await res.json();
Response#
{
"data": [
{
"id": "wh_01j9x4km2v",
"url": "https://your-server.example.com/webhooks/nodukan",
"description": "Forward leads to HubSpot CRM",
"events": ["lead.captured"],
"isActive": true,
"successRate": 0.99,
"lastDeliveryAt": "2026-05-06T10:15:30Z",
"lastDeliveryStatus": "success",
"createdAt": "2025-11-10T08:00:00Z"
},
{
"id": "wh_01j9y7mp3k",
"url": "https://your-server.example.com/webhooks/social",
"description": "Slack notification on post publish/fail",
"events": ["post.published", "post.failed"],
"isActive": true,
"successRate": 1.0,
"createdAt": "2026-01-15T10:00:00Z"
}
],
"requestId": "req_01j9xabc..."
}
Note: The signingSecret is never returned in list or get responses after initial creation.
POST /webhooks#
Creates a new webhook endpoint. The signingSecret is returned only in this response — save it immediately.
Request body#
| Field | Type | Required | Description |
|---|---|---|---|
url | string (URL) | ✅ | HTTPS endpoint to deliver events to |
events | string[] | ✅ | Array of event types to subscribe to |
description | string | Internal label for this endpoint | |
isActive | boolean | Whether to deliver events (default true) | |
headers | object | Custom headers to include in deliveries (e.g., for auth tokens) |
Available event types: lead.captured, lead.magnet.updated, chat.new, chat.message.received, post.published, post.failed, short_url.clicked, automation.triggered, subscription.updated
Use ["*"] to subscribe to all current and future event types.
curl -X POST https://api.nodukan.com/v1/webhooks \
-H "Authorization: Bearer NDK_live_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.example.com/webhooks/nodukan",
"events": ["lead.captured", "chat.new"],
"description": "CRM integration — leads + chat events",
"headers": {
"X-Internal-Token": "my-secret-header-value"
}
}'
const res = await fetch('https://api.nodukan.com/v1/webhooks', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.NODUKAN_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
url: 'https://your-server.example.com/webhooks/nodukan',
events: ['lead.captured', 'chat.new'],
description: 'CRM integration',
}),
});
const { data } = await res.json();
// Save data.signingSecret to your secrets manager NOW
process.env.NODUKAN_WEBHOOK_SECRET = data.signingSecret;
Response 201 Created#
{
"data": {
"id": "wh_01j9znew00",
"url": "https://your-server.example.com/webhooks/nodukan",
"description": "CRM integration — leads + chat events",
"events": ["lead.captured", "chat.new"],
"signingSecret": "whsec_01j9xm4r7k2p9d1f...",
"isActive": true,
"createdAt": "2026-05-06T11:00:00Z"
},
"requestId": "req_01j9xabc..."
}
The signingSecret is shown only once at creation time. Store it in your secrets manager immediately. If you lose it, delete the webhook and create a new one.
PUT /webhooks/:id#
Updates an existing webhook. You can change the URL, events, active state, or description. Send only the fields you want to change.
# Add a new event subscription
curl -X PUT https://api.nodukan.com/v1/webhooks/wh_01j9x4km2v \
-H "Authorization: Bearer NDK_live_..." \
-H "Content-Type: application/json" \
-d '{"events": ["lead.captured", "chat.new", "post.published"]}'
# Temporarily disable delivery
curl -X PUT https://api.nodukan.com/v1/webhooks/wh_01j9x4km2v \
-H "Authorization: Bearer NDK_live_..." \
-H "Content-Type: application/json" \
-d '{"isActive": false}'
Returns the updated webhook object (without signingSecret).
DELETE /webhooks/:id#
Permanently deletes a webhook endpoint. All pending deliveries for this endpoint are cancelled.
curl -X DELETE https://api.nodukan.com/v1/webhooks/wh_01j9x4km2v \
-H "Authorization: Bearer NDK_live_..."
Returns 204 No Content on success.
POST /webhooks/:id/test#
Delivers a synthetic test event to the webhook endpoint. The test payload includes a clearly marked "isTest": true field.
curl -X POST https://api.nodukan.com/v1/webhooks/wh_01j9x4km2v/test \
-H "Authorization: Bearer NDK_live_..."
const res = await fetch(`https://api.nodukan.com/v1/webhooks/${webhookId}/test`, {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.NODUKAN_API_KEY}` },
});
const { data } = await res.json();
console.log('Test delivery:', data.status, data.httpStatusCode);
Response#
{
"data": {
"deliveryId": "del_01j9znew00",
"webhookId": "wh_01j9x4km2v",
"status": "success",
"httpStatusCode": 200,
"durationMs": 142,
"sentAt": "2026-05-06T11:00:00Z",
"testPayload": {
"id": "evt_test_01j9xabc",
"event": "lead.captured",
"isTest": true,
"createdAt": "2026-05-06T11:00:00Z",
"data": {
"leadMagnetId": "lm_test",
"leadMagnetTitle": "Test Lead Magnet",
"lead": {
"id": "lead_test",
"email": "[email protected]",
"name": "Test User",
"capturedAt": "2026-05-06T11:00:00Z"
}
}
}
},
"requestId": "req_01j9xabc..."
}
If the test delivery fails (non-2xx response from your endpoint), status will be failed and httpStatusCode will reflect what your server returned.
Last updated