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

# Salesforce

> Three ways to connect a Salesforce org, for a normal user and for an API-only user.

The Salesforce integration lets your workflows query records, read a record, and read the schema of your org. It also runs the Sitetracker sync, if your org holds the Sitetracker package.

Salesforce is the one provider with three ways to connect. The other four have one. Read [Choose how to connect](#choose-how-to-connect) before you click any button.

## Why there are three options

Most providers show a sign-in page, and you give your consent there. Salesforce blocks that page for a user that holds the **API Only User** permission. Such a user gives consent nowhere, so a sign-in makes no connection.

Many organizations use exactly this type of user for an integration. The other two options exist for them, and they need no Salesforce credentials on your Current server.

## Before you start

You need two things:

* The **admin** role in the Current workspace.
* A Salesforce administrator, for the connected app or for the API user.

You also need the **My Domain URL** of your org, for example `https://acme.my.salesforce.com`. Find it in Salesforce Setup, under **My Domain**. Two of the three options ask for it.

## Choose how to connect

| Option                                                    | Use it when                                                                                 | What Current stores                                 |
| --------------------------------------------------------- | ------------------------------------------------------------------------------------------- | --------------------------------------------------- |
| [A connected app](#option-a-connect-with-a-connected-app) | Your Salesforce administrator makes a connected app in your org. **Use this option first.** | The consumer key and the consumer secret.           |
| [Sign in](#option-b-connect-with-the-sign-in)             | The user signs in through a browser, and your Current server holds Salesforce credentials.  | A refresh token.                                    |
| [An API user](#option-c-connect-with-an-api-user)         | Your org gives no Run As user to a connected app.                                           | The username, the password, and the security token. |

Option A is the recommended option. It stores no user password, it needs no security token, and it survives a password change. Choose another option only when option A is impossible.

<Note>
  For a sandbox org, use option A or option C. The sign-in option reaches `https://login.salesforce.com` only.
</Note>

## Option A: Connect with a connected app

Your Salesforce administrator makes a connected app in your own org and gives it a Run As user. Current then gets a token with the client credentials flow. There is no sign-in page and no user password.

The work divides between two people. Your Salesforce administrator does the first part, and you do the second.

### Your Salesforce administrator prepares the org

<Steps>
  <Step title="Make a connected app">
    In Salesforce, go to **Setup** > **App Manager**. Click **New Connected App**. A newer org shows **New External Client App**.

    Give a name and a contact email address.
  </Step>

  <Step title="Enable the OAuth settings">
    Select **Enable OAuth Settings**.

    Give a callback URL. The client credentials flow uses no callback, and Salesforce asks for a value:

    ```
    https://api.current.orinlabs.ai/api/integrations/callback/salesforce/
    ```
  </Step>

  <Step title="Select the api scope">
    In **Selected OAuth Scopes**, add **Manage user data via APIs (api)**.
  </Step>

  <Step title="Enable the client credentials flow">
    Select **Enable Client Credentials Flow**. Save the app.

    <Warning>
      A connection attempt in the first 10 minutes fails with `invalid_client_id`. Salesforce takes up to 10 minutes to make a new app available. Wait, then continue.
    </Warning>
  </Step>

  <Step title="Give a Run As user">
    Open the app. Click **Manage**, then **Edit Policies**. Under **Client Credentials Flow**, give a Run As user.

    <Warning>
      The connection reads and writes only the data that the Run As user reads and writes. Select a user with the permissions that your workflows need. To change the access later, change the permissions of that user. The change applies to the connection immediately.
    </Warning>
  </Step>

  <Step title="Read the credentials">
    Open the app and click **Manage Consumer Details**. Read the consumer key and the consumer secret.

    Send both to the Current workspace admin over a secure channel.
  </Step>
</Steps>

### The workspace admin makes the connection

<Steps>
  <Step title="Open the connect menu">
    In the portal, go to **Settings** > **Integrations**. Find the **Salesforce** row.

    Click the chevron at the side of **Connect**. A menu opens with three options. The plain **Connect** button starts the sign-in option, which is not this one.
  </Step>

  <Step title="Select the connected app option">
    Click **Connect with a connected app**. A form opens.
  </Step>

  <Step title="Give the three values">
    Give the My Domain URL of the org, for example `https://acme.my.salesforce.com`. You can also paste the full token endpoint URL.

    Give the consumer key and the consumer secret.

    <Warning>
      The address `https://login.salesforce.com` fails this flow, because the request holds no username. Give the My Domain URL of your org.
    </Warning>
  </Step>

  <Step title="Connect">
    Click **Connect**. Current gets a token one time to test the values, so the form stays open for a moment.

    <Check>
      The form closes and the **Salesforce** row shows the green **Connected** badge.
    </Check>

    Current reads every other value from Salesforce, such as the instance URL and the name of the Run As user. You give nothing more.
  </Step>
</Steps>

If Salesforce refuses the values, the form stays open, names the reason, and makes no connection:

| Message from Salesforce                 | What to do                                                                                         |
| --------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `request not supported on this domain`  | Give the My Domain URL of the org, not `https://login.salesforce.com`.                             |
| `no client credentials user enabled`    | Ask your Salesforce administrator to give a Run As user to the client credentials flow of the app. |
| `invalid_client_id` or `invalid_client` | Check the consumer key and the consumer secret. If the app is new, wait 10 minutes and try again.  |

To repair this connection, click **Reconnect** and give the three values again.

## Option B: Connect with the sign-in

Use this option when the user signs in through a browser.

<Steps>
  <Step title="Open the Integrations page">
    Go to **Settings** > **Integrations**.
  </Step>

  <Step title="Connect Salesforce">
    Find the **Salesforce** row. Click **Connect**.
  </Step>

  <Step title="Sign in to Salesforce">
    Sign in and give your consent to the `api` and `refresh_token` access.
  </Step>

  <Step title="Confirm the connection">
    The browser comes back to the **Integrations** page.

    <Check>
      The **Salesforce** row shows the green **Connected** badge.
    </Check>

    Click the chevron at the end of the row to read the instance URL of the org.
  </Step>
</Steps>

<Note>
  **Connect** is inactive when your Current server holds no Salesforce credentials. The grey line then reads `OAuth is not configured on this server — connect with credentials.` Use option A or option C, or speak to your Current contact.
</Note>

## Option C: Connect with an API user

Use this option only when your org gives no Run As user to a connected app. Current signs in with the Salesforce SOAP API instead.

This option stores a user password. A password change stops the connection, so plan for that.

<Steps>
  <Step title="Open the connect menu">
    Go to **Settings** > **Integrations**. Find the **Salesforce** row. Click the chevron at the side of **Connect**.
  </Step>

  <Step title="Select the API user option">
    Click **Connect via API user**. A form opens.
  </Step>

  <Step title="Give the username and the password">
    Give the username and the password of the Salesforce user.
  </Step>

  <Step title="Give the security token">
    Give the security token. See [Get a security token](#get-a-security-token) below.

    Leave this box empty if the IP address of your Current server is in the trusted IP ranges of the org.
  </Step>

  <Step title="Give the login host">
    Give the login host if your org has a My Domain sign-in policy, or if the org is a sandbox. For a sandbox, give `https://test.salesforce.com`.

    Leave this box empty for `https://login.salesforce.com`.
  </Step>

  <Step title="Connect">
    Click **Connect**. Current signs in one time to test the values.

    <Check>
      The form closes and the **Salesforce** row shows the green **Connected** badge.
    </Check>
  </Step>
</Steps>

If the sign-in fails, the form names the Salesforce fault code and makes no connection:

| Fault code                      | What it means                                            |
| ------------------------------- | -------------------------------------------------------- |
| `LOGIN_MUST_USE_SECURITY_TOKEN` | The org needs a security token. Give one.                |
| `INVALID_LOGIN`                 | The username, the password, or the token is not correct. |

<Warning>
  The connection stops when a person changes the password of the Salesforce user. Salesforce cancels the security token at the same time. Click **Reconnect** and give the new password and the new token.
</Warning>

### Get a security token

Salesforce sends a security token to the email address of the Salesforce user. A user receives a token in two ways only: the user changes the password, or the user resets the token in the Salesforce interface. An administrator reads the token nowhere.

<Accordion title="A user with the API Only User permission">
  A password reset sends no token to a user that holds the **API Only User** permission. To get a token for this user, the Salesforce administrator does these steps:

  1. Assign the user to a profile that does not hold the **API Only User** permission.
  2. Remove the login IP ranges from this profile. Salesforce hides the reset control while an IP range applies.
  3. Sign in as the user.
  4. Go to **Settings** > **Reset My Security Token**. Click **Reset Security Token**.
  5. Read the token in the email.
  6. Assign the user to the profile with the **API Only User** permission again.
</Accordion>

<Note>
  A security token fails if the profile holds the **Multi-Factor Authentication on API Logins** permission. That permission makes Salesforce ask for a verification code. Salesforce also asks for no security token when the IP address of your Current server is in the trusted IP ranges of the org.
</Note>

## Why Current keeps your credentials

Options A and C store a secret: the consumer secret, or the password with the security token. Current encrypts both.

Salesforce gives a short session. Current treats a Salesforce token as valid for 30 minutes, and it gets a new one about every 25 minutes. A person cannot repeat that by hand, so Current keeps the credential and renews the connection without you.

## The Sitetracker sync

If your Salesforce org holds the Sitetracker package, Current copies your projects into the workspace. The sync starts by itself one time each hour, at 15 minutes past the hour. You configure nothing.

The sync reads Salesforce. It writes to Salesforce never.

Each run writes the mapped field values of every project, and it records the new milestone changes as observations. A field write of the sync is versioned, so a member reverts it from the project feed.

<Note>
  The sync is not a workflow. The **Actions** page shows it nowhere, and no run history holds it.
</Note>

<Warning>
  The sync fails for an org without the Sitetracker package. It runs for every workspace with an active Salesforce connection, and it tests for the package nowhere. It reads projects from the Sitetracker objects, and an org without them gives an error each hour. Tell your Current contact if your org holds no Sitetracker package.
</Warning>

## Verify the installation

Go to **Settings** > **Integrations**. Click the chevron at the end of the **Salesforce** row.

<Check>
  The details give the instance URL of your org. For a connected app, they also give the Run-as user. A green badge with an instance URL confirms that Current signed in to your org one time.
</Check>

## Remove the integration

Go to **Settings** > **Integrations**. Click **Disconnect** on the **Salesforce** row, then confirm.

A disconnection always removes the credentials from Current. What happens at Salesforce depends on the option:

| Your option                     | What Current cancels at Salesforce                                                              |
| ------------------------------- | ----------------------------------------------------------------------------------------------- |
| The sign-in option              | The token. Current cancels it.                                                                  |
| A connected app, or an API user | Nothing. Current holds a secret or a password, and it sends neither to a cancellation endpoint. |

For a connected app, ask your Salesforce administrator to remove the app in **Setup** > **App Manager**. For an API user, ask for a password change on that user.

<Warning>
  A disconnection stops the Sitetracker sync for this workspace. The projects stay in the workspace, and their field values stop at their last value.
</Warning>

## Questions you may have

<AccordionGroup>
  <Accordion title="Which option do I choose?">
    Choose option A, the connected app, when your Salesforce administrator makes one. It stores no user password, and it survives a password change.

    Choose option B when the account signs in through a browser and your Current server holds Salesforce credentials.

    Choose option C only when option A is impossible.
  </Accordion>

  <Accordion title="I clicked Connect, and it started a sign-in that I did not want.">
    The plain **Connect** button starts the sign-in option. The other two options are behind the chevron at the side of that button.

    Click the chevron, then select **Connect with a connected app** or **Connect via API user**.
  </Accordion>

  <Accordion title="Which records does Current read?">
    The records that the connected identity reads.

    For option A, that identity is the Run As user of the connected app. For option C, it is the API user. To change the access, change the permissions of that user in Salesforce. The change applies immediately, and you connect nothing again.
  </Accordion>

  <Accordion title="Our connection stopped, and we changed nothing in Current.">
    A password change of the Salesforce user stops a connection that uses an API user. Salesforce cancels the security token at the same time.

    Click **Reconnect** and give the new password and the new token. To avoid this, move to option A.
  </Accordion>

  <Accordion title="Can I use a sandbox org?">
    Yes, with option A or option C. For option C, give `https://test.salesforce.com` as the login host.

    The sign-in option reaches `https://login.salesforce.com` only, so it fails for a sandbox.
  </Accordion>
</AccordionGroup>
