When to use syncs
Syncs are ideal when you want to:- Store a copy of external API data in your app and keep it up to date
- Detect changes in external APIs that don’t offer webhooks
- Combine polling and webhooks for a reliable, real-time stream of changes
- Syncing contacts, companies, or deals from CRMs (HubSpot, Salesforce, Attio, etc.)
- Syncing files from drives (Google Drive, SharePoint, Box, etc.)
- Syncing call transcripts from video recorders (Gong, Fathom, Zoom, etc.)
Key facts
- Syncs run in Nango’s infrastructure, powered by Functions
- You control the code: which data to fetch, transformations, data models, etc.
- All platform features are available: data validation, per-customer config, retries, rate-limit handling, and pagination
- Syncs run in the context of each Connection (API key or access token of your user)
- Syncs can be incremental (only fetch changed data) or full refresh (always fetch all data)
- Synced data is cached in Nango (encrypted at rest and in transit)
- Nango detects changes (additions, updates, deletes) and sends webhooks to your app
- You set the polling frequency (15 seconds minimum interval)
- All sync runs and API requests are logged in Nango’s logs
Syncs in detail
Incremental vs. full-refresh syncs
Nango supports both modes and automatically detects changes to records in either.| Mode | Description | Best for |
|---|---|---|
| Incremental | Only fetches data changed since last execution | Large datasets; requires API support for querying modified records |
| Full refresh | Retrieves entire dataset each execution | APIs without last-modified filtering; fallback option |
syncType: 'incremental' or syncType: 'full' in your sync definition.
Deletion detection
Nango can detect deleted records on external APIs. For incremental syncs, this requires specific API support. For full-refresh syncs, deletes are always detectable. Follow the deletion detection guide for implementation details.Real-time syncs with webhooks
Nango supports real-time syncs using webhooks. You can rely entirely on webhooks or combine them with polling to ensure you never miss data. Follow the real-time syncs guide to add real-time support.How to build a sync
If you are using a function template, you can skip to using a sync.
Step 1 - Initial Functions setup
If you don’t have anango-integrations folder yet, follow the initial Functions setup guide first.
Otherwise, you can skip to the next step.
Step 2 - Start dev mode
Before you plan to modify your integration functions, run:Step 3 - Create the sync file
In yournango-integrations folder, create the file for your new sync function.
Sync files should be within a syncs folder, which is nested under the integration’s folder.
For example, if you want to create a new sync to sync contacts from salesforce, your structure should look like this:
salesforce-contacts.ts
index.ts file:
index.ts
Step 4 - Implement your sync
In theexec method, implement the logic of your sync. Edit MyObject to contain the properties you need.
The following can help you with your implementation:
nangoobject reference to understand the SDK methods available in syncs- Our integration templates repo has 800+ examples of syncs & actions implemented by Nango
- Leveraging AI agents guide to build syncs with claude code, cursor & other AI agents
salesforce-contacts.ts
nango.lastSyncDateis the last date at which the sync has runawait nango.batchSave()to persist external data in Nango’s cacheawait nango.get()to perform an API request (automatically authenticated by Nango)await nango.log()to write custom log messages
Step 5 - Test your sync locally
Easily test your integration functions locally as you develop them with thedryrun function of the CLI:
--diagnostics flag displays detailed performance metrics including average and peak memory usage (RSS, heap, external) and CPU utilization, which is useful for performance tuning and identifying memory leaks.
To learn more about all the options for the dryrun, run: nango dryrun --help.
Because this is a dry run, syncs won’t persist data in Nango. Instead, the retrieved data is printed to the console.
Step 6 - Deploy your sync
To run your sync in Nango, you need to deploy it to an environment in your Nango account. To deploy all integrations in yournango-integrations folder, run:
--sync parameter:
nango deploy -h for more options to deploy only parts of your integrations.
To fetch the synced data in your product, follow the steps in the next setion.
How to use a sync
Pre-built integration templates
For common use cases, pre-built integration templates are available to help you get started fast. Select your integration in the Integrations tab, and navigate to the Endpoints tab. Available pre-built sync integrations will appear in the endpoint list. Select the relevant one and enable it with the toggle. Nango will automatically sync the corresponding data in the background for each relevant connection. Integration templates are a starting point. You will likely need to customize them or create your own custom sync.Step 1 - Setup webhooks from Nango
Nango sends webhook notifications to your backend whenever new data is available for a connection & sync combination. Set these up by following the implement webhooks from Nango guide. When the sync finishes, Nango will send you a webhooks with this payload.Step 2 - Fetch the latest data from Nango
After receiving a Nango webhook, fetch the latest records using the backend SDK (reference) or API (reference). Use themodifiedAfter timestamp from the webhook payload as a parameter in your request to fetch only the modified records.
- cURL (standard endpoint)
- Node SDK
Cursor-based synchronization
In practice, webhook notifications can be missed, and relying solely on the webhook payload to fetch modified records can cause you to miss some updates. A more reliable way of keeping track of how far you’ve synced records (for each connection & sync combination) is to rely on record cursors. Each record comes with a synchronization cursor in_nango_metadata.cursor. Nango uses cursors internally to keep a chronological list of record modifications.
Each time you fetch records, you should store the cursor of the last record you fetched to remember how far you’ve synced (for each connection & sync combination).
The next time you fetch records, pass in the cursor of the last-fetched record to only receive records modified after that record:
- cURL (standard endpoint)
- Node SDK
- Receive a webhook notification from Nango
- Query your database for the cursor of the last-fetched record
- Fetch the modified records (passing the cursor)
- Store the modified records
- Store the last-fetched record cursor