Skip to main content

Salesforce Source

Configure Salesforce as a source for API-accessible standard and custom objects. Supaflow uses scheduled cursor-based reads; it does not subscribe to Salesforce Change Data Capture events.

For capabilities and use cases, see the Salesforce connector page. For the Snowflake-specific workflow, see Salesforce to Snowflake.

Prerequisites

Before you begin, ensure you have:

  • An active Salesforce org with API access enabled
  • A Salesforce user with API access and read permission for the required objects and fields
  • A Salesforce account configured for Supaflow
  • For OAuth, permission to approve the Supaflow Connected App
  • For Basic authentication, the user's Salesforce security token when the org requires one

If your Salesforce org restricts source IPs, add the Supaflow hosted-agent IP to Salesforce Network Access:

18.214.240.61

To add: Setup → Security → Network Access → New

OAuth: Grant User Permission (Required)

When the Supaflow Connected App is not installed in the organization, the connecting user needs Approve Uninstalled Connected Apps. Assign the permission through a permission set or the user's profile.

Steps to enable permission:

  1. Create or edit a permission set: Navigate to Setup → Search for and select Permission Sets → Click New or select an existing one
  2. Add the permission: Select System Permissions → Click Edit → Find and select "Approve Uninstalled Connected Apps" → Click Save
  3. Assign to user: Go to the user's profile → In Permission Set Assignments, click Edit Assignments → Add the permission set → Click Save

Learn more in Salesforce documentation →

Basic Authentication (Security Token Required)

When the org requires a security token for Basic authentication:

  1. Go to your Personal Settings in Salesforce
  2. Click on "Reset My Security Token" under Personal Information
  3. Check your email for the new security token

Learn more about security tokens →

Supported Objects

Supaflow discovers objects directly from the connected Salesforce org. Standard objects such as Account, Contact, Lead, Opportunity, Case, Task, and Event can appear alongside org-specific custom objects when the connected user can read them.

An object is eligible for source sync only when Salesforce marks it queryable and exposes a filterable incremental timestamp. Supaflow prefers SystemModstamp, then LastModifiedDate, then CreatedDate. When Salesforce returns an object but none of those fields is usable, Supaflow skips it with a reason instead of presenting it as safely incremental.

Objects Salesforce does not expose to the connected user may not appear in discovery. Returned deprecated or hidden objects, Big Objects, external objects, and other restricted object types are skipped when the connector can identify them.

Three optional Supaflow-managed picklist metadata tables are available for selection: SUPAFLOW_PICKLIST_FIELD, SUPAFLOW_PICKLIST_FIELD_VALUE, and SUPAFLOW_DEPENDENT_PICKLIST_RELATION. See Picklist values and labels.

Sync Behavior

The initial run reads the selected object's available history. Later scheduled runs resume from the saved timestamp position, with an optional lookback overlap for late-arriving updates. This is cursor-based incremental ingestion, not Salesforce CDC.

The connector uses Salesforce bulk extraction by default for supported large reads. When an object or query is not supported by that path, Supaflow can use the synchronous Salesforce API instead.

The source read includes active, archived, and recycle-bin records that Salesforce still exposes. The Salesforce deletion indicator is mapped for downstream handling. Once Salesforce permanently purges a record, the connector has no hard-delete event or source row to read.

Configuration

Step 1: Choose Authentication Method

Authentication Type*

How Supaflow connects to Salesforce.

Options:

  • oauth — Browser-based authorization with automatic token refresh
  • basic — Username and password, with a security token when required

Default: oauth


Salesforce Domain*

The login host for the Salesforce org. Use the production login host, the sandbox login host, or your organization's custom My Domain.

Authorize*

Click Authorize, sign in to the selected org, and approve the requested access. Supaflow manages the resulting OAuth tokens.


Option B: Basic Authentication

Username*

Active Salesforce username with API access.

Password*

Password for the Salesforce user. Do not append the security token.

Security Token

Security token for the Salesforce user. This is required when the org does not trust the Supaflow agent's source IP.
Stored encrypted

Salesforce Domain*

The production, sandbox, or custom My Domain login host for the Salesforce org.


Step 2: Advanced Settings (Optional)

API Version

Leave the default unless a Salesforce compatibility requirement calls for a specific supported API version.

Use Bulk API

Use Salesforce bulk extraction for supported large reads. When disabled, or when a read is not supported by the bulk path, the connector uses the synchronous API.
Default: true

Batch Size

Maximum read batch size. Keep the default unless a measured Salesforce or network constraint requires a smaller batch.

Schema Refresh Interval

How often Supaflow rediscovers Salesforce objects and fields.
Options:

  • 0 — Refresh before every pipeline execution
  • -1 — Disable automatic schema refresh
  • Positive value — Refresh interval in minutes

Default: 30

Lookback Time

Number of seconds to overlap the previous incremental window. Use an overlap when Salesforce updates can become queryable after the saved position.
Default: 0


Step 3: Test & Save

After configuring the connection, click Test & Save. Supaflow verifies the credential and discovers the Salesforce schema available to it.

Picklist values and labels

If you have ever compared a synced record against the Salesforce UI and seen different text in the same field, you have met the difference between a picklist value and its label. Every picklist entry in Salesforce has two parts:

  • The API value is what Salesforce stores on the record and what integrations and warehouse models commonly use for joins and logic.
  • The label is what users see in the Salesforce UI. Admins can rename labels at any time without touching the underlying data.

Supaflow syncs the API value on the source record. If an admin renames a label without changing its API value, existing warehouse rows keep the stored value. This can make the warehouse show Pending where the Salesforce UI shows Not Compared, or US where the UI shows United States.

To let you report with the labels your users recognize, the connector provides three system tables alongside your Salesforce objects. They appear in the schema selection like any other table -- select them and they sync into your destination.

SUPAFLOW_PICKLIST_FIELD

One row per picklist, multi-select picklist, or combobox field in your org. Use it to discover which fields have picklists and how they relate.

ColumnDescription
picklist_field_idKey, <object>.<field>, for example Account.Industry
object_nameObject API name
field_nameField API name
field_labelField display label
field_typepicklist, multipicklist, or combobox
restrictedWhether the picklist is restricted to defined values
dependentWhether the picklist depends on a controlling field
controller_nameControlling field API name (null unless dependent)

SUPAFLOW_PICKLIST_FIELD_VALUE

One row per picklist entry -- this is the value-to-label dictionary you join against.

ColumnDescription
picklist_field_idKey part, joins to SUPAFLOW_PICKLIST_FIELD
valueStored/API value, for example Pending
labelDisplay label, for example Not Compared
value_indexPosition in Salesforce's metadata ordering
activeWhether the value is currently active
default_valueWhether this is the field's default value
valid_for_base64Raw dependent-picklist bitset (advanced; not decoded)

Querying labels

Join your object table to SUPAFLOW_PICKLIST_FIELD_VALUE once per picklist column you want to translate. The join key is the field's picklist_field_id (<Object>.<FieldName>) plus the stored value:

select
a.name,
a.industry as industry_value,
ind.label as industry_label,
a.billingcountrycode as country_value,
cc.label as country_label,
a.cleanstatus as cleanstatus_value,
cs.label as cleanstatus_label
from salesforce.account a
left join salesforce.supaflow_picklist_field_value ind
on ind.picklist_field_id = 'Account.Industry'
and ind.value = a.industry
left join salesforce.supaflow_picklist_field_value cc
on cc.picklist_field_id = 'Account.BillingCountryCode'
and cc.value = a.billingcountrycode
left join salesforce.supaflow_picklist_field_value cs
on cs.picklist_field_id = 'Account.CleanStatus'
and cs.value = a.cleanstatus;

Example result:

NAMEINDUSTRY_VALUEINDUSTRY_LABELCOUNTRY_VALUECOUNTRY_LABELCLEANSTATUS_VALUECLEANSTATUS_LABEL
Edge CommunicationsElectronicsElectronicsUSUnited StatesPendingNot Compared
GenePointBiotechnologyBiotechnologyUSUnited StatesPendingNot Compared

For many standard picklists (like Industry here) the label equals the value, and the join passes the value through unchanged. Where they differ -- country codes, status fields, or any picklist an admin has relabeled -- the join surfaces the label your users expect.

Use a left join rather than an inner join so records keep flowing even if a value has no matching picklist entry (for example, a value that was deleted in Salesforce after the record was created).

Dependent picklists

Salesforce lets one picklist control another: a controlling field (for example Country) decides which values of a dependent field (for example State) are available. In Salesforce metadata this relationship is stored as a compact bitset that is not practical to query directly, so the connector decodes it into a third system table:

SUPAFLOW_DEPENDENT_PICKLIST_RELATION

One row per valid combination of a dependent value and the controlling value that allows it.

ColumnDescription
dependent_picklist_field_idThe dependent field, <object>.<field>
dependent_valueDependent picklist API value
controller_field_idThe controlling field, <object>.<field>
controller_valueControlling API value this dependent value is valid for

A dependent value that is valid for several controlling values gets one row per combination.

Example 1 -- list the allowed values per controlling value, with display labels. Join the relation to SUPAFLOW_PICKLIST_FIELD_VALUE to bring in labels and active status -- useful for building cascading filters in BI tools:

select
r.controller_value,
r.dependent_value,
pv.label as dependent_label,
pv.active
from salesforce.supaflow_dependent_picklist_relation r
left join salesforce.supaflow_picklist_field_value pv
on pv.picklist_field_id = r.dependent_picklist_field_id
and pv.value = r.dependent_value
order by r.controller_value, r.dependent_value;
CONTROLLER_VALUEDEPENDENT_VALUEDEPENDENT_LABELACTIVE
FoodEggsEggsTrue
FoodMilkMilkTrue
ServiceConsultingConsultingTrue

Example 2 -- flag records whose dependent value is not legal for their controlling value. Dependency rules are only enforced in the Salesforce UI; records created by integrations or loaded before a rule changed can hold combinations that are no longer valid. This anti-join surfaces them:

select a.id, a.country__c, a.state__c
from salesforce.account a
where a.state__c is not null
and a.country__c is not null
and not exists (
select 1
from salesforce.supaflow_dependent_picklist_relation r
where r.dependent_picklist_field_id = 'Account.State__c'
and r.dependent_value = a.state__c
and r.controller_value = a.country__c
);

One limitation: dependencies controlled by a checkbox (rather than another picklist) are not included in this table. Those fields still appear in SUPAFLOW_PICKLIST_FIELD with dependent set and the checkbox named in controller_name.

How fresh is the picklist data?

These tables are built from Salesforce metadata rather than record data. Their destination freshness depends on how often the selected metadata tables run a full refresh. Two details to be aware of:

  • Renamed labels and activation changes update on the next full refresh of the selected metadata tables.
  • Values deleted in Salesforce can linger in the destination until you re-sync the table with a reset, since Salesforce metadata carries no deletion marker.

Troubleshooting

OAuth authorization fails

  1. Confirm the connecting user has Approve Uninstalled Connected Apps when the Supaflow app is not installed in the org.
  2. Confirm the org allows the Connected App and the user has API access.
  3. Confirm Salesforce Domain points to the correct production, sandbox, or custom My Domain host.
  4. Retry authorization in a browser window that allows the Salesforce sign-in and redirect.

Basic authentication is rejected

  1. Confirm the username, password, and current security token are entered in separate fields.
  2. Confirm the user has API access and is active in the selected org.
  3. Confirm Salesforce Domain points to the correct org.
  4. If the org restricts source IPs, add the Supaflow hosted-agent IP to Salesforce Network Access.

Salesforce reports an API-limit error

  1. Review API usage in Salesforce Setup.
  2. Avoid overlapping pipelines that use the same org and user.
  3. Narrow the selected object and field scope where possible.
  4. Schedule large reads during a quieter period. Supaflow retries transient throttling, but an exhausted account limit must recover before the source can continue.

An object or field does not appear

  1. Confirm the connected user has object- and field-level read access.
  2. Confirm Salesforce marks the object queryable and the field visible to the API.
  3. Set Schema Refresh Interval to 0, then test and save the source again.
  4. Review the object's reason in schema selection or Job Details. Deprecated, hidden, Big, external, restricted, and cursorless objects can be skipped intentionally.

A Bulk API read fails

  1. Review Job Details for the affected object and Salesforce error.
  2. Confirm the Salesforce user can use the required API features.
  3. Reduce Batch Size if the object is unusually wide or the connection is unstable.
  4. Disable Use Bulk API for that source when the object must use the synchronous Salesforce API path.

A deleted record is missing

The connector can return a record only while Salesforce still exposes it through the all-record query path. If Salesforce has permanently purged the record, it cannot be emitted as a hard-delete event. Use the deletion indicator for retained records and define a separate reconciliation policy when permanent-delete parity is required.


Support

Need help? Contact us at support@supa-flow.io