Skip to main content

Salesforce

This connector captures data from Salesforce objects into Estuary collections. It uses Salesforce's Bulk API 2.0 and REST API.

This connector offers several unique advantages:

  • Efficient Backfills: Uses Salesforce's Bulk API 2.0 for initial data loads and backfills, enabling significantly faster data transfer rates while preserving REST API call limits. Note: Bulk API 2.0 has its own usage limits, and bulk jobs submitted by the connector count against those.

  • Formula Field Handling: The connector automatically refreshes formula fields on a configurable schedule (default: daily). This ensures your formula field data stays current without manual intervention, even though Salesforce doesn't track formula field changes in record modification timestamps.

  • Custom Field Support: Enhanced handling of custom fields with better type detection and mapping, ensuring all your custom Salesforce objects and fields are captured accurately.

Supported data resources

This connector captures Salesforce standard objects, custom objects, and field history for custom objects.

All available objects will appear after connecting to Salesforce.

info

To reduce how many API calls are needed to discover objects, the connector maintains an internal list of standard objects available for replication. If a standard object does not appear as an available binding after connecting to Salesforce, please contact us via Slack or email to request the standard object's addition to the connector's internal list.

Because most Salesforce accounts contain large volumes of data, you may only want to capture a subset of the available objects. There are several ways to control this:

Prerequisites

  • A Salesforce organization on the Enterprise tier, or with an equivalent API request allocation.

  • Salesforce user credentials. We recommend creating a dedicated read-only Salesforce user.

tip

If your Salesforce organization's login policy prevents signing in through login.salesforce.com, set the my_domain field to your full My Domain login host - for example, mycompany.my.salesforce.com or acme--uat.sandbox.my.salesforce.com. This applies to all authentication methods and is required when authenticating with Client Credentials. Leave it blank to use the standard login endpoint.

Authentication

There are three ways to authenticate with Salesforce when capturing data into Estuary.

OAuth

Sign in to Salesforce from the Estuary web app and grant access. Estuary handles the token exchange and refresh for you. This is the recommended method in the web app.

Username, Password, & Security Token

Sign in using a Salesforce user's username, password, and security token. This is a good fit if you cannot use OAuth, but will not work in organizations that enforce single sign-on (SSO) for interactive logins.

Client Credentials

Authenticate via Salesforce's OAuth 2.0 Client Credentials flow using a Salesforce External Client App (or a legacy Connected App). The connector exchanges the app's Consumer Key and Consumer Secret for an access token minted as the app's configured "Run As" user.

Use this option when your organization enforces SSO or other login restrictions that prevent the other authentication methods from working. The my_domain field is required since the Client Credentials flow must hit your org's My Domain token endpoint.

See Create an External Client App for setup steps.

Setup

Create a read-only Salesforce user

Creating a dedicated read-only Salesforce user is a simple way to specify which objects Estuary will capture. This is useful if you have a large amount of data in your Salesforce organization.

  1. While signed in as an administrator, create a new profile by cloning the standard Minimum Access profile.

  2. Edit the new profile's permissions. Grant it read access to all the standard and custom objects you'd like to capture with Estuary.

  3. Create a new user, applying the profile you just created. You'll use this user's email address and password to authenticate Salesforce in Estuary. If you're authenticating with username, password, and security token, you'll also need the user's security token. If you're authenticating with Client Credentials, you'll designate this user as the External Client App's "Run As" user.

Create an External Client App

Follow these steps to create an External Client App in Salesforce for use with Client Credentials authentication. You must be a Salesforce administrator to complete this setup.

Create the external client app
  1. In Salesforce, go to Setup.

  2. In the Quick Find box, enter App Manager, then click App Manager.

  3. In App Manager, click New External Client App.

  4. Enter the following details:

    • Label: a name for the app, for example, Estuary Integration.
    • Contact Email: your contact email address.
  5. Find the Distribution State field and set Distribution State to Local. This makes the app a local External Client App only usable in this org and not packageable.

  6. In the API (Enable OAuth Settings) section, select the Enable OAuth checkbox.

  7. Expand the OAuth Settings section.

  8. In the Callback URL field, enter https://dashboard.estuary.dev/oauth. The Client Credentials flow does not redirect to the specified callback URL, but Salesforce requires a value be provided.

  9. In the OAuth Scopes menu, select the Manage user data via APIs (api) scope.

  10. In the Field Enablement section, select the Enable Client Credentials Flow checkbox.

  11. Click Create. Your local external client app now appears in the External Client App Manager.

Modify app policy
  1. Open your app.

  2. Go to Policies and click Edit.

  3. In the OAuth Policies section, under OAuth Flows and External Client App Enhancements, make sure Enable Client Credentials Flow is checked.

  4. In the Security section, deselect all the checkboxes.

  5. Enter the integration user for the app. We recommend the dedicated Salesforce user you created in Create a read-only Salesforce user. The connector's access token will inherit this user's permissions, so the user must have read access to every object you intend to capture.

  6. In the App Authorization section, select Relax IP restrictions in the IP Relaxation dropdown menu.

  7. Save your changes.

Find client credentials
  1. Open your app.

  2. Click the Settings tab.

  3. Expand the OAuth Settings section.

  4. In the App Settings field, click Consumer Key and Secret.

  5. Remember the Consumer Key and Consumer Secret. You'll use these as the client_id and client_secret values when configuring the connector.

You must also provide your My Domain URL when configuring the connector with the Client Credentials flow - for example, mycompany.my.salesforce.com.

note

If your org does not yet expose the External Client App Manager, you can use a legacy Connected App instead. The connector works the same way with either app type - it just needs the Consumer Key and Consumer Secret. The Client Credentials Flow and integration user configuration steps are equivalent in the Connected App UI.

Configuration

You configure connectors either in the Estuary web app, or by directly editing the Data Flow specification file. See connectors to learn more about using connectors. The values and specification sample below provide configuration details specific to the Salesforce source connector.

Properties

Endpoint

PropertyTitleDescriptionTypeRequired/Default
/start_dateStart DateStart date in the format YYYY-MM-DD. Data added on and after this date will be captured. If left blank, the start date will be set to Salesforce's founding date.string1999-02-03T00:00:00Z
/my_domainMy DomainYour Salesforce My Domain login host. Enter the full host ending in .my.salesforce.com to login with your My Domain host. e.g. mycompany.my.salesforce.com, acme--uat.sandbox.my.salesforce.com. Leave blank to log in via the standard login/test endpoint. Required when authenticating with Client Credentials.string""
/is_sandboxSandboxWhether you're using a Salesforce Sandbox.booleanfalse
/credentialsAuthenticationCredentials for the chosen authentication method. See the per-method credential properties below.objectRequired
/advanced/window_sizeWindow sizeThe date window size in days to use when querying the Salesforce APIs.integer18250
Credentials

OAuth:

PropertyTitleDescriptionTypeRequired/Default
/credentials/credentials_titleAuthentication MethodMust be OAuth Credentials.stringRequired
/credentials/client_idOAuth Client IDThe OAuth app's client ID.stringRequired
/credentials/client_secretOAuth Client SecretThe OAuth app's client secret.stringRequired
/credentials/refresh_tokenOAuth Refresh TokenThe refresh token received from the OAuth app.stringRequired
/credentials/instance_urlInstance URLThe URL for the instance of your Salesforce organization.stringRequired

Username, Password, & Security Token:

PropertyTitleDescriptionTypeRequired/Default
/credentials/credentials_titleAuthentication MethodMust be Username, Password, & Security Token.stringRequired
/credentials/usernameUsernameThe user's username.stringRequired
/credentials/passwordPasswordThe user's password.stringRequired
/credentials/security_tokenSecurity TokenThe user's security token.stringRequired

Client Credentials:

PropertyTitleDescriptionTypeRequired/Default
/credentials/credentials_titleAuthentication MethodMust be Client Credentials.stringRequired
/credentials/client_idConsumer KeyThe Consumer Key of the External Client App or Connected App.stringRequired
/credentials/client_secretConsumer SecretThe Consumer Secret of the External Client App or Connected App.stringRequired

Bindings

PropertyTitleDescriptionTypeRequired/Default
/nameNameName of the data resource.stringRequired
/intervalIntervalInterval between data syncsstringPT5M
/scheduleFormula Field Refresh ScheduleThe schedule for refreshing this binding's formula fields. Accepts a cron expression. For example, a schedule of 55 23 * * * means the binding will refresh formula fields at 23:55 UTC every day. If left empty, the binding will not refresh formula fields.string55 23 * * *

Sample

This sample specification reflects the Client Credentials authentication method.

captures:
${PREFIX}/${CAPTURE_NAME}:
endpoint:
connector:
image: ghcr.io/estuary/source-salesforce-native:v1
config:
credentials:
credentials_title: "Client Credentials"
client_id: <secret>
client_secret: <secret>
my_domain: mycompany.my.salesforce.com
is_sandbox: false
start_date: "2025-03-19T12:00:00Z"
advanced:
window_size: 18250
bindings:
- resource:
name: Account
interval: PT5M
schedule: "55 23 * * *"
target: ${PREFIX}/Account
{...}

Formula Fields

Salesforce objects can contain formula fields, fields whose values are calculated at query time. Since formula fields do not maintain state in Salesforce, formula fields updates do not update the associated record's last modified timestamp. The Salesforce connector uses the last modified timestamp to incrementally detect changes, and since formula field updates don't update the last modified timestamp, formula fields updates are not incrementally captured by the connector.

To address this challenge, the Salesforce connector is able to refresh the values of formula fields on a schedule after the initial backfill completes. This is controlled at a binding level by the cron expression in the schedule property. When a scheduled formula field refresh occurs, the connector fetches every record's current formula field values and merges them into the associated collection with a top-level merge reduction strategy.

Note that formula field refreshes emit partial documents containing only the record's key and formula field values. By default, these are combined with previously captured complete documents, and this works well for standard updates materializations. However, delta updates materializations do not fully reduce documents, so partial documents from formula field refreshes are materialized as-is with all non-formula fields as null.

Troubleshooting

Field Permissions

If a field is not present in documents captured by the connector but the field exists on the object in Salesforce, confirm that the field is visible for the configured user in Salesforce's field permissions. If the Salesforce account used when authenticating the connector does not have permission to view a field, Salesforce prevents the connector from replicating that field.

To check field permissions in Salesforce:

  1. Go to Setup > Object Manager
  2. Click the object for the specific field (Account, Contact, Opportunity, etc.)
  3. Click "Fields & Relationships" and select the field that is not being captured.
  4. Click "Set Field-Level Security" and make sure the profile of the account used for authentication has visibility for the field.
  5. If the associate profile does not have visibility, update it and click "Save".