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

# Salesforce Integration

> Instructions for integrating the CamoAg platform with Salesforce using standard APIs.

## Overview

The CamoAg platform relies on standard Salesforce APIs to import customer first party client data, which is used to match customer client data to other third party data sets stored in CamoAg.

## Required and Optional Data

The data is considered to be non-sensitive or confidential information and low risk by most organizations and includes the following client/prospect information:

* Account/Contact Name
  * Required
* Address
  * Required
* Phone Numbers
  * Optional
  * Supports mobile, home and business
* Email
  * Optional
* Marketing (Optional, custom objects or fields within Salesforce)
  * Email opt out
  * Direct mail opt out
  * Do not market
  * Deceased
  * Segmentation / Customer Tier
    * e.g. Personas, Young/Beginning/Small Farmer, Gold, Silver, Bronze etc.
* Custom salesforce domain
  * Allows links to Salesforce account page from within the CamoAg platform
* Products & Services
  * Optional:
    * i.e.: Operating Loans, Real Estate Loans, Crop Insurance, or Seed, Chemical Fertilizer, etc.
    * Does not need to include specific details
  * Used in our Contact pane and BI reports
* Account type
  * Individual/Business client,prospect, or lead
  * Optional: Used in our Salesforce account pane, along with map iconography distinguishing between client vs. prospect
* Relationship manager / Crop Insurance Officer / Seed Rep
  * Optional, two distinct fields
  * Used in BI report and map filters, part of upcoming features to offer quick filters if the logged-in SSO user is the relationship manager or insurance officer
* Business type
  * Optional, if account is a business
  * Used for display

Optional additional information may also be provided should the customer wish to access this data through the CamoAg interface, but is not required.

<Note>
  Organizations implement Salesforce differently and store information with the account object and contact object.  It is important to understand where and how data is stored. CamoAg will work with your organization to determine the best approach for your integration.
</Note>

## Salesforce APIs and Usage

The CamoAg platform integrates with Salesforce using two standard Salesforce APIs.  Access to salesforce is read only for the Client Intelligence Integration.

1. [<u>Salesforce REST API</u>](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_rest.htm)
   1. Used for initial bulk account sync and sync based on published changed events
2. [<u>Change Data Capture</u>](https://developer.salesforce.com/docs/atlas.en-us.242.0.change_data_capture.meta/change_data_capture/cdc_intro.htm)
   1. Used to receive near-real-time change events when an account is created, updated, deleted, etc.

For Salesforce authentication, the CamoAg platform currently supports the [<u>OAuth 2.0 Client Credentials flow</u>](https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_client_credentials_flow.htm\&type=5).

After this data is in the CamoAg platform, the platform begins matching account data to other data stored in the CamoAg platform.

## Setting Up the External Client App

Authentication is configured in your Salesforce org as an External Client App using the OAuth 2.0 Client Credentials flow. A Salesforce admin can complete the whole setup below.

<Steps>
  <Step title="Create the External Client App">
    Go to **Setup → App Manager → New External Client App**. Give it a name (for example, `CamoAg Integration`) and set a contact email.
  </Step>

  <Step title="Enable OAuth settings">
    Under **API (Enable OAuth Settings)**, check **Enable OAuth**.
  </Step>

  <Step title="Enter a callback URL">
    Salesforce makes the **Callback URL** field mandatory as soon as OAuth settings are enabled. The client credentials flow never redirects a browser, so this value is never used — but the field still has to be filled in.

    Use your own org's OAuth success endpoint:

    ```
    https://<your-my-domain>.my.salesforce.com/services/oauth2/success
    ```

    `https://login.salesforce.com/services/oauth2/success` also works. The URL must be HTTPS.

    <Note>
      **Do not ask CamoAg for a callback URL to put here.** Any URL we supplied would be a dead endpoint. Use your own org, as shown above.
    </Note>
  </Step>

  <Step title="Select the OAuth scope">
    Add **one** scope:

    * **Manage user data via APIs (`api`)** — older orgs label this **Access and manage your data (api)**

    That single scope covers both things CamoAg does: REST/SOQL reads against `/services/data/`, and the Change Data Capture streaming subscription. Nothing else is required.

    Leave the rest off:

    * **`refresh_token` / `offline_access`** — the client credentials flow never issues a refresh token, so this is dead weight.
    * **`full`** — not used, and exactly the kind of over-grant a security review will flag.
    * **`web`, `id` / `profile` / `email`, `chatter_api`** — not used.
  </Step>

  <Step title="Enable the client credentials flow">
    In the app's policies, check **Enable Client Credentials Flow** and set **Run As** to a dedicated integration user. See [Integration User and Read-Only Access](#integration-user-and-read-only-access) below — this is the setting that actually determines what CamoAg can and cannot do in your org.
  </Step>

  <Step title="Send CamoAg the credentials">
    Open **Manage Consumer Details** and share the **Consumer Key** and **Consumer Secret** with CamoAg over a secure channel. Please do not send them in plaintext email.
  </Step>

  <Step title="Check IP restrictions">
    If the app enforces IP restrictions, either relax them for this app or ask CamoAg support for our egress IP ranges to allowlist. Otherwise, authentication will fail.
  </Step>
</Steps>

## Integration User and Read-Only Access

<Note>
  **OAuth scopes do not make the integration read-only.** The `api` scope grants API access; what CamoAg can actually see and change is determined entirely by the profile and permission sets of the **Run As** user. This is the step most often missed.
</Note>

* **Use a dedicated integration user** for the Run As assignment rather than a person's account. Salesforce recommends granting that user the **API Only User** permission, which prevents interactive login.
* **Grant Read only** — at both the object level and the field level — on the objects CamoAg syncs. Do not grant Create, Edit, or Delete. This is what enforces the read-only guarantee described above.

<Note>
  Change Data Capture events only deliver fields the subscribing user is allowed to read. A field-level security gap therefore shows up as **silently missing data, not an error**. If a field looks empty in CamoAg, check field-level security on the integration user first.
</Note>

## Change Data Capture Setup

<Note>
  **Change Data Capture is not a webhook.** CamoAg initiates all connections outbound to your Salesforce instance and continually maintains them via CometD long polling ([https://your-instance.my.salesforce.com/cometd/:version](https://your-instance.my.salesforce.com/cometd/:version)). Salesforce never pushes to a CamoAg endpoint, so no inbound network path, exposed endpoint, or callback URL is required on your side.
</Note>

<Steps>
  <Step title="Select the entities to publish">
    Go to **Setup → Change Data Capture** and select the entities you want change events published for.
  </Step>

  <Step title="Start with Account">
    **Account** is what our standard integration subscribes to (`/data/AccountChangeEvent`), so it's the right starting point for most orgs. It isn't a hard requirement — some integrations are scoped to different  objects, or use custom platform events instead. If you're unsure, enable **Account** and we'll confirm the final channel list with you during onboarding.
  </Step>

  <Step title="Add custom platform events if needed">
    Where a workflow calls for it, CamoAg can also subscribe to custom platform events in your org. Coordinate the event name with your CamoAg contact so we can configure the subscription on our side.
  </Step>

  <Step title="Confirm the integration user can access them">
    The integration user needs sufficient access to every entity selected here. Permission gaps don't raise an error — depending on what's missing, events either don't arrive at all or arrive with fields absent — so it's worth checking your org's setup against Salesforce's [requirements for change event subscribers](https://developer.salesforce.com/docs/atlas.en-us.change_data_capture.meta/change_data_capture/cdc_security_perms.htm).

    **Read access alone is not enough to subscribe.** Change events are only delivered to a user who can see *every* record of an object, so for each object in the channel the integration user also needs one of:

    * **View All Records** on that specific object, or
    * the org-wide **View All Data** permission.

    Grant this on the permission set assigned to the Run As user — the same user behind the Consumer Key and Secret. Object-level **View All Records** is the narrower of the two and is usually the better choice; **View All Data** exposes every object in the org.

    <Note>
      Both are view permissions, so neither one weakens the read-only setup described above. They widen *which records* the integration user can see, not what it can change.
    </Note>
  </Step>

  <Step title="Re-check this if record access in your org is restricted">
    Orgs that scope users to a select few objects — through a restrictive role, sharing rules, or a narrowly scoped permission set — are where this most often goes wrong, and custom channels are the common case.

    Read access on an object is easy to mistake for enough. A permission set can grant Read on, say, Account and Contact and still deliver no events, because neither object has **View All Records**. Walk the channel object by object and confirm the permission on each one individually rather than on the objects that look most relevant.

    <Note>
      A missing record-access permission is silent. The subscription still authenticates and the connection stays open, but events never arrive. If the setup looks correct and nothing is coming through, audit these permissions first.
    </Note>
  </Step>
</Steps>

## Salesforce Custom Field

It might be desirable to provide a link in Salesforce to an account within the CamoAg platform; CamoAg intentionally uses the case safe 18-digit Salesforce ID in its route to an account. One option is to create a Formula (Text) field on the Salesforce Account object as follows:

"[https://app.camo.ag/research/account/"\&CASESAFEID(Id)](https://app.camo.ag/research/account/"\&CASESAFEID\(Id\))
