{"title":"Sync custom objects using flows","slug":"sync-custom-objects-using-flows","url":"https://support.storeconnect.com/articles/sync-custom-objects-using-flows","url_markdown":"https://support.storeconnect.com/articles/sync-custom-objects-using-flows.md","subtitle":null,"summary":"Use the StoreConnect Sync Record Changes invocable action in a Salesforce record-triggered flow to push create, update, and delete events to StoreConnect for objects that are not automatically synced.","type":"Help_Documentation","video_url":"","keywords":"sync custom objects, record-triggered flow, salesforce flow, invocable action, SyncRecordChangesInvocable, custom data mappings, storeconnect sync, change events, liquid custom objects, apex invocable, flow automation, pos sync","last_modified":"2026-08-21T07:12:35+0000","body_markdown":"StoreConnect automatically syncs its own objects (products, orders, accounts, and others) using change events. For custom objects (those you have defined yourself in Salesforce and mapped via [custom data mappings](liquid-custom-data-fields)) changes are not tracked automatically. You need to create a Salesforce record-triggered flow that calls the **StoreConnect: Sync Record Changes** invocable action whenever a record is created, updated, or deleted.\n\n## How it works\n\nThe `SyncRecordChangesInvocable` Apex class accepts a record and the type of change (Create, Update, or Delete) and sends the event through StoreConnect's standard change event pipeline.\n\n## Before you begin\n\nCheck both of these before building a flow. If either is missing, the flow runs but nothing reaches your store.\n\n- The object is configured in **Custom Data Mappings**. Changes to an unmapped object are never synced, whatever the flow does.\n- **StoreConnect Sync** is enabled on your org. If sync is disabled, the invocable action returns an error and no change event is generated.\n\nYou need two flows to cover the full record lifecycle: one for creates and updates, and a separate one for deletes. Salesforce cannot handle deletes in the same flow, because a delete flow must run before the record is removed.\n\n:::note\nThis invocable is designed for custom objects, which bypass per-record opt-in filtering. If you use it on a standard object where per-record opt-in filtering (`StoreConnect_Sync__c`) is enabled, pass `$Record` as **Entire Resource** so the opt-in field is available for evaluation.\n:::\n\n## Set up a flow for create and update events\n\n1. In Salesforce Setup, go to **Flows** and create a new **Record-Triggered Flow**.\n2. Select the custom object you want to sync (for example, `c_o__book__c`).\n3. Set the trigger to **A record is created or updated**.\n4. Set **Optimize the flow for** to **Actions and Related Records**.\n5. Set the flow to run **After the record is saved**.\n6. Add a **Decision** element. Create an outcome named **Create** with the condition formula `ISNEW()` = `True`. Leave the default outcome as **Update**.\n7. For the **Create** outcome, add an **Action** element and select **StoreConnect: Sync Record Changes**. Set the inputs:\n   - **Change Type**: `Create`\n   - **Current Record**: `{!$Record}` (Entire Resource)\n   - **Prior Record**: `{!$Record__Prior}` (Entire Resource)\n8. For the **Update** (default) outcome, add another **Action** element and select **StoreConnect: Sync Record Changes**. Set the inputs:\n   - **Change Type**: `Update`\n   - **Current Record**: `{!$Record}` (Entire Resource)\n   - **Prior Record**: `{!$Record__Prior}` (Entire Resource)\n9. Save and activate the flow.\n10. Create a record on the object, then query it in a Liquid template or check that it reaches the POS local database, to confirm the change event went through.\n\n## Set up a flow for delete events\n\n1. Create a new **Record-Triggered Flow** for the same object.\n2. Set the trigger to **A record is deleted**. Salesforce automatically sets **Optimize the flow for** to **Before the record is deleted**.\n3. Add an **Action** element and select **StoreConnect: Sync Record Changes**.\n4. Set the action inputs:\n   - **Change Type**: `Delete`\n   - **Current Record**: `{!$Record}` (Entire Resource)\n   - **Prior Record**: leave blank\n5. Save and activate the flow.\n6. Delete a test record and confirm it no longer appears on your store.\n\n## Action inputs\n\n| Input | Required | Description |\n|-------|----------|-------------|\n| **Change Type** | Yes | The type of change: `Create`, `Update`, or `Delete` (case-insensitive) |\n| **Current Record** | Yes | The record that triggered the flow. Use `{!$Record}` (Entire Resource). |\n| **Prior Record** | No | The record before the change. Use `{!$Record__Prior}` (Entire Resource). Required for updates; leave blank for delete. |\n\n## Action outputs\n\n| Output | Type | Description |\n|--------|------|-------------|\n| **Success** | Boolean | `true` if the change event was sent successfully |\n| **Error Message** | Text | Error message if the operation failed |\n\n## POS sync\n\nCustom objects that are also referenced in a **POS Layout** are synced to POS devices. When a change event is generated (either automatically or via this invocable action), the record is pushed to the POS local database on the next sync cycle. See [custom data mappings](liquid-custom-data-fields) for how to configure them, and [querying records in Liquid](liquid-query) for how to query custom objects in Liquid templates.\n\n## Governor limits\n\nThe flow invocable runs as the user who triggered the transaction. Note that although `SyncRecordChangesInvocable` is declared `with sharing`, the underlying sync handler executes in system mode, so sharing rules, CRUD, and FLS are not enforced on the sync operations. If you expect high-volume record changes, be aware of Salesforce governor limits on invocable actions in bulk operations. Use asynchronous flow execution where appropriate."}