NodukanNodukan/ Developers
API Reference

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#

MethodPathScopeDescription
GET/webhookswebhooks:readList all webhook endpoints
POST/webhookswebhooks:writeCreate a webhook endpoint
PUT/webhooks/:idwebhooks:writeUpdate a webhook endpoint
DELETE/webhooks/:idwebhooks:writeDelete a webhook endpoint
POST/webhooks/:id/testwebhooks:writeSend 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#

FieldTypeRequiredDescription
urlstring (URL)✅HTTPS endpoint to deliver events to
eventsstring[]✅Array of event types to subscribe to
descriptionstringInternal label for this endpoint
isActivebooleanWhether to deliver events (default true)
headersobjectCustom 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..."
}
Warning:

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.

Was this helpful?
Edit on GitHub

Last updated