> ## Documentation Index
> Fetch the complete documentation index at: https://docs.genesiscomputing.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Salesforce

> Configure Salesforce connections in Genesis for CRM reads, record updates, and optional approval-gated duplicate merges.

## Overview

Salesforce appears in **Config -> Connections** under the **Dev Tools** category. Genesis supports four saved auth modes:

* `user_oauth` for per-user browser consent.
* `jwt_bearer` for server-to-server JWT bearer grants.
* `refresh_token` when you already hold a long-lived refresh token.
* `client_credentials` for OAuth client-credentials server-to-server access.

After setup, Genesis tests the connection against the configured login and instance hosts. On Snowflake Native App / SPCS deployments, Salesforce connections declare dynamic egress for `login_host` and `instance_url`; Genesis registers discovered hosts before opening Snowsight so the consent list includes every endpoint the connection needs.

## Setup workflow

<Steps>
  <Step title="Open the Salesforce connector">
    Go to **Config -> Connections**, choose **Dev Tools**, then select **Salesforce**.
  </Step>

  <Step title="Choose an auth mode">
    Use **User OAuth** for per-user consent, **Server-to-Server (JWT Bearer)** for integration-user JWT flows, **OAuth Refresh Token** when you already obtained a refresh token externally, or **OAuth Client Credentials (server-to-server)** for Connected App client-credentials grants on your My Domain host.
  </Step>

  <Step title="Enter connection fields">
    For every mode, set **Login Host** (for example `login.salesforce.com` or your sandbox host). Provide **Instance URL** when you know it so egress can be approved in one cycle; after User OAuth, Genesis may discover an instance host that differs from the login host.

    For **User OAuth**, create a Salesforce External Client App (or Connected App), enable OAuth, register the redirect URI Genesis displays, and add the `api` and `refresh_token` scopes. Paste the consumer key and secret into the connection OAuth fields. Genesis suggests the connection name `salesforce_oauth_main` and defaults scopes to `api` and `refresh_token`. The redirect URI embeds the connection name — register the exact value Genesis shows for the name you save. If authorization fails with `redirect_uri_mismatch`, use **Copy redirect URI** on the **Connect OAuth** step in the post-save guide; Genesis also points you to **Setup -> External Client App Manager -> your app -> Settings -> OAuth Settings -> Callback URL**. Salesforce can take a few minutes to propagate a callback URL change before retrying.

    For **JWT Bearer**, supply **Consumer Key**, **Salesforce Username**, **Private Key**, and the login host.

    For **Client Credentials**, use your org's **My Domain** host as **Login Host** — Salesforce rejects the client-credentials grant on `login.salesforce.com`. The Connected App or External Client App must designate a run-as user.
  </Step>

  <Step title="Test, egress, and save">
    On SPCS deployments, complete egress preflight in the post-save guide. When you click **Approve in Snowflake**, Genesis registers required endpoints first, then opens Snowsight. Save the connection, complete OAuth when required, and run **Test Connection**.
  </Step>
</Steps>

<Note>
  If your deployment uses outbound allowlists or external access controls, allow Genesis to reach both the configured **Login Host** and **Instance URL** hosts.
</Note>

## Connection fields

Shared optional merge settings appear on every auth mode:

| **Field** | **Type** | **Required** | **Default** | **Notes** |
| - | - | - | - | - |
| **`merge_enabled`** | Select (`false` / `true`) | No | `false` | Opt in to approval-gated merges. Defaults to off. |
| **`merge_survivorship_policy`** | Text (JSON) | Yes when merge is enabled | none | Survivorship policy for merge previews and execution. Required when `merge_enabled` is `true`. |

### `user_oauth`

| **Field** | **Type** | **Required** | **Default** | **Notes** |
| - | - | - | - | - |
| **`login_host`** | String | Yes | none | For example `login.salesforce.com` or a sandbox host. |
| **`instance_url`** | String | No | none | Discovered after authorization; provide it to approve egress in one cycle. |
| **`client_id`** | String | Yes | none | OAuth consumer key from the External Client App. |
| **`client_secret`** | String | Yes | none | OAuth consumer secret. |
| **`authorization_url`** | String | No | `https://login.salesforce.com/services/oauth2/authorize` | Genesis derives hosts from `login_host` when left at the standard default. |
| **`token_url`** | String | No | `https://login.salesforce.com/services/oauth2/token` | Same host derivation as authorization URL. |
| **`scopes`** | String | No | `api`, `refresh_token` | Comma- or space-separated scopes. |

### `jwt_bearer`

| **Field** | **Type** | **Required** | **Default** | **Notes** |
| - | - | - | - | - |
| **`consumer_key`** | String | Yes | none | Connected App consumer key. |
| **`username`** | String | Yes | none | Integration user username. |
| **`private_key`** | String (secret) | Yes | none | PEM private key for the JWT assertion. |
| **`login_host`** | String | Yes | none | For example `login.salesforce.com`. |
| **`instance_url`** | String | No | none | Recommended so egress can be approved in one cycle. |

### `refresh_token`

| **Field** | **Type** | **Required** | **Default** | **Notes** |
| - | - | - | - | - |
| **`client_id`** | String | Yes | none | OAuth client ID. |
| **`client_secret`** | String (secret) | Yes | none | OAuth client secret. |
| **`refresh_token`** | String (secret) | Yes | none | Pre-issued refresh token. |
| **`login_host`** | String | Yes | none | For example `login.salesforce.com`. |
| **`instance_url`** | String | No | none | Recommended so egress can be approved in one cycle. |

### `client_credentials`

| **Field** | **Type** | **Required** | **Default** | **Notes** |
| - | - | - | - | - |
| **`client_id`** | String | Yes | none | Connected App client ID. |
| **`client_secret`** | String (secret) | Yes | none | Connected App client secret. |
| **`login_host`** | String | Yes | none | **My Domain** host such as `mycompany.my.salesforce.com`, not `login.salesforce.com`. |
| **`instance_url`** | String | No | none | Normally the same host as **Login Host**. |

## Approval-gated merge

Merges are opt-in per connection and irreversible. Enable **Enable Approval-Gated Merge** (`merge_enabled`) only when operators are ready to govern duplicate consolidation.

When merge is enabled, set **Merge Survivorship Policy (JSON)** on the connection. The policy must include:

* `version` — non-empty string bound into the approval digest.
* `preview_fields` — non-empty list of field API names shown on the human review surface.
* `rules` — optional map of field names to survivorship rules.

Supported rule values: `prefer_survivor` (default when a field has no rule), `prefer_non_null`, `prefer_most_recent`, and `prefer_loser`.

Example:

```json theme={null}
{
  "version": "v1",
  "rules": {
    "Phone": "prefer_non_null"
  },
  "preview_fields": ["Name", "Phone"]
}
```

Genesis supports merging **Lead**, **Contact**, and **Account** only, with one survivor and at most two losers per merge.

### Merge workflow

1. **Preview** — `salesforce_connector` with `preview_merge`, or `POST /api/salesforce/merge/preview`. Writes nothing; returns projection and digest.
2. **Request approval** — `request_merge_approval` or `POST /api/salesforce/merge/approvals` with optional `expected_digest` from the preview.
3. **Human approve** — `POST /api/salesforce/merge/approvals/{approval_id}/approve`. Only a genuinely authenticated human can approve; agents cannot substitute.
4. **Execute** — `execute_merge` or `POST /api/salesforce/merge/approvals/{approval_id}/execute` with the bound connection name.

Approval lifetime defaults to `3600` seconds and is capped by `salesforce.max_approval_ttl_seconds` in App Config (default `86400`).

Salesforce approval-list reads perform on-demand stale-claim recovery; see [CRM merge endpoints](/docs/Genesis-API/API-Reference#crm-merge-endpoints) for the recovery behavior and threshold.

## What it enables

After setup, Genesis can use `salesforce_connector_tools` for bounded CRM reads and writes. With merge enabled, agents and operators can run the preview → approval → execute merge path for duplicate Leads, Contacts, and Accounts.

## Related pages

* [Connections](/docs/Setup/Connections)
* [OAuth Providers](/docs/Setup/OAuth-Providers)
* [Salesforce Connector Tools](/docs/Genbot-Toolkit/Salesforce-Connector-Tools)
* [Salesforce merge endpoints](/docs/Genesis-API/API-Reference#salesforce-merge-endpoints)
* [CRM merge endpoints](/docs/Genesis-API/API-Reference#crm-merge-endpoints)
