Initial sync overview and best practices
Last updated: January 9, 2026
Overview
Your customer just integrated their account into your product with Merge Link, what happens next? This article explains the initial sync - how it works, what to expect, and how to monitor it, so you can design a smooth product and user experience.
What happens right after a Linked Account is connected?
Right after a Linked Account is successfully connected, Merge begins the initial sync. During the initial sync, Merge retrieves and normalizes all data that exists in the third-party that adheres to your configured common model scopes and selective sync filters.
Merge stores data as soon as we get it from the third-party - meaning you'll start to see data returned from Merge's endpoints while the initial sync is still running.
How long does the initial sync take?
This initial sync can take anywhere from a few minutes to hours, depending on:
amount of data to be synced (eg. 100 employees v/s 10K employees in HRIS)
the third‑party’s API rate limits (some 3P have harsh rate limits like 60 queries per min)
the integration connected (3P API performance and response formats)
For typical accounts, you can usually expect the initial sync to complete in few hours, but large accounts could take over 24 hours.
Because of the significant variability, Merge can't commit to specific initial sync completion times with customers.
How do I know when the initial sync is complete?
There are three ways to monitor initial sync progress:
Poll
GET /sync-statusfor overall and per–common model sync progress
Subscribe to the
Linked account syncedwebhook to be notified when the initial sync completesSubscribe to the
Common model syncedwebhook to be notified when the initial sync completes for a common model. This is useful if your product depends on a specific common model.
The /sync-status endpoint
Sample response from GET /sync-status during the initial sync:
{
"results": [
{
"model_name": "Employee",
"model_id": "hris.Employee",
"last_sync_start": "2025-11-27T10:39:49.905833Z",
"next_sync_start": null,
"last_sync_result": null,
"last_sync_finished": null,
"status": "SYNCING",
"is_initial_sync": true
}
]
}Note:
is_initial_sync = trueidentifies initial syncstatusreflects current progress per common model (Employee model in above sample).status = DONEwould mean sync is complete. Sync status definitions
Recommended polling cadence:
Start at every 15–30 seconds for the first 2–3 minutes.
Back off to every 1–5 minutes
Stop polling once
status= DONEis reported.
Linked account synced webhook
The Linked account synced webhook can notify when the initial sync completes. You can configure this webhook on the Webhooks management console in your Merge dashboard. Learn more
What it does:
Fires once per Linked Account when the sync is complete across common models.
Payload includes
is_initial_sync = trueso you can distinguish this event from subsequent routine syncs.
Sample Linked account synced webhook payload for a ticketing category linked account:
{
"hook": {
"id": "2fa2b314-33c6-48d5-9eb8-683dc5754429",
"event": "LinkedAccount.sync_completed",
"target": "https://david-merge.requestcatcher.com/"
},
"linked_account": {
"id": "7841ee0a-5a1a-44db-bc7e-2912d8c17515",
"integration": "Azure DevOps",
"integration_slug": "azure-devops",
"category": "ticketing",
"end_user_origin_id": "TEST_AUM6QPMP",
"end_user_organization_name": "MERGE Test User AUM6QPMP",
"end_user_email_address": "[email protected]",
"status": "COMPLETE",
"webhook_listener_url": "https://api.merge.dev/api/integrations/webhook-listener/7hT4V5bFJBeu1fYD5Hy79rT_VCL6qBF7r1mJHGm5BRrNiJlwOEs6dg",
"is_duplicate": null,
"account_type": "TEST",
"completed_at": "2025-11-26T23:54:25.835905Z"
},
"data": {
"is_initial_sync": true,
"sync_status": {
"ticketing.TicketingAttachment": {
"last_sync_result": "DONE",
"last_sync_finished": "2025-11-27T00:16:19Z"
},
"ticketing.Ticket": {
"last_sync_result": "DONE",
"last_sync_finished": "2025-11-27T00:16:19Z"
},
"ticketing.Collection": {
"last_sync_result": "DONE",
"last_sync_finished": "2025-11-27T00:48:01Z"
},
"ticketing.Role": {
"last_sync_result": "DONE",
"last_sync_finished": "2025-11-27T00:22:49Z"
},
"ticketing.User": {
"last_sync_result": "DONE",
"last_sync_finished": "2025-11-27T00:22:49Z"
},
"ticketing.TicketingTeam": {
"last_sync_result": "DONE",
"last_sync_finished": "2025-11-27T00:22:49Z"
}
}
}
}Note:
is_initial_sync = trueidentifies initial sync.status = COMPLETEreflects all the common models in the Linked account have been synced.
Recommendation:
Do not rely solely on the webhook. If you miss it,
/sync-statuspolling will still show completion.For maximum reliability, combine both approaches: listen for the webhook for immediate updates, but poll
/sync-statusperiodically as a safety net.
Common model synced webhook
In most scenarios, your product wouldn't need the entire data to be synced but require certain common models to start letting your users to use the integration. For example - if there is a configuration step after the initial connection that only requires data from Groups common model, you wouldn't want to wait for all the common models to sync. Common model synced webhook would be useful in this case which can notify with sync status of each common model.
Sample Common model synced webhook payload for Candidates common model in ATS category:
{
"hook": {
"id": "e8affe31-8ae0-4b37-8c50-d86303094dc4",
"event": "Candidate.synced",
"target": "https://yoururl.com"
},
"linked_account": {
"id": "a3602c03-aba7-4d9d-a349-dbc338504092",
"integration": "Workday",
"integration_slug": "workday",
"category": "ats",
"end_user_origin_id": "",
"end_user_organization_name": "Test",
"end_user_email_address": "[email protected]",
"status": "COMPLETE",
"webhook_listener_url": "https://api.merge.dev/api/integrations/webhook-listener/IDS",
"is_duplicate": null,
"account_type": "PRODUCTION"
},
"data": {
"integration_name": "Ashby",
"integration_id": "ashby",
"synced_fields": ["first_name", "last_name"],
"sync_status": {
"model_name": "Candidate",
"model_id": "ats.Candidate",
"last_sync_start": "2023-09-27T20:50:47.490402Z",
"next_sync_start": "2023-09-11T23:24:52.242660Z",
"status": "COMPLETE",
"last_sync_result": "DONE",
"last_sync_finished": "2023-09-27T20:53:47.490402Z",
"is_initial_sync": true
}
}
}Note:
is_initial_sync = TRUEidentifies initial sync.model_nameidentifies the common modelstatus = COMPLETEreflects all data in the particular common model has been synced.
Recommendation:
Do not rely solely on the webhook. If you miss it,
/sync-statuspolling will still show completion.For maximum reliability, combine both approaches: listen for the webhook for immediate updates, but poll
/sync-statusperiodically as a safety net.
Make your product “ready” based on sync status
A tight integration between your product and the sync status is necessary to ensure a smooth user experience for your customer. No one would like to keep clicking on "Show Employees" to not find anyone or see an incomplete list. The following are some ideas on how you can use the intial sync status in your product to design a smooth experience for your users:
Show a “Syncing your data” banner until initial sync complete
Gate features that require all/some common models to be synced
Surface high-level error with GET /issues endpoint or issues webhook and provide “Retry” or “Contact support” guidance wherever necessary.
Common issues and fixes
status = Partially Synced
You could see the status for some common models is "Partially Synced" which would mean that one or more fields for the specific Common Model failed to sync. Learn how you can investigate the Partially synced status.
Sync failures
A sync could fail due to various reasons- issue with the 3rd party or with Merge servers. But in any case, Merge has a robust retry mechanism built which will automatically restart the sync.