How do I set up real-time Salesforce sync (via Flow Builder)?

Last updated: October 8, 2026

What this does (and doesn't do)

  • It triggers an immediate incremental sync of Customers + Contracts for your Salesforce connection, instead of waiting for the next scheduled poll.

  • It does not decide what counts as "Closed Won" or which records are eligible — that's still controlled entirely by your existing Pipeline Filters / Sync Filters configuration on the Salesforce settings page in Tabs. This trigger just says "something changed, go re-check now" — it fires on any Opportunity change, and your sync configuration still determines what actually syncs in.

  • It does not replace the 4-hour poll or the periodic watchdog sync — those keep running as backstops even once this is set up.

  • A burst of changes (e.g. bulk-editing several Opportunities) collapses into a single sync, so you don't need to worry about rate-limiting it yourself.

Prerequisites

  • Salesforce Setup access (to create External Credentials, Named Credentials, Permission Sets, and Flows).

  • A Tabs user with access to Developer Setup to create an API key.

  • Salesforce's own Flow Builder basics — if you're new to it, Salesforce's Build Flows with Flow Builder Trailhead trail is a good primer before starting.

Step 1 — Create a Tabs API key

  1. In Tabs, go to Developer Settings.

  2. Click Create API Key.

  3. Name it something identifiable, e.g. Salesforce Real-Time Sync.

  4. Set Access Level to Editor. This step has to call a POST endpoint, which requires Editor — Reporter (read-only) keys will get a 403.

  5. Copy the generated key immediately and store it securely (e.g. your password manager) — you won't be able to view it again but you can rotate it from the same page if you lose the key.

Step 2 — Set up authentication in Salesforce

Salesforce Flows call external APIs through a Named Credential, which in turn uses an External Credential to hold the actual secret. You only need to do this once per org.

  1. External Credential. Setup → External Credentials → New.

    • Label / Name: Tabs_API_External_Credential

    • Authentication Protocol: Custom

    • Under Custom Headers, add one:

      • Name: Authorization

      • Value: (paste the API key from Step 1 — no Bearer prefix, just the raw key)

  2. Named Credential. Setup → Named Credentials → New.

    • URL: https://integrators.prod.api.tabsplatform.com

    • Authentication: select the External Credential you just created.

  3. Principal + Permission Set (so the Flow is allowed to use this credential).

    • On the External Credential, go to Principals → New Principal and give it a name.

    • Setup → Permission Sets → New → create one (e.g. Tabs Real-Time Sync).

    • Inside it, go to External Credential Principal Access → Edit, and move your new Principal into Enabled External Credential Principals.

    • Under Manage Assignments, assign this Permission Set to yourself and anyone else who needs to run or debug the Flow.

Step 3 — Build the Flow

  1. Setup → Flows → New Flow → Record-Triggered Flow.

  2. Configure the trigger:

    • Object: Opportunity

    • Trigger: A record is created or updated

    • Condition Requirements: None — let it run on every change; Tabs' own sync filters decide what actually matters, so there's no condition to maintain here.

    • Optimize for: Actions and Related Records

    • When to run: After the record is saved, and set the Flow to run the callout on the asynchronous path (Salesforce requires HTTP callouts in record-triggered flows to run async).

  3. On the async path, add an Action → HTTP Callout:

    • Create a new HTTP Callout action, choose the Named Credential from Step 2.

    • Method: POST

    • Path: /v3/integrations/crm/sync

    • No request body or headers needed here — the Named Credential supplies auth, and the endpoint resolves everything else from the API key. You also don't need to map anything from $Record — this is a coarse "re-sync now" trigger, not a per-record payload.

    • Optionally store the response (status will be "triggered", "pooled", or "not_applicable" — see Troubleshooting below) if you want to branch on it, but this isn't required.

  4. Save and Activate the Flow.

Step 4 — Test it

  1. Open the Flow and click Debug.

  2. Pick an existing Opportunity to run the test against.

  3. Run it, then open the HTTP Callout step in the debug output and confirm you got back a 202 with a status field.

  4. In Tabs, check the Last synced timestamp on the Salesforce integration tile — it should update shortly after.

Troubleshooting

Symptom

Likely cause

Callout returns 401/403

API key is wrong, revoked, or was created with Reporter access instead of Editor.

Callout returns 202 with "status": "not_applicable"

This merchant doesn't have an active Salesforce connection yet — complete the standard How do I integrate with Salesforce? (v2) first.

Callout succeeds ("triggered" or "pooled") but the record never shows up in Tabs

The trigger only forces a re-sync — it doesn't make a record eligible. Check the merchant's Pipeline Filters / Sync Filters on the Salesforce settings page; the record may not match the configured stage(s) or filters.

Flow doesn't seem to fire at all

Confirm the Flow is Activated (not just saved as a draft), and check Setup → Flow debug/run history for errors.