This approach of syncing with Kombo is deprecated and will be removed in the
future. For the modern approach, see Syncing Data. Also see
Migrate to Data Changed for how to
migrate to the new approach.
Syncing Data
To sync data from Kombo into your database, just call the endpoints you are
interested in and handle the data on your side. To allow for faster syncs,
we strongly recommend only fetching the changes that happened since the last sync.
You don’t have to worry about missing changes on your side when following the
approach outlined below.
Listen to Webhooks
Kombo provides webhooks to notify you when we finish a sync or receive a webhook
about changes from the ATS system. We are tracking any changes diligently
on our side so you don’t have to worry about what kind of change happened.
You can leverage those webhooks from Kombo to fetch any changes that happened
since your last sync with Kombo.
To implement this, create a webhook subscription for the sync-finished and
remote-event-received webhooks on the webhook page.
Learn how to use webhooks in development and how to authenticate them here.
React to webhooks
After receiving a webhook, you can use the integration_id in the body to fetch
updated data from Kombo into your database. Do that by calling the endpoints
you are interested in while providing the updated_after query parameter. This
parameter is available for all Kombo GET endpoints. The endpoints are still
paginated when using the updated after filter.
We recommend that you persist the timestamp of your last fetching process in
your database and use that as the updated_after filter.
Important: Do NOT use the sync_started_at field from the webhook payload
as your updated_after parameter. The sync_started_at represents when Kombo
started syncing from the ATS, not when you started fetching from Kombo. Using
sync_started_at will cause you to miss data that was created/updated via
webhooks before the sync started. Always track your own fetch timestamp as
shown in the example below.
Here is an example of how this could be implemented in Node.js:
/**
* @param {Object} options
* @param {number} options.customerId Id of the customer in your database
* @param {boolean} options.syncOnlyUpdates Specify if you want to sync deltas or full sync.
* > It's recommended to run a full sync from time to time and updates if you want to receive changes.
*/
async function syncCustomer({
customerId,
syncOnlyUpdates,
}: {
customerId: number
syncOnlyUpdates: boolean
}) {
// Assuming we are using prisma as our ORM
const customer = await prisma.customer.findUniqueOrThrow({
where: {
id: customerId,
},
select: {
last_synced_from_kombo_at: true,
kombo_integration_id: true, // Also select the integration ID
},
})
// IMPORTANT: We track when WE start fetching from Kombo (not when Kombo synced from the ATS)
// This ensures we don't miss any changes that happen between fetches
const ourFetchStartTime = new Date() // This time should be in UTC
const lastFetchStartTime = customer?.last_synced_from_kombo_at?.toISOString()
let cursor
do {
const resp = await axios.get('https://api.kombo.dev/v1/ats/applications', {
headers: {
Authorization: `Bearer ${KOMBO_API_KEY}`,
'X-Integration-Id': customer.kombo_integration_id ?? '', // Use the stored integration ID
},
params: {
cursor: cursor,
updated_after: syncOnlyUpdates ? lastFetchStartTime : undefined,
},
})
cursor = resp.data.data.next
// Implement your handling logic here
// Usually, you will upsert the data into your database and build specific
// domain logic here.
await handleApplicationData(resp.data.data.results)
} while (cursor)
// Save our fetch start time to use as updated_after in the next fetch
await prisma.customer.update({
where: {
id: customerId,
},
data: {
last_synced_from_kombo_at: ourFetchStartTime,
},
})
}