{"id":42828,"date":"2025-11-14T11:10:34","date_gmt":"2025-11-14T05:40:34","guid":{"rendered":"https:\/\/www.inogic.com\/blog\/?p=42828"},"modified":"2025-11-14T11:10:34","modified_gmt":"2025-11-14T05:40:34","slug":"a-practical-guide-to-background-operations-and-callback-url-in-dynamics-365-part-2","status":"publish","type":"post","link":"https:\/\/www.inogic.com\/blog\/2025\/11\/a-practical-guide-to-background-operations-and-callback-url-in-dynamics-365-part-2\/","title":{"rendered":"A Practical Guide to Background Operations and Callback URL in Dynamics 365: Part 2"},"content":{"rendered":"<p><img decoding=\"async\" class=\"alignnone size-full wp-image-42834\" src=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/11\/A-Practical-Guide-to-Background-Operations-and-Callback-URL-in-Dynamics-365-Part-2.png\" alt=\"Operations and Callback URL in Dynamics 365\" width=\"2100\" height=\"1200\" srcset=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/11\/A-Practical-Guide-to-Background-Operations-and-Callback-URL-in-Dynamics-365-Part-2.png 2100w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/11\/A-Practical-Guide-to-Background-Operations-and-Callback-URL-in-Dynamics-365-Part-2-300x171.png 300w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/11\/A-Practical-Guide-to-Background-Operations-and-Callback-URL-in-Dynamics-365-Part-2-1024x585.png 1024w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/11\/A-Practical-Guide-to-Background-Operations-and-Callback-URL-in-Dynamics-365-Part-2-768x439.png 768w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/11\/A-Practical-Guide-to-Background-Operations-and-Callback-URL-in-Dynamics-365-Part-2-1536x878.png 1536w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/11\/A-Practical-Guide-to-Background-Operations-and-Callback-URL-in-Dynamics-365-Part-2-2048x1170.png 2048w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/11\/A-Practical-Guide-to-Background-Operations-and-Callback-URL-in-Dynamics-365-Part-2-660x377.png 660w\" sizes=\"(max-width: 2100px) 100vw, 2100px\" \/><\/p>\n<p>Handling large-scale data tasks in Dynamics 365 CRM can be challenging, especially when syncing thousands of records with external systems. Background Operations allow these resource-intensive tasks to run asynchronously, keeping the system responsive.<\/p>\n<p>In this article, we\u2019ll walk through the technical setup using a practical scenario: syncing thousands of records with an external system. You\u2019ll learn how to create a Background Operation and use a Callback URL to get notified or trigger other processes automatically once the job completes.<\/p>\n<p>For insights into synchronous vs asynchronous workflows and why Background Operations are essential for large data sets, refer to <a href=\"https:\/\/www.inogic.com\/blog\/2025\/10\/synchronous-vs-asynchronous-workflows-in-dynamics-365-crm-best-practices-for-large-data-sets-part-1\/\" target=\"_blank\" rel=\"noopener\">Part 1<\/a>.<\/p>\n<h2><strong>The Scenario: Syncing Records with External System<\/strong><\/h2>\n<p>Many organizations use both Dynamics 365 CRM and an external ERP system, requiring regular synchronization of all customer and order data. This includes not only the records themselves but also related data in the external system.<\/p>\n<p>Using a Background Operation allows this process to run asynchronously, without affecting other running processes. It also supports a Callback URL, which notifies the administrator automatically once the operation is completed, eliminating the need for manual monitoring.<\/p>\n<p>With a Background Operation, all syncing logic can be consolidated into a single request, allowing Dynamics 365 to run the large job in the background without disturbing users, while automatically informing the system or administrators when the task is finished.<\/p>\n<h2><strong>Technical Setup: Running Background Operations Asynchronously<\/strong><\/h2>\n<p>To implement this in Dynamics 365, a Custom API containing the sync logic must be created and triggered via the ExecuteBackgroundOperation request.<\/p>\n<h3><strong>Step 1: Create a Custom API<\/strong><\/h3>\n<p>Create a Custom API in Dynamics 365 called SyncRecordsToExternalSystem. Back it with a plugin, which handles:<\/p>\n<ul>\n<li>Querying Dynamics 365 records<\/li>\n<li>Sending data to the external system via API<\/li>\n<li>Handling responses and updating sync status flags<\/li>\n<\/ul>\n<p>This plugin runs in the background, removing timeout limitations and efficiently processing thousands of records.<\/p>\n<h3><strong>Step 2: Trigger the Background Operation<\/strong><\/h3>\n<p>Next, you need a way to <em>call<\/em> your new Custom API. The key is that instead of executing your Custom API directly, you wrap it in an ExecuteBackgroundOperation request.<\/p>\n<p>This tells Dynamics 365 to take your request (the asyncRequest) and run it as a background job, giving you back a BackgroundOperationId to track it.<\/p>\n<p>Here is a C# code snippet, similar to the one from Part 1, but this time we are calling our new Custom API. This code would typically run in another plugin (e.g., on a scheduled job or button click).<\/p>\n<pre class=\"lang:css gutter:true start:1\">public void Execute(IServiceProvider serviceProvider)\r\n{\r\n\r\n\/\/ Services\r\n\r\nIPluginExecutionContext context =\r\n\r\n(IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));\r\n\r\n\u00a0\r\n\r\nITracingService tracingService =\r\n\r\n(ITracingService)serviceProvider.GetService(typeof(ITracingService));\r\n\r\n\u00a0\r\n\r\nIOrganizationServiceFactory serviceFactory =\r\n\r\n(IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));\r\n\r\n\u00a0\r\n\r\nIOrganizationService service =\r\n\r\nserviceFactory.CreateOrganizationService(context.UserId);\r\n\r\n\u00a0\r\n\r\ntry\r\n\r\n{\r\n\r\ntracingService.Trace(\"Starting background sync operation...\");\r\n\r\n\u00a0\r\n\r\n\/\/ 1. Create the request for your Custom API that syncs records.\r\n\r\nvar asyncRequest = new OrganizationRequest(\"sample_SyncRecordsToExternalSystem\")\r\n\r\n{\r\n\r\nParameters =\r\n\r\n{\r\n\r\n\/\/ You can pass parameters to your logic,\r\n\r\n{\"EntityName\", \"account\"},\r\n\r\n{\"SyncMode\", \"Incremental\"},\r\n\r\n{\"ExternalSystemUrl\", \"https:\/\/api.erpsystem.com\/v1\/customers\"},\r\n\r\n{\"LastSyncDate\", DateTime.UtcNow.AddDays(-1)}\r\n\r\n}\r\n\r\n};\r\n\r\n\u00a0\r\n\r\n\/\/ 2. Create the request to execute your Custom API in the background.\r\n\r\nvar request = new OrganizationRequest(\"ExecuteBackgroundOperation\")\r\n\r\n{\r\n\r\nParameters =\r\n\r\n{\r\n\r\n{\"Request\", asyncRequest },\r\n\r\n\u00a0\r\n\r\n\/\/ 3. Request a callback. This is a Power Automate Flow URL.\r\n\r\n\/\/ This flow will be triggered when the job is done.\r\n\r\n{\"CallbackUri\", \"https:\/\/prod-123.westeurope.logic.azure.com\/workflows\/...\" }\r\n\r\n}\r\n\r\n};\r\n\r\n\u00a0\r\n\r\n\/\/ Execute the background operation request\r\n\r\nvar response = service.Execute(request);\r\n\r\n\u00a0\r\n\r\n\/\/ This ID lets you monitor the job in the \"Background Operations\" view\r\n\r\ntracingService.Trace($\"BackgroundOperationId: {response[\"BackgroundOperationId\"]}\");\r\n\r\ntracingService.Trace($\"Location: {response[\"Location\"]}\");\r\n\r\n}\r\n\r\ncatch (Exception ex)\r\n\r\n{\r\n\r\ntracingService.Trace($\"Exception: {ex.Message}\");\r\n\r\nthrow new InvalidPluginExecutionException(\"Sync background job failed.\", ex);\r\n\r\n}\r\n\r\n}<\/pre>\n<h2><strong>Step 3: Monitor the Background Operation<\/strong><\/h2>\n<p>You can monitor the progress under <strong>Advanced Settings \u2192 Settings \u2192 System Jobs \u2192 Background Operations, <\/strong>where you can view status, duration, parameters, and error logs easily.<\/p>\n<h2><strong>Step 4: Handle the Completion with the Callback URL<\/strong><\/h2>\n<p>This is where the magic happens. Your duplicate job might take 30 minutes, 4 hours, or even a whole day. You don&#8217;t want to sit and watch the &#8220;System Jobs&#8221; screen.<\/p>\n<p>The CallbackUrl you provided (e.g., the URL for a Power Automate HTTP-triggered flow) will be called automatically by Dynamics 365 the <em>moment<\/em> the operation finishes.<\/p>\n<p>Your Power Automate flow can then:<\/p>\n<ul>\n<li>Parse the response from the job.<\/li>\n<li>Check if it &#8216;Succeeded&#8217; or &#8216;Failed&#8217;.<\/li>\n<li>Send an email to the CRM Administrator with a summary (&#8220;Sync job complete. 2,456 records successfully synced to external system.&#8221;).<\/li>\n<li>Log the completion details for auditing.<\/li>\n<li>Update a sync status dashboard or field.<\/li>\n<li>Trigger error handling workflows if the sync failed.<\/li>\n<li>Schedule the next incremental sync.<\/li>\n<\/ul>\n<h3><strong>Conclusion<\/strong><\/h3>\n<p>Handling large-scale integration operations can be challenging, but Dynamics 365 provides the right tools to manage them efficiently. By combining Custom APIs with the ExecuteBackgroundOperation message, you can safely run heavy, resource-intensive tasks like external system synchronization without affecting users or system performance.<\/p>\n<p>With the CallbackUrl, Dynamics 365 automatically notifies you once the background job is completed. It can trigger actions like sending a summary email, logging results, updating dashboards, or scheduling the next sync, removing the need for manual monitoring.<\/p>\n<h2><strong>FAQs: Dynamics 365 Background Operations &amp; Callback URL<\/strong><\/h2>\n<p><strong>What are Background Operations in CRM?<\/strong><\/p>\n<p>Background Operations in Dynamics 365 CRM are asynchronous processes that run in the background, allowing long-running or resource-intensive tasks to execute without slowing down the system. They are ideal for bulk updates, data migration, or integration with external systems.<\/p>\n<p><strong>How does a Callback URL work in CRM?<\/strong><\/p>\n<p>A Callback URL is an endpoint (like a Power Automate flow, webhook, or API) that Dynamics 365 CRM automatically calls when a Background Operation completes. It enables automatic notifications, follow-up workflows, dashboard updates, or error handling.<\/p>\n<p><strong>Why are asynchronous workflows better for large data sets in Dynamics 365?<\/strong><\/p>\n<p>Asynchronous workflows, such as Background Operations, prevent system slowdowns or timeout errors when processing thousands of records. Unlike synchronous workflows, they allow users to continue working while large data operations run in the background.<\/p>\n<p><strong>Can Background Operations sync data with external systems?<\/strong><\/p>\n<p>Yes. Background Operations in Dynamics 365 CRM can execute custom APIs to synchronize records with external ERP or other third-party systems efficiently, ensuring data consistency and minimal disruption to users.<\/p>\n<p><strong>How can administrators monitor Background Operations?<\/strong><\/p>\n<p>Administrators can monitor Background Operations under Advanced Settings \u2192 System Jobs \u2192 Background Operations, checking status, parameters, duration, and error logs for each job.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Handling large-scale data tasks in Dynamics 365 CRM can be challenging, especially when syncing thousands of records with external systems. Background Operations allow these resource-intensive tasks to run asynchronously, keeping the system responsive. In this article, we\u2019ll walk through the technical setup using a practical scenario: syncing thousands of records with an external system. You\u2019ll\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.inogic.com\/blog\/2025\/11\/a-practical-guide-to-background-operations-and-callback-url-in-dynamics-365-part-2\/\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":15,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[16,2361],"tags":[3262],"class_list":["post-42828","post","type-post","status-publish","format-standard","hentry","category-dynamics-365","category-technical","tag-background-operations-and-callback-url-in-dynamics-365"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/posts\/42828","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/users\/15"}],"replies":[{"embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/comments?post=42828"}],"version-history":[{"count":0,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/posts\/42828\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/media?parent=42828"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/categories?post=42828"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/tags?post=42828"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}