Skip to main content

Documentation Index

Fetch the complete documentation index at: https://nango.dev/docs/llms.txt

Use this file to discover all available pages before exploring further.

Nango supports real-time syncs using webhook functions. You can rely entirely on webhooks or combine them with polling to ensure you never miss data.

What is a real-time sync

Real-time sync involves receiving webhooks from external APIs and processing them inside a sync function. By default, sync functions poll data at a set frequency, but they can also be configured to handle webhooks for real-time updates. When processed in a sync:
  • The webhook triggers the execution of a Nango sync script
  • The script extracts data from the webhook and optionally fetches additional data from the external API
  • The modified data is stored in the Nango cache
Whenever the cache is updated, Nango sends a sync completion webhook to notify your application of new data. This entire process happens in real-time.

Webhooks & periodic polling

Webhooks can fail due to external API outages or unordered events. Periodic polling ensures data consistency by reconciling any missed updates. If you use webhooks for real-time syncs, we recommend always combining them with a polling sync function.

Near real-time syncing

As an alternative to real-time syncing, consider near-real-time syncing by polling at a higher frequency, which is simpler. Sync functions can run as frequently as every 30 seconds. This is more resource intensive, but can be a good compromise if you are only syncing data for a handful of Connections.

Implement a real-time sync

Step 1 — Setup prerequisites

To create a real-time sync, you need:

Step 2 — Enable webhooks processing

To enable the real-time sync, define webhookSubscriptions and onWebhook in your sync function:
export default createSync({
  exec: async (nango) => {
        // Use for periodic polling.
  },

  webhookSubscriptions: ['contact.propertyChange'], // Webhook event type to listen to

  // Webhook handler
  onWebhook: async (nango, payload) => {
    if (payload.subscriptionType === 'contact.propertyChange') {
      const updatedObject = {
        id: payload.objectId,
        [payload.propertyName]: payload.propertyValue
      };

      // Use nango.batchSave() or nango.batchUpdate() to save/update records.
    }
  }
});
To check if a sync supports webhooks, navigate to the Integrations tab > select an integration > Endpoints sub-tab > check the function settings for webhook subscriptions.

Sync concurrency considerations

When a polling run and a webhook race to update the same record, the later write wins by default — which can clobber a fresher webhook update with stale polled data. To prevent that, set a merging strategy at the start of your function:
export default createSync({
  exec: async (nango) => {
    // Don't overwrite records that were modified after this batch was fetched
    await nango.setMergingStrategy({ strategy: 'ignore_if_modified_after' }, 'Contact');

    const contacts: Contact[] = [];
    await nango.batchSave(contacts, 'Contact');
  }
});
Two strategies are available:
  • override (default) — applies updates regardless of last modification time. May overwrite real-time webhook updates with older polled data.
  • ignore_if_modified_after — preserves records that were modified after the current batch was fetched. Recommended when you combine polling with webhooks.
Run batchSave / batchUpdate / batchDelete calls sequentially (not in parallel), and persist data promptly after fetching — concurrent batch operations can race against each other.