Dander Salesforce Connector
First-party Salesforce Bulk API 2.0 connector plugin for Dander.
Alpha: pin both Dander and this plugin exactly. Scheduled ingestion is read-only. Explicit connector write commands are experimental and mutate Salesforce. Contact Email and Phone are enabled by default and are personal data; deploy them only into an approved project.
What it reads
The four endpoints stream bounded CSV result pages and commit separate SystemModstamp watermarks:
| Endpoint | Raw relation | Salesforce operation | Deletion state |
|---|---|---|---|
accounts |
raw.salesforce_accounts |
queryAll |
IsDeleted |
contacts |
raw.salesforce_contacts |
queryAll |
IsDeleted |
opportunities |
raw.salesforce_opportunities |
queryAll |
IsDeleted |
users |
raw.salesforce_users |
query |
IsActive |
Inclusive SystemModstamp >= cursor filters deliberately reread the cursor boundary. Dander's
SCD1 writer makes that replay duplicate-free. Soft-deleted CRM records remain as tombstones rather
than being physically deleted from BigQuery, and inactive owners remain available for historical
joins. Salesforce records that have already been hard-deleted or purged cannot be recovered by
this connector.
Salesforce's deleted-record feed retains at most 15 days. Dander rejects a wider or non-forward window instead of silently presenting it as complete.
Dander compatibility
This release supports dander-platform>=0.6.0rc1,<0.10 through plugin API v1. Pin both
packages exactly in deployments. CI installs the built connector wheel into a fresh environment
and runs the complete connector test suite with Dander 0.6.0rc1, 0.7.1, and 0.9.0rc20.
The normal development lock uses stable Dander 0.7.1; release candidates must be selected
explicitly. These checks use synthetic data and do not certify every Salesforce
configuration.
Install and configure
Declare the exact stable version in dander.yaml:
version: 1
plugins:
salesforce:
distribution: dander-connector-salesforce
version: 0.3.2
pipelines:
salesforce_crm:
source: salesforce
models: []
build_models: false
schedule: "0 7 * * *"
time_zone: America/New_York
paused: true
secrets:
SALESFORCE_EXTERNAL_CLIENT_APP_ID: salesforce-client-id
SALESFORCE_EXTERNAL_CLIENT_APP_PRIVATE_KEY: salesforce-private-key
Existing installations may keep their current pipeline ID to avoid replacing Cloud Run and Scheduler resources. Install the manifest's exact package pin:
dander plugins install
Copy salesforce_jwt.example.yaml
into connectors/salesforce.yaml. Replace only the public org URL, OAuth subject, and login-domain
settings. Store the External Client App ID and RSA private key in Dander's secret store; never put
credential values in YAML.
The Salesforce integration user needs API access plus read access to each selected object and
field. Custom fields are opt-in: add each field to both the endpoint's SOQL SELECT and its
raw_schema. This explicit declaration prevents undeclared source drift from entering BigQuery.
Runtime contract
- Engine:
salesforce_bulk2 - Authentication: Dander core's cloud-neutral
oauth2_jwtstrategy - API: Salesforce Bulk API 2.0 Query
- Publication: Dander's idempotent SCD1 writer
- Memory: CSV pages are streamed and bounded by Salesforce
maxRecords - Replay: inclusive server-side
SystemModstampfilters - Optional reads: exact aggregate count and one-record lookup by validated Salesforce
Id - Optional deleted feed: Accounts, Contacts, and Opportunities within Salesforce's 15-day window
- Explicit writes: create, update, and delete by validated Salesforce
Id - Connection check: authenticated REST
/limitsprobe that returns no business records
With a supported Dander version, inspect and check an installed pipeline without ingestion:
dander connector inspect salesforce_crm
dander connector check salesforce_crm
Dander retains its deprecated built-in Salesforce fallback for compatibility. An explicitly pinned plugin takes precedence.
Experimental write-back
Write-back is never invoked by dander run. It requires the separate connector command, local JSON
input files, and an explicit --confirm-write acknowledgement:
dander connector write salesforce_crm accounts create --record new-account.json --confirm-write
dander connector write salesforce_crm accounts update --identity account-id.json \
--changes account-changes.json --confirm-write
dander connector write salesforce_crm accounts delete --identity account-id.json --confirm-write
Upsert is disabled by default. To enable it for a custom endpoint, declare one Salesforce External
ID field as the endpoint's sole primary key, include it in both the SOQL selection and raw_schema,
and name it in request_body:
primary_key: [Dander_External_ID__c]
request_body:
operation: queryAll
query: SELECT Dander_External_ID__c, Name FROM Account
upsert_external_id_field: Dander_External_ID__c
raw_schema:
- {name: Dander_External_ID__c, type: STRING, mode: REQUIRED}
- {name: Name, type: STRING, mode: REQUIRED}
Before each upsert, the connector checks Salesforce metadata and refuses fields that are not marked both External ID and Unique. External-ID values are encoded as one URL path segment. The local control field is not sent in Bulk query job bodies.
These write capabilities use the same Dander compatibility range as the package. Provider writes remain explicit CLI operations and are not invoked by normal scheduled ingestion.
Development
uv sync --extra dev
uv run ruff check .
uv run mypy src tests
uv run pytest
Apache-2.0 licensed.
Metadata
Release files for dander-connector-salesforce 0.3.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dander_connector_salesforce-0.3.2.tar.gz | 197.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dander_connector_salesforce-0.3.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 216.8 kB
Release files / dander_connector_salesforce-0.3.2.tar.gz
| Download URL | dander_connector_salesforce-0.3.2.tar.gz |
|---|---|
| Size | 197.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1c2cbb21abd09d898fed16b599174cd6b78d8e1e400e0ad6746301276a950100
|
|
BLAKE2b-256 checksum How to use checksums |
dfb5c49c0368fda653e6983d3d10f5feabcc8b4904f331dafd73fbee50cf8b8c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.
Transparency logRelease files / dander_connector_salesforce-0.3.2-py3-none-any.whl
| Download URL | dander_connector_salesforce-0.3.2-py3-none-any.whl |
|---|---|
| Size | 19.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1b144103bceb47c9df5b5c9a7f7a8b02c9f7b813be3f9f71f50f03bfc88ca696
|
|
BLAKE2b-256 checksum How to use checksums |
378a9ff774772b93ce07dd3387d48f2f2f2097a4ed959bf5bc499454f3f9db57
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.
Transparency log