Webhooks
A **webhook **is simply a way for one application to send data to another automatically, the moment something important happens. Think of it as a notification system between apps. At the center of this system is a webhook URL, which serves as an address that one app knows to deliver data to the other.
Let’s understand this with an example. Imagine you ordered something from an online store. Now, you have two choices to track your package:
-
Polling: You keep calling the store every hour asking, “Is my package ready yet”?
-
Webhooks: The store calls you the moment your package is ready and sends it straight to your doorstep.
The second one is easier, faster, and saves everyone time. This is exactly how webhooks work in software.
Polling means your app repeatedly checks another system to see if new data is available. This consumes time and resources, especially if nothing has changed.
Webhooks, on the other hand, remove this back-and-forth. Instead of your app checking all the time, the other app pushes data to you only when something happens, like when a new order is created, a lead is added, or a record is updated.
How It Works
Technically, a webhook is an automated POST``
request that one application sends to another when a specific event occurs. The request contains a payload, which is the data or message you care about. That message is sent to a URL you’ve set up to receive these kinds of updates, called the webhook URL.
For example, let’s say your server has this webhook URL:
https://yourapp.com/order
Whenever the e-commerce system processes a new order for you, it sends a request to that URL with the order details. Your server receives it, understands what happened, and takes action, maybe saving the order to your database, sending a confirmation to your user, or starting the delivery process.
You don’t have to ask. You don’t have to wait; you just get notified the moment something happens.
Why Use Webhooks?
Webhooks are like push notifications for systems. They’re efficient, instant, and event-driven. They’re used when your app needs to respond to something happening in another app, and it needs to happen right away.
They help avoid constant API calls or background jobs. Instead, you can simply wait for the other system to push the data to you when needed. This makes your app more efficient and responsive, and reduces unnecessary load on both sides.
In short, a webhook is a smart, automated way to say:
“No waiting, no checking - just instant updates.”
How to Set Up Webhooks for Knit Syncs
Knit uses webhooks to send you real-time events during data syncs. For example, during an employee sync for an HRIS app, you might receive information whenever a new employee is added, an existing employee’s details are modified, or a record is removed.
Step 1: Set up a Public API route
Before you can start receiving real-time updates, you need to set up a webhook endpoint where Knit can deliver these events.
To get started, you need to create a public API endpoint on your server. This is the URL where Knit will send these event notifications. Make sure this endpoint:
-
Accepts only POST requests
-
It is publicly accessible and uses HTTPS for secure communication
Example:
https://yourdomain.com/knit/webhook
Step 2: Handle Knit events
Your webhook handler should be able to process five main Knit events:
-
record.new
- Sent when a new record is detected (e.g., a new employee or job post). \ -
record.modified
- Sent when existing data is updated (e.g., changes to employee details). \ -
record.deleted
- Sent when a record is removed or marked inactive. -
sync.events.processed
- Indicates that a sync has completed processing a certain number of records. -
sync.events.allConsumed
- Signals that the sync is fully completed and all events have been acknowledged. -
sync.heartbeat
- Provides a tentative count of records processed during an ongoing sync. -
sync.failed
- Notifies you when a sync run has failed due to an issue.
Each event is sent as a JSON payload to your webhook. Knit always sends one record per request, meaning if there are 500 records, your webhook will be called 500 times.
For a detailed explanation of these events, see the ‘Setting Up the Webhook for Knit Syncs’ section.
Step 3: Validate Incoming Requests
Before processing the event data, validate that the request is genuinely coming from Knit. Every webhook request includes two important headers:
-
X-Knit-Integration-Id
- Represents the integration ID of the connected account. This can be used to identify which account the webhook payload belongs to. -
X-Knit-Signature
- Used to authenticate the incoming request. An HMAC-SHA256 signature is generated using your API key.
Note: Use these headers to verify authenticity. If the signature is missing or invalid, reject the request to prevent unauthorized data injections. Refer to Authenticating Knit Webhooks for full details on validating signatures.
Step 4: Acknowledge the Event
Return an HTTP 200 ``OK
status to confirm event consumption. If your endpoint doesn’t return 200 - OK
, Knit retries every 30 minutes for up to 4 days.
Step 5: (Recommended): Monitor Sync Progress
**While not required for your webhook to function, it’s highly recommended to monitor sync progress.
During a sync, you can track how data is being processed using these events:
-
sync.heartbeat
- Provides tentative counts of processed records during the sync. -
sync.events.processed
- Offers accurate counts of processed and emitted records once a sync is done.
Use the Logs and Issues pages in the Knit Dashboard to troubleshoot event deliveries and monitor webhook performance.
Example Webhook Handler
post("/knithook", (req, res) -> {
String integrationId = req.headers("X-Knit-Integration-Id");
String actualSignature = req.headers("X-Knit-Signature");
String reqBody = req.body();
String expectedSignature = getSignature("Your_API_Key", reqBody);
if (actualSignature == null || !actualSignature.equals(expectedSignature)) {
res.status(401);
return "Unauthorized";
}
JsonNode event = new ObjectMapper().readTree(reqBody);
String eventType = event.get("eventType").asText();
switch (eventType) {
case "record.new":
// handle new record
break;
case "record.modified":
// handle modified record
break;
case "record.deleted":
// handle deleted record
break;
case "sync.events.processed":
// handle sync processed
break;
case "sync.events.allConsumed":
// handle completion
break;
case "sync.heartbeat":
// track progress
break;
case "sync.failed":
// handle failure
break;
}
res.status(200);
return "OK";
});
How to Register a Webhook
After creating and configuring your webhook handler, the next step is to register it in the Knit Dashboard so it can start receiving real-time sync events.
First, make sure that your webhook URL is publicly accessible over HTTPS and configured to accept POST
requests. This URL will be used in Step 2 of the** “Getting Started”** process.
Once your endpoint is ready, go to the “Register Webhook URL” section in the Knit Dashboard. Paste your public webhook URL into the provided field and save it. After saving, you can test event delivery directly from the dashboard.
Knit will send various event types, such as record.new
, record.modified
, record.deleted
, sync.events.processed
, and sync.events.allConsumed
, allowing you to verify that your webhook correctly handles each one. Make sure your handler validates the signature headers and processes these test events successfully.
After all tests pass and the webhook is successfully registered, you can enable the relevant category. Once enabled, your integration will begin receiving real-time sync events from Knit.
Refer to the 'How to Register a Webhook' guide for instructions on registering your URL, selecting event types, and testing the integration before enabling it.
Types of Webhooks
Knit supports two types of webhooks: Virtual Webhooks and Native Webhooks. Both deliver standardized events to your endpoint, but they differ in how the events are generated and delivered.
Virtual Webhooks
Some applications don’t have built-in support for outgoing webhooks. To handle these cases, Knit provides Virtual Webhooks, a mechanism that delivers near real-time updates without requiring the source app to support webhooks natively.
Or
Virtual webhooks allow Knit to deliver data change events to your application even when the source app doesn’t support native webhooks. Knit continuously polls the source application’s API on a schedule and pushes any detected changes to your webhook endpoint. This creates a near-real-time experience without requiring you to build your own polling system.
How it works
With Virtual Webhooks, Knit continuously polls the source application’s API in the background. Whenever it detects a new record, an update, or a deletion, Knit transforms this change into a webhook event and sends it to your configured URL.
For example, if an HRIS system without webhook support adds a new employee, Knit’s sync engine will detect this change and immediately trigger a record.new
event to your webhook URL. Similarly:
-
Modified records →
record.modified
events -
Deleted records →
record.deleted
events -
Sync lifecycle events →
sync.events.processed
,sync.events.allConsumed
,sync.heartbeat
, andsync.failed
.
Each event includes data formatted in Knit’s unified model, ensuring consistent handling across different integrations.
Some Key Points about Virtual Webhooks:
-
Push-based behavior: Even if the source only supports data polling, Knit provides a webhook-like, event-driven experience.
-
Low latency: Updates are usually delivered within seconds, and a full sync cycle typically completes within minutes (depending on API speed and rate limits).
-
Granular events: Each record generates a separate webhook call (e.g., 500 new records result in 500 individual webhook events).
-
No polling infrastructure needed: Knit manages all background polling and event transformation, saving you from building it yourself.
In short, Virtual Webhooks allow you to integrate “pull-only” applications into a modern, push-based architecture, giving your backend real-time event streams without additional complexity.
Use Case
Useful for legacy or older apps (e.g., many HRIS or ATS systems) that only allow data retrieval via API. Knit handles polling, retries, and rate-limiting for you, so you receive updates without building your polling infrastructure.
Example: An HR system without webhook support can still notify your app about new employees. Knit polls the system, converts changes into a unified data model, and delivers them via webhooks as soon as they’re found.
Or
Knit handles the complexities of polling, retries (up to 4 days for failed deliveries), and rate-limiting. This gives you real-time-like data updates without building your own polling or retry systems.
Example: An HRIS app without webhooks can still notify you about new employees. Knit polls the HR system, converts new or updated employee data into its unified model, and delivers it to your webhook endpoint.
Benefits
-
Works with any app: Even if an app doesn’t support webhooks, you’ll still receive webhook-style updates. \
-
No extra infrastructure: Knit handles scheduling, polling, retries, and comparison logic. Your app only needs to process incoming webhook events. \
-
Bulk data handling: Ideal for syncing large datasets like full employee directories or product catalogs. \
-
Unified event format: Virtual webhooks use the same standardized payload as native webhooks, including fields like
eventType
,eventData
, timestamps, and sync metadata.
Example Payload:
{
"eventId": "ev_12345",
"eventType": "record.new",
"eventData": { /* Unified model data */ },
"syncType": "initial_sync",
"syncDataType": "employee",
"recordId": "123",
"triggeredAt": "1676292064383"
}
**Note: **Knit sends one webhook per record change (e.g., 500 new employees = 500 webhook calls).
Automatic Setup
No special configuration is needed. Once you register your webhook URL and start syncing, Knit automatically switches to virtual mode if the integration requires it.
Virtual webhooks give you push-based updates even from apps without native event APIs, ensuring your system stays up to date with minimal delay. While there may be a slight lag (based on polling frequency), it provides a reliable near-real-time experience across all integrations.
Native Webhooks
Native webhooks in Knit enable direct, real-time event delivery by using the source application’s own webhook or event subscription capabilities. When an app natively supports webhooks, Knit acts as a bridge: it subscribes to those events in the source app, listens for any data changes, and immediately forwards those events to your registered webhook endpoint.
This approach is ideal for instant, record-level updates where data changes need to be reflected in your application without delays. Unlike bulk syncs that periodically pull large datasets, native webhooks push only the specific changes that happen, as they happen.
For example, when a new lead is added in HubSpot, the app sends a webhook notification to Knit, which instantly forwards that notification to your app, maintaining real-time synchronization.
How Native Webhooks Work
When a user connects their account, Knit checks if the source application supports webhooks. If it does, Knit automatically subscribes to key events such as record creation, updates, and deletions. This means Knit is actively listening for changes in the connected app without the need for polling. Whenever a change occurs, the source application immediately sends an event notification (usually via an HTTP POST request) to Knit, allowing for instant event capture.
Once the event is received, Knit processes and transforms the data into its unified model format, ensuring consistency across different integrations. The transformed event is then forwarded to your registered webhook endpoint using standard event types like record.new
, record.modified
, or record.deleted
.
For example, when a new contact is created in HubSpot, HubSpot’s native webhook sends this data to Knit, which standardizes it and delivers a crm_contacts_new
event to your webhook containing the new contact’s details. This process enables real-time, reliable data updates without requiring additional syncs or manual API calls.
Or
For example, imagine a new contact is created in HubSpot. The HubSpot application instantly triggers its native webhook, sending the event to Knit. Knit then transforms that data into its standardized format and immediately delivers a crm_contacts_new
event to your webhook endpoint. The payload contains all the necessary details about the new contact, allowing your system to process the update without manually querying HubSpot’s API. This seamless flow, from subscription and capture to transformation and delivery, provides a fully automated, real-time integration experience.
Updated 23 days ago