> For the complete documentation index, see [llms.txt](https://v2.dataos.info/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://v2.dataos.info/concepts/resources/nilus/batch/batch-sources/salesforce.md).

# Salesforce

[Salesforce](https://www.salesforce.com/) is the cloud CRM platform for sales, service, marketing, and analytics. Nilus uses Salesforce as a batch source to extract standard and custom objects, accounts, opportunities, contacts, leads, custom objects, into a downstream warehouse for sales and revenue analytics.

Under the hood, Nilus authenticates against the [Salesforce REST API](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_what_is_rest_api.htm) using username/password plus a security token. Standard objects load in `replace` mode; a few objects (opportunity, account, etc.) support automatic incremental loading via Salesforce's `SystemModstamp` / `LastModifiedDate`.

## Requirements

Connectivity and credentials must both be in place before the pipeline can run.

### Connectivity

* The Nilus runtime must be able to reach `https://<your-domain>.my.salesforce.com` over HTTPS.
* The Salesforce user must be granted API access (Profile → Administrative Permissions → API Enabled) and read access on every object in `source_table`.
* Security tokens are required when logging in from outside trusted IP ranges. Reset the token if the password changes.

{% hint style="info" %}
Salesforce credentials grant read access to your CRM. Project all four parameters (`username`, `password`, `token`, `domain`) from a Nilus instance secret rather than embedding them in YAML.
{% endhint %}

### Required parameters

| Parameter  | Required | Default | Description                                                                                                 |
| ---------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------- |
| `username` | Yes      | -       | Salesforce account username (typically an email).                                                           |
| `password` | Yes      | -       | Salesforce account password.                                                                                |
| `token`    | Yes      | -       | Salesforce security token. Reset/copy from Setup → My Personal Information → Reset My Security Token.       |
| `domain`   | Yes      | -       | Salesforce instance domain (e.g. `my-org.my`, used as `<domain>.salesforce.com`). Use `test` for sandboxes. |

### URI format

```
salesforce://?username=<salesforce-username>&password=<password>&token=<token>&domain=<domain>
```

## Supported objects

| Object                        | Merge key          | Strategy | Description                                                                |
| ----------------------------- | ------------------ | -------- | -------------------------------------------------------------------------- |
| `user`                        | -                  | replace  | Users with access to the org.                                              |
| `user_role`                   | -                  | replace  | Role definitions and hierarchy.                                            |
| `contact`                     | -                  | replace  | Contact records associated with accounts.                                  |
| `lead`                        | -                  | replace  | Lead records.                                                              |
| `campaign`                    | -                  | replace  | Campaign records.                                                          |
| `product`                     | -                  | replace  | Product catalog (`Product2`).                                              |
| `pricebook`                   | -                  | replace  | Price book definitions (`Pricebook2`).                                     |
| `opportunity`                 | `SystemModstamp`   | merge    | Sales opportunities. Incremental.                                          |
| `opportunity_line_item`       | `SystemModstamp`   | merge    | Products on opportunities. Incremental.                                    |
| `opportunity_contact_role`    | `SystemModstamp`   | merge    | Contact roles on opportunities. Incremental.                               |
| `account`                     | `LastModifiedDate` | merge    | Customer/organization accounts. Incremental.                               |
| `campaign_member`             | `SystemModstamp`   | merge    | Contacts/leads associated with campaigns. Incremental.                     |
| `custom:<custom_object_name>` | -                  | replace  | Custom Salesforce objects. Pass the API name (e.g. `custom:My_Object__c`). |

### Field handling

* All available fields are retrieved automatically.
* **Compound fields** are excluded by Salesforce (except for `Name`).
* System fields (`SystemModstamp`, `LastModifiedDate`) are always included and used for incremental tracking.
* Do **not** set `incremental_key`, Nilus picks the right one per object.

### Example: DataOS secret

```yaml
name: salesforce-cred
version: v2alpha
type: secret
description: Salesforce credentials for Nilus
spec:
  type: key-value
  data:
    SALESFORCE_USERNAME: <base64>
    SALESFORCE_PASSWORD: <base64>
    SALESFORCE_TOKEN: <base64>
    SALESFORCE_DOMAIN: <base64>
```

## Source options

| Option            | Required | Description                                                                |
| ----------------- | -------- | -------------------------------------------------------------------------- |
| `source_table`    | Yes      | One of the resources in the [supported objects](#supported-objects) table. |
| `incremental_key` | No       | Not used. Nilus manages refresh cadence per resource internally.           |

## Sink options

| Option                 | Required | Description                                                                                               |
| ---------------------- | -------- | --------------------------------------------------------------------------------------------------------- |
| `dest_table`           | Yes      | Destination table name. Use one stable target per source resource so re-runs merge cleanly.               |
| `incremental_strategy` | Yes      | Destination write behavior. Use `merge` for time-aware resources, `replace` for snapshot-style resources. |

## Sample Nilus config

```yaml
name: salesforce-account-batch
version: v1alpha
type: nilus
spec:
  type: batch
  compute: universe-compute
  source:
    address: salesforce://?username={SALESFORCE_USERNAME}&password={SALESFORCE_PASSWORD}&token={SALESFORCE_TOKEN}&domain={SALESFORCE_DOMAIN}
    options:
      source_table: account
  sink:
    address: dataos://warehouse?purpose=rw
    options:
      dest_table: salesforce_objects.account
      incremental_strategy: merge
```

## Behavior and capabilities

* **Pipeline mode**: Salesforce runs as a `batch` source.
* **Object selection**: set `source.options.source_table` to one standard object, custom object, or supported Salesforce resource from the supported objects table.
* **Fetch semantics**: most objects load as full snapshots with `replace`; selected high-change CRM objects use Salesforce modification timestamps and should write with `merge`.
* **Field handling**: Nilus retrieves available fields automatically, excludes unsupported compound fields, and preserves Salesforce system fields needed for incremental tracking.
* **Custom objects**: use `custom:<api_name>` with the Salesforce API name, including the `__c` suffix.

## Troubleshooting

| Symptom                            | Likely cause                                                                        | Resolution                                                                                     |
| ---------------------------------- | ----------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `INVALID_LOGIN`                    | Wrong username, password, token, or domain. Token resets when the password changes. | Reset the security token, update the secret, and verify domain (use `test` for sandboxes).     |
| `INSUFFICIENT_ACCESS`              | User profile lacks API access or object-level read permission.                      | Grant `API Enabled` profile permission and the relevant object permissions.                    |
| `INVALID_FIELD` on a custom object | Field-level security is hiding fields from the API user.                            | Edit the user's profile/permission set to grant `Read` on those fields.                        |
| Custom object not found            | Wrong API name in `custom:<name>` (custom objects always end in `__c`).             | Use the API name shown in Setup → Object Manager → `<Object>` → Details (e.g. `My_Object__c`). |

## Related docs

* [Batch sample configs](/concepts/resources/nilus/batch/sample-configs.md)
* [Understanding Batch Pipeline Config](/concepts/resources/nilus/batch/pipeline-config.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://v2.dataos.info/concepts/resources/nilus/batch/batch-sources/salesforce.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
