Connectors / Service / Salesforce

Salesforce is a leading enterprise customer relationship management (CRM) application, based in the cloud. (updated: 1669025050752)


Salesforce is a cloud based customer relationship management software suite.


Salesforce provides customer relationship management service software, and has a complementary suite of enterprise applications as well. These are focused on customer service, marketing automation, analytics, and application development. It is the market leader in CRM solutions.


PLEASE NOTE: SFDC Editions with API Access include: Enterprise, Unlimited, Developer, and Performance. Any licenses that do not have this edition cannot communicate to external services via API.

When using the Salesforce connector for the first time, you will need to create a new authentication:


You will then need to select the 'scopes' for your authentication to configure exactly what access your Tray workflow will have to Salesforce:

Note that for standard use, you will always need to tick the Api scope


You will then be prompted to enter the credentials of the Salesforce user you will be authenticating with.

This user must be set up with the correct permissions in the Salesforce Admin UI, to ensure that you will be able to access all the available connector operations.

Correct setup of user permissions

Managing access

The Tray Salesforce connector gives you full access to all of your Salesforce data including leads, contacts, custom objects/fields, and even workflow rules and outbound messages.

Therefore you will need to make sure that the user you authenticate with has access to the correct objects and record types - in a read, write and create capacity, depending on need.

Managing permissions for users in Salesforce can be done using Profiles and Permission Sets.

Currently the Salesforce connector can only be used on the Enterprise Edition of Salesforce, and higher. You may use the Salesforce connector on Professional Edition, but ONLY if you've requested API access from your Salesforce account manager. However, you will not be able to use instant WebHooks on the Professional Edition.

Managing access with profiles

Managing access with Permission Sets

Salesforce Trigger

If you wish your workflow to be kicked off by a particular action in Salesforce, you can use the Salesforce Trigger.

The Salesforce trigger allows you to receive notifications and trigger workflows when given events occur associated with the selected trigger operation.

Note that the Salesforce Trigger uses the same authentication method which is described earlier in the first section of this page.

Trigger features

The Salesforce trigger has a couple of fairly unique features that you should be aware of before you begin using it

The first is that users can white-label the trigger should they chose to i.e. adjust Salesforce objects with prefixes.

The second is to note that the trigger has two types of trigger events to choose from. Standard trigger events and Manually-created trigger events.

More details on both features can be found below.

IMPORTANT! Note that when using the Salesforce trigger, you currently must use a permission set and add it to the User that you will be authenticating with. This permission set must have the 'Modify all Data' and 'Customize Application' permissions.

Handling Events from the Salesforce Trigger

Trigger event types

Trigger demos

On Custom Flow Formula

IMPORTANT!: Salesforce has changed its structure so that Flows have now replaced Rules. This is one of the reasons why the previous 'On custom workflow formula' operation is no longer available.

Please see the following article for more details. Note that there is a migration tool available to help users convert their previous rules to flows should you wish to keep your previous work.

Below is an example of a way in which you could potentially use the Salesforce trigger using the On Custom Flow Formula operation.

This example demo's how to use Salesforce formulas and operations. The example here check's if the field in question does not return a blank field

Due to the complexity we have very briefly outlined the method and included links to the Salesforce documentation where necessary for further guidance.


On Outbound Message

Below is an example of a way in which you could potentially use the Salesforce trigger with the On Outbound message operation.

This example demo's how to create a Flow which will trigger (and activate your your workflow) once an opportunity record's amount field has been been created / updated to more than 20. The fields have been filled in as follows.


Notes on using Salesforce

Handling Leads in Salesforce

You can find a list of records from Salesforce, using the "Find Records" operation.


Once a lead is converted, you cannot update them in any way, and they are no longer available in the Salesforce interface.

Behind the scenes in the API, Salesforce uses a "Converted" field which is either true or false. You can use this in the Salesforce connector to get a list of leads who haven't been converted yet, for example.


Going a step further, leads can be converted into Contacts, Opportunities, and Accounts. In tray it's possible to get the "ID" of the relevant new converted objects using the "Converted Account ID", "Converted Opportunity ID" and "Converted Contact ID" fields.


Data processing

When using Salesforce in production workflows, you will likely be dealing with large amounts of data - processing hundreds or thousands of rows.

In this case, you will likely need to make use of callable workflows to send data for sub-processing. Learn more about this in our course on callable workflows from the Tray Academy Live

You also may need to use our CSV Editor as an intermediate storage medium, before making use of the batch/bulk operations.

When dealing with large amounts of data in Salesforce it is important to be aware of:

  • What are the API limits according to your account, in terms of how many API calls can be made per day. Please the Salesforce API limits page for guidance on this

  • How can you use to manage the amount of API calls that are being made?

In order to address the second point, you will see that certain operations for pulling data from Salesforce offer pagination options which allow you to grab batches of data in one and then loop through them with, instead of making repeated single calls. The section below on Pulling data and pagination takes you through this in detail.

When pushing data to Salesforce you may need to make use of the batch create / update and bulk upsert operations. These allow you to reduce hundreds of record updates to a single call, and so are extremely important in terms of managing your API limits. Please the section on Pushing data and batch / bulk operations for detailed explanations of this.

Batch Operations input structure

The input stucture for batch operations varies depending on which operation is being used:

Create &/ Update Flow Names

These operations will automatically set up your Salesforce Flows for you.

  • On Record Create

  • On Record Update

  • On Record Create or Update

Be aware that your Flow name will be autogenerated. Your Flow will be available to view in the All Flows page.

The name of your Flow will be based on the Object prefix (which is automatically set to "Tray"), the name of the operation itself, and will include a random hash following it.

Note that the Object prefix can be changed under the Show Advanced Properties button in the trigger's property panel.


Example usage

Salesforce and Trello

Below is an example of a way in which you could potentially use the Salesforce trigger and connector, to integrate with Trello. In this imagined scenario, upon creation of a Salesforce record, the workflow checks who created said card and if it was a Partner referral. Should this be the case, the workflow will set a time limit for contact to be made.

The steps will be as follows:

  1. Setup the trigger and the first connector step in order to get the new record information.

  2. Create a boolean condition to base your output on.

  3. If a partner referral is not confirmed, create a Trello card as standard.

  4. If a partner referral is confirmed, set a contact due date on said Trello card.

The final outcome should look like this:


Advanced topics pt. 1

Managing API limits

Pulling data and pagination

When using certain operations such as the 'Find Records' operation, you will find there are 'pagination' options which allow you to pull results from Salesforce in batches.

This means you can limit the number of API calls you make - e.g. you can retrieve 3 batches of 2000 records which match your criteria, instead of making 6000 individual calls for each record.

The following workflow shows a basic pagination system where we are pulling batches of leads from Salesforce with a rating of 'warm' in order to loop through them and send them to another third-party service:


For a full explanation and pre-built pagination workflow please see our 'Paginate through Salesforce Records' template:

You can adjust this template to your exact needs any time you need to paginate through batches of pulled SFDC records.

Pushing data and batch / bulk operations

As mentioned above, when you are pushing large batches of data to Salesforce, you will need to control the rate at which you do so in order not to exceed your API limits.

  • 'Bulk upsert' is effectively two operations in one - if a record of a particular type (e.g. 'lead') is found then it will be updated, if it is not found then a new one of that type (e.g. 'lead') will be created

  • 'Batch Update' / 'Batch Create' can be used together when, in the case of a record of a particular type (e.g. 'account') not being found, you wish to create a record of a different type (e.g. 'lead')

Bulk upsert

PLEASE NOTE: The 'Bulk upsert' operation only accepts data in CSV format

This demo imagines a scenario whereby, for a particular Salesforce Account, you have pulled together information on a number of the Salesforce contacts for that Account (i.e. the people who work for that company) - from a number of sources (e.g. enrichment info from Zoominfo and Clearbit) and you are wanting to achieve the following:

  • upload this contact information to Salesforce using a limited number of API calls

  • if a contact doesn't exist in Salesforce, then the upsert operation will auto-create a new contact using the information provided

The following screenshot shows that we are picking the workflow up from the point where we have pulled the contact data together into data storage.

We then take the following basic steps:

  1. Fetch the records and count the total number

  2. If the total number of records found is only 1, use the single 'Create/update record' operation

  3. If the total number of records found is more than 1, create a CSV to store the contacts in (this is because data must be in CSV format for the Bulk upsert operation)

  4. Export the CSV file and upload the data to Salesforce using 'Bulk upsert'


In detail the steps being followed are:

IMPORTANT!: In implementing a solution like the above you would need to make sure that you do not overload data storage (the limit for data stored under a single key is 400K). So if you are processing thousands of records you would likely use a Callable Workflow to send them off for sub processing.

Polling a bulk upsert

When a bulk operation is used, Salesforce does not process the data immediately, instead it starts a bulk data load job. The time in which it takes for this job to finish depends on resources available in your Salesforce instance.

When you use a bulk data operation it receives a Job ID (or just ID as shown in the connector step output).

This job ID can then be used to poll for the status of the job. Only when the job shows a status of JobComplete has the data been successfully processed in Salesforce.

The following workflow shows a Bulk Upsert job has been started - pulling a CSV file from a trigger:


The Repeat polling call step uses the 'Loop Forever' operation.

The Poll SF - check job status step uses the 'Get job info' operation. It pulls in the 'Job ID' using the $ jsonpath

On each iteration of the Loop, we check if the job has succeeded by looking at the status field. If the job has completed it will show a status of JobComplete:


Is job complete? is a boolean step which checks if $.steps.salesforce-2.state is equal to JobComplete.

IMPORTANT!: As per Salesforce's API docs the completed status could also be UploadComplete. The following screenshot from the Salesforce docs shows the different job statuses you might check for:


The TRUE branch of the boolean contains the Break loop step (referring to the correct loop! 'loop-1' in this case).

The FALSE branch of the boolean has the Delay and repeat loop step:


You can set the delay to be e.g. 1 minute before the next check.

A key point here is that each check is an API call, so if you are running a large update job you don't want to be checking every 10 seconds!

IMPORTANT!: When using the 'Loop forever' operation to poll for a status you should factor in the possibility that a status will never be reached. To allow for this you should include a check on how long the loop has been running, as illustrated in our Loop Connector documentation .

Get Job Information

Add a final Salesforce connector step to your workflow. This is used to gather the job information (how many file uploads, which failed, time taken etc). Set the operation to 'Get job info' and the 'Job ID' to: $

In your Debug panel you should see results similar to below:


Batch update / batch create

As mentioned above, there may be a bulk upload scenario where, if a record is not found then you want to create a record of a different type (which is not possible with 'Bulk upsert').

This section will be a very simple demo of using a combination of the 'Batch update records' and 'Batch create records' operations to achieve this.

IMPORTANT! The Salesforce API will only receive batch update / create lists in an exact format, as explained in the above note on batch operations input structure. The below example shows a way of formatting your input using the Object Helpers 'JSON parse' operation.

IMPORTANT! When processing batches of data using Data Storage lists, you need to be conscious of the fact that the storage limit under one key is 400K. One way to handle this is for batches to be sent for parallel processing to a callable workflow which uses 'current run' data storage that is cleared after each run (as discussed in our guide to workflow threads ). Another approach might be to use the CSV Editor .

The scenario is that a callable workflow is receiving batches of data such as the following:


The idea is that all records with an object_id are pre-existing Salesforce Accounts that need to be updated with Phone and BillingCity.

While records without an object_id do not yet exist in Salesforce and we need to turn them into Leads which might become Accounts at a later stage.

The screenshot below shows a callable workflow which is receiving these batches of records:


The data being received by the Callable Trigger is in json format:


The following steps are taken through the course of the workflow:

Advanced topics pt. 2

Deduplicating and merging Salesforce Records

Over time you may find that duplicate records build up in your Salesforce database.

The following workflow imagines a scenario whereby new leads being created need to be checked for pre-existing duplicates:

  1. The Listen for Lead Creation triggers the workflow when a new lead is created in Salesforce

  2. Get New Lead uses the 'Find records' operation, using the $[0].Id jsonpath to retrieve the newly created lead, including all the relevant associated fields (FirstName, LastName, Email, Phone, Lead ID, Company etc.)

  3. We then conduct a series of 3 checks to see if this lead already exists as a duplicate (explained in detail below)

  4. If any of these checks find a duplicate, the Salesforce id for the duplicate lead is stored using a Data Storage set id step ('Set Value operation'), and the workflow moves on to the de-duplicating stage

  5. If all 3 checks fail to find a duplicate then the workflow is terminated, as no action needs to be taken

  6. If deduplicating is required, the Data Storage get id step uses 'Get Value' to retrieve the id of the duplicate lead

  7. Get Old Record is a 'Find Records' operation which uses $ to retrieve the duplicate lead, including all the relevant associated fields (FirstName, LastName, Email, Phone, Lead ID, Company etc.)

  8. Build Merged Lead Values is a script which then replaces all the old duplicate values for name, email, etc. with the values from the new lead. If they are not present for the new lead then the original old values will be used

  9. Merge Leads finally uses the Salesforce 'Merge Records' operation with the new Lead ID ($[0].Id) as the Master record ID and the old Lead ID ($ as the 'Record to merge'. The 'Fields to populate' come from the result of the merged values script ($.steps.script-1.result)

PLEASE NOTE: You can import the above workflow yourself for inspection and testing. Just click here to download the workflow file. To import just create a ne workflow with any kind of trigger, then click on the import option in the top-left of the workflow builder:


The duplicate checks explained

When making the above duplicate checks, we are making a series of checks of varying degrees of certainty.

The first check is by email:


Looking at the properties panel, we can see how this check is set up:


You can see that while a check is being made to see if any existing leads match this new lead by email, we are also checking for First Name, Last Name and Vertical (i.e. automotive, banking, consumer etc.)

The subsequent checks by phone and company use the same conditional setup, replacing email with phone and company.

By the end of this process we will have checked with approx 99% degree of certainty for pre-existing duplicates (these aren't absolute failsafes as there could be a typo in each field we are checking)

Merging the new and duplicate record

After using the Data Storage get id step to retrieve the id of the identified duplicate, we fetch the duplicate lead itself:


The Build Merged Lead Values script step then pulls in the old Lead values and new Lead values as variables:


The script itself is simple:

// You can reference the input variables using input.NAME
// Parsed JSON files could be referenced as fileInput
exports.step = function(input, fileInput) {
let values = [];
for(let key in input.newLead){
if(key !== "Id"){
if(input.newLead[key] === null){
"name": key,
"value": input.oldLead[key]
} else {
"name": key,
"value": input.newLead[key]
return values;

It will replace all values from the old lead with values from the new lead.

If the new lead does not have a particular value, then the old lead value will be retained.

The output is then in a format which will be accepted by the Salesforce schema for merging records. For example:

"result": [
"name": "FirstName",
"value": "Roger"
"name": "LastName",
"value": "Ramjet"
"name": "Phone",
"value": "(850) 777-2436"
"name": "Id",
"value": "00Q1QxxxxxxYGUA3"
"name": "Vertical__c",
"value": "Automotive"
"name": "Company",
"value": "Ramjet and co"
"name": "Email",
"value": ""
"name": "MobilePhone",
"value": "(850) 755-3555"
"console": []

The output of the script step can then be used in Fields to populate for the Merge leads step:


SOQL Query & SOSL Query operations

The Salesforce Object Query Language (SOQL) and Salesforce Object Search Language (SOSL) APIs can be used to search your organisation’s Salesforce data.

Generally speaking when using these query operations, you should use SOQL to query one operation at a time, and SOSL when you want to search text, email, phone fields, etc (basically when searching multiple objects simultaneously). This is why the latter is better to use when querying a relationship between objects and such.

Here are some points you need to consider when choosing between the two query operations:

Use SOQL when you know which objects the data resides in, and you want to:

  • Retrieve data from a single object or from multiple objects that are related to one another.

  • Count the number of records that meet specified criteria.

  • Sort results as part of the query.

  • Retrieve data from number, date, or checkbox fields.

IMPORTANT!: Please note that for for SOQL Query to accept your date references, the format MUST BE: YYYY-MM-DD. Please see the SOQL API Documentation site for more details.

Use SOSL when you don’t know which object or field the data resides in, and you want to:

  • Retrieve data for a specific term that you know exists within a field. Because SOSL can tokenize multiple terms within a field and build a search index from this, SOSL searches are faster and can return more relevant results.

  • Retrieve multiple objects and fields efficiently where the objects might or might not be related to one another.

  • Retrieve data for a particular division in an organization using the divisions feature.

  • Retrieve data that’s in Chinese, Japanese, Korean, or Thai. Morphological tokenization for CJKT terms helps ensure accurate results.

The language used is crucial for your search patterns. In principal, it is extremely similar to SQL in text style.

With the above taken into consideration, below is an example of a SOQL query, which also involves using the Date & Time helper connector (notice how the 'Format' has been deliberately set up to suit Salesforce protocols):


This image demonstrates the way one may use the SOSL query operation to run through 'All Fields' available, in order to return any and all account names and IDs found (unlike the above query example, this is tailored towards multiple )


For further information regarding the Salesforce Object Query Language (SOQL) and Salesforce Object Search Language please see their API Documentation site for more details.

Using the Raw HTTP Request ('Universal Operation')

IMPORTANT!: Please note that the Raw HTTP Request only works with REST API endpoints. You cannot make requests to SOAP API endpoints.

As of version 7.5, you can effectively create your own operations.

This is a very powerful feature which you can put to use when there is an endpoint in Salesforce which is not used by any of our operations.

To use this you will first of all need to research the endpoint in the Salesforce API documentation, to find the exact format that Salesforce will be expecting the endpoint to be passed in.

Note that you will only need to add the suffix to the endpoint, as the base URL will be automatically set (the base URL is picked up from the value you entered when you created your authentication).

IMPORTANT!: Accessing the base URL: If you need to access the base URL (e.g. for making a Full URL Raw HTTP requests) then the following information will be useful. The base URL for Salesforce is your Salesforce instance URL. It will most likely be similar to: '' where 'abc123' is your Salesforce instance name. You may access your Salesforce instance URL within a workflow by using jsonpath to extract it from the authentication parameters** '$.auth.instance_url'**.

For example, say that the 'Get Job Info' operation did not exist in our Salesforce connector, and you wanted to use this endpoint, you would use the Salesforce API docs to find the relevant endpoint - which in this case is a GET request called: /services/data/vXX.X/jobs/ingest/jobID.

PLEASE NOTE: You will need to enter the correct API version (e.g. 'v51.0') and the correct job ID (e.g. '7504S000001nOJkQAM') in order to build a valid endpoint for the URL.

More details can be found here.


So if you know what your method, endpoint and details of your query parameters are, you can get the Salesforce job information with the following settings:

Method: GET

Endpoint: /services/data/v51.0/jobs/ingest/7504S000001nOJkQAM

Query Parameters: None

Body Type : None : null

Final Example outcome being:


All Operations

Latest version:


Batch create records

Create a batch of new records in Salesforce. (Max 200).

Batch delete records

Delete a batch of records in Salesforce. (Max 200).

Batch update records

Update a batch of records in Salesforce. (Max 200).

Bulk update records

Bulk update records using the Salesforce Bulk API. Record data should be in CSV format.

Bulk upsert records

Bulk upsert records using the Salesforce Bulk API. Record data should be in CSV format

Convert Lead

Convert a lead into an account, contact and/or opportunity

Count records

Count the number of records that match a given set of conditions.

Create amendment quote

Create an amendment quote for a contract.

Create custom field

Create custom field metadata. Single or multiple fields can be created.

Create query job

Creates a query job.

Create record

Create a new record in Salesforce.

Create/update record

Create a record if a record with the "lookup value" doesn't already exist. Update it if it does exist.

Create/update record using ID

Create a record if a record with the 'lookup value' doesn't already exist. Update it if it does exist. If there is no external ID to reference, insert a new record using ID as the External ID.

Delete custom field

Delete custom field metadata. Single or multiple fields can be deleted in a single operation.

Delete query job

Deletes a query job.

Delete record

Delete a record in Salesforce, using it's unique object id.

Describe object (advanced)

Describes the raw structure of an object in Salesforce.

Download attachment

Downloads a file attachment from Salesforce, for use in other connectors.

Download file

Downloads a file from Salesforce.

Execute report async

Runs an instance of a report asynchronously with or without filters.

Execute report query

Returns report data without saving changes to an existing report or creating a new one.

Execute report sync

Runs a report immediately with or without changing filters, groupings, or aggregates and returns the latest summary data with or without details for your level of access.

Find records

Find a list of records in Salesforce.

Get Record Object Description

Get the description of a record type, given the unique ID of the record of that type in Salesforce.

Get consent

Locate customers’ preferences for consent across multiple records.

Get instance results

Retrieves results of an asynchronous report run.

Get job info

Get details about a bulk data processing job

Get job successful record results

Retrieve a list of successfully processed records for a completed job as a CSV file.

Get omni-channel presence status

Get the presence status of an omni-channel

Get picklist item details

Retrieves details for a specific picklist item from a given object and field name.

Get query job

Gets information about one query job.

Get query job results

Returns a CSV file with the results of a completed query job.

Get user info

Get details about the authenticated Salesforce user.

List jobs

Retrieve a list of jobs created by bulk data operations e.g. Bulk upsert records

List query jobs

Gets information about all query jobs.

List query jobs DDL

List report fields

Retrieves report fields available for specified reports.

List report fields DDL

List report fields for standard date filter DDL

List report instances

Returns a list of instances for a report.

List report types

Return a list of report types.

List report types DDL

List reports

Retrieves a list of up to 200 reports that you recently viewed.

List reports DDL

Merge records

Merge records into a master record. Be advised if you want to keep values from non-master records the Fields to populate input must be used

Raw HTTP request (advanced)

Perform a raw HTTP request with some pre-configuration and processing by the connector, such as authentication.

Revoke tokens

Revokes the access and refresh token used in the auth, which makes the authentication useless

Run report (sync)

Run a report from your Salesforce Reports list.

SOQL Query (advanced)

Execute a raw SOQL query to extract data from Salesforce.

SOSL Query (advanced)

Execute a raw SOSL query to extract data from Salesforce.

Update custom field

Update custom field metadata using name.

Update record

Update a record in Salesforce.

Upload and link file

Upload and link a file to a particular record in Salesforce.

Upload attachment

Upload an file, attached to a particular record in Salesforce.

Upload file

Upload a file to Salesforce.

Write consent

Update and write consent across multiple records, helping you sync consent across records or populate the new Consent data model.