When to use syncs
Syncs are the right tool when you need to:- Store a local copy of external data and keep it up to date (CRM contacts, Drive files, call transcripts).
- Feed a RAG pipeline — embed and index fresh documents as they change.
- Build a search index — re-index records only when they change.
- Trigger workflows on new or modified data without requiring the external API to support webhooks.
- Combine polling with webhooks for a reliable, real-time stream of changes.
How syncs work
1
Sync function runs on a schedule
You define a sync function in TypeScript. Nango executes it on each connection at your chosen frequency (minimum 15 seconds). The function fetches data from the external API, transforms it to your model, and saves it with
nango.batchSave().2
Nango detects changes
Nango compares incoming records against the previous snapshot and identifies additions, updates, and deletions automatically.
3
Webhook notification
After each sync run, Nango sends a webhook to your backend with a
modifiedAfter timestamp. You fetch only the changed records.4
Your app processes records
You call
nango.listRecords() (or the REST API) with the cursor or timestamp from the webhook, retrieve the delta, and store or process the records in your system.Full sync vs. incremental sync
Checkpoints are saved with
nango.saveCheckpoint() and retrieved with nango.getCheckpoint(). On the first run, getCheckpoint() returns null, so you fetch everything. On subsequent runs, you pass the saved timestamp to the API to fetch only the delta.
Building a sync
The following example syncs contacts from Salesforce incrementally:nango.getCheckpoint()— retrieves saved checkpoint; returnsnullon first run.nango.saveCheckpoint()— persists progress so the next run resumes from here.nango.batchSave(records, modelName)— writes records to Nango’s encrypted cache.nango.get({ endpoint })— makes an authenticated request to the external API.
Reading synced records
After receiving a webhook notification from Nango, fetch the changed records using themodifiedAfter timestamp or a cursor.
Fetch by timestamp
- Node SDK
- REST API
Cursor-based synchronization
Webhooks can occasionally be missed. Cursor-based synchronization is more reliable — it tracks exactly how far you’ve consumed the record stream per connection, regardless of missed notifications. Each record includes a_nango_metadata.cursor field. Store the cursor of the last record you processed. On the next fetch, pass that cursor to receive only records modified after it:
- Node SDK
- REST API
- Receive a webhook notification from Nango.
- Look up the stored cursor for this connection and model.
- Call
listRecordswith that cursor. - Process and store the records.
- Save the cursor from the last record for next time.
Record metadata
Every record returned bylistRecords includes a _nango_metadata object automatically populated by Nango:
last_action is one of ADDED, UPDATED, or DELETED. Use it to decide whether to insert, update, or remove the record from your system.
Webhooks for real-time triggers
Nango sends a webhook to your backend after each sync run that produces changes. Configure your webhook endpoint in the Nango dashboard, then handle incoming events:Polling vs. event-driven
Nango supports both approaches and lets you combine them:
See the real-time syncs guide for instructions on configuring external webhook triggers.