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 APIs that don’t offer webhooks
- Combine polling and webhooks for a reliable, real-time stream of changes
Key facts
- Syncs run in Nango’s infrastructure, scoped to a connection
- You control the code: which data to fetch, how to transform it, and what the data model looks like
- All platform features are available: data validation, per-customer config, retries, and rate-limit handling
- Syncs support checkpoints to save progress, resume after failures, and fetch only changed data
- Synced records are encrypted at rest and in transit
- The minimum polling interval is 15 seconds
- All sync runs and API calls are logged in the Nango dashboard
Build a sync
Step 1 — Set up your integrations folder
If you don’t have anango-integrations folder yet, follow the functions setup guide.
Step 2 — Start dev mode
Step 3 — Create the sync file
Sync files live inside asyncs/ folder nested under the integration folder. For a sync that fetches Salesforce contacts:
salesforce-contacts.ts
index.ts:
index.ts
Step 4 — Implement your sync
Write your fetch-and-save logic inside theexec method. Here is a complete Salesforce contacts sync using incremental fetches with checkpoints:
salesforce-contacts.ts
SDK methods available in syncs
Step 5 — Test locally
Step 6 — Deploy
Use a sync from your backend
Receive Nango webhooks
Set up a webhook endpoint in your app and configure Nango to notify it. When a sync completes, Nango sends a webhook with the payload containingproviderConfigKey, connectionId, model, and modifiedAfter.
Fetch records
Use the Node SDK or REST API to fetch the latest records after receiving a webhook:- Node SDK
- cURL
_nango_metadata with last_action (ADDED, UPDATED, or DELETED), first_seen_at, last_modified_at, and a cursor for pagination.
Cursor-based pagination
Rather than relying solely on webhook timestamps (which can be missed), track thecursor from the last record you fetched. Pass it on subsequent requests to fetch only records modified after that point: