LoadersSalesforce

Salesforce Loader

The Salesforce loader pulls data from your Salesforce org into your data warehouse using the Salesforce REST API. It supports incremental sync via Salesforce’s SystemModstamp field and handles both standard and custom objects.

Prerequisites

  • A Salesforce org (Production, Sandbox, or Developer Edition)
  • A Salesforce user with API access (the “API Enabled” permission must be active)
  • A connected Warehouse (target warehouse) with write permissions on the target schema

Authentication

The Salesforce loader uses OAuth 2.0 for authentication.

OAuth 2.0 Setup

  1. In SignalSmith, click Add Loader and select Salesforce
  2. Click Connect with Salesforce
  3. You’ll be redirected to the Salesforce login page
  4. Log in with your Salesforce credentials and click Allow to grant SignalSmith access
  5. You’ll be redirected back to SignalSmith with the connection established

SignalSmith requests the following OAuth scopes:

ScopePurpose
apiAccess Salesforce REST API
refresh_tokenMaintain a long-lived connection without re-authenticating
offline_accessRefresh tokens when the access token expires

SignalSmith automatically refreshes the access token before it expires. If the refresh token is revoked (e.g., user password reset, admin action), you’ll need to re-authenticate.

Sandbox Connections

To connect to a Salesforce Sandbox, toggle the Sandbox option before clicking “Connect.” This directs the OAuth flow to test.salesforce.com instead of login.salesforce.com.

Available Objects

The Salesforce loader can sync any standard or custom object accessible to the authenticated user. The most commonly used objects are:

ObjectAPI NameDescriptionDefault Sync Mode
ContactContactIndividual people associated with accountsIncremental
LeadLeadProspective customers not yet associated with an accountIncremental
AccountAccountCompanies or organizationsIncremental
OpportunityOpportunitySales deals with stages, amounts, and close datesIncremental
CampaignCampaignMarketing campaigns and their metadataIncremental
Campaign MemberCampaignMemberJunction object linking contacts/leads to campaignsIncremental
TaskTaskActivities like calls, emails, and to-dosIncremental
EventEventCalendar events and meetingsIncremental
UserUserSalesforce users (reps, admins)Incremental
CaseCaseSupport casesIncremental
Custom ObjectsMyObject__cAny custom object with API accessIncremental

Custom Objects

Custom objects are automatically discovered during the connection setup. They appear in the object list alongside standard objects, identified by the __c suffix. Custom fields on standard objects are also included in the extracted schema.

Configuration

SettingDescriptionDefault
EnvironmentProduction or SandboxProduction
API VersionSalesforce REST API version to useLatest stable (e.g., v59.0)
ObjectsList of objects to sync— (you choose during setup)
Sync ModeFull Refresh or Incremental (per object)Incremental
Cursor FieldField used for incremental syncSystemModstamp
Primary KeyField(s) that uniquely identify a recordId
Target SchemaWarehouse schema for Salesforce tables— (required)
Table PrefixOptional prefix for table namessf_
ScheduleSync frequencyHourly

Scheduling Notes

  • Incremental sync uses SystemModstamp, which Salesforce updates whenever any field on a record changes, including system-level changes. This ensures no modifications are missed.
  • Rate limits: Salesforce enforces API call limits based on your edition and license count. A standard Enterprise edition provides approximately 100,000 API calls per 24-hour period. Each loader run consumes API calls proportional to the number of objects and records extracted.
  • Bulk API: For objects with more than 10,000 records, SignalSmith automatically uses the Salesforce Bulk API 2.0 to extract data more efficiently and consume fewer API calls.
  • Deleted records: SignalSmith queries the Salesforce queryAll endpoint to capture soft-deleted records (those in the Recycle Bin). These records are marked with IsDeleted = true in your warehouse.

Schema Mapping

Salesforce field types are mapped to warehouse-compatible types:

Salesforce TypeWarehouse TypeNotes
idVARCHAR(18)18-character Salesforce ID
string, textareaVARCHARLength from Salesforce field metadata
booleanBOOLEAN
intINTEGER
double, currency, percentDOUBLE / FLOAT
dateDATE
datetimeTIMESTAMPUTC normalized
referenceVARCHAR(18)Lookup/master-detail relationship ID
picklist, multipicklistVARCHARPicklist values as strings
email, phone, urlVARCHAR

Troubleshooting

IssueSolution
”INVALID_SESSION_ID” or token expiredRe-authenticate by clicking “Reconnect” on the loader detail page
”REQUEST_LIMIT_EXCEEDED”You’ve hit Salesforce’s daily API limit. Reduce sync frequency or number of objects, or upgrade your Salesforce edition
Missing custom objectsEnsure the authenticated user’s profile has read access to the custom object and that it has API access enabled
”QUERY_TOO_COMPLICATED”Salesforce rejected a complex query. Contact SignalSmith support — this may require object-specific configuration
Sandbox data not appearingVerify you toggled “Sandbox” before authenticating. Sandbox and Production are separate connections
Records missing after incremental syncCheck if records were hard-deleted (permanently removed from Recycle Bin). Hard-deleted records are not captured by incremental sync
Slow initial syncLarge orgs with millions of records may take several hours for the initial backfill. Subsequent incremental syncs will be much faster

Example API Configuration

curl -X POST https://your-workspace.signalsmith.dev/api/v1/loaders \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Salesforce Production",
    "connector": "salesforce",
    "auth": {
      "type": "oauth2",
      "access_token": "00D...",
      "refresh_token": "5Aep...",
      "instance_url": "https://mycompany.my.salesforce.com"
    },
    "objects": [
      {
        "name": "Contact",
        "sync_mode": "incremental",
        "cursor_field": "SystemModstamp",
        "primary_key": ["Id"]
      },
      {
        "name": "Lead",
        "sync_mode": "incremental",
        "cursor_field": "SystemModstamp",
        "primary_key": ["Id"]
      },
      {
        "name": "Account",
        "sync_mode": "incremental",
        "cursor_field": "SystemModstamp",
        "primary_key": ["Id"]
      },
      {
        "name": "Opportunity",
        "sync_mode": "incremental",
        "cursor_field": "SystemModstamp",
        "primary_key": ["Id"]
      }
    ],
    "target": {
      "source_id": "src_abc123",
      "schema": "SALESFORCE_RAW",
      "table_prefix": "sf_"
    },
    "schedule": {
      "interval": "hourly"
    }
  }'

Next Steps