Salto allows you to manage CPQ data (products, configuration attributes, etc.) as if it was metadata. That means you can compare and deploy it across environments, visualize dependencies (a.k.a “where is this used?”), and keep track of its history with Git.
Note the emphasis on the word allows. You can use Salto for CPQ for other use cases, such as seeding a sandbox with sample data. Treating CPQ data as metadata is a choice, and it typically means that:
You consider production the source of truth for CPQ data
You want the exact same data to exist in other sandboxes
You want to be able to make changes to this data in a sandbox and deploy the changes to production (just like you do with metadata)
CPQ data is not created in production without using Salto
If you want to treat CPQ data as metadata, then you must become familiar with how Salto manages CPQ records and the different options you have for specifying how records are matched across Salesforce environments.
The need for an ID
Salesforce metadata can easily be deployed to other orgs because it has a unique ID: its name.
If you have an apex class named UnitOfWork
in both your sandbox and production environments, these 2 classes are considered to be the same. They can be updated/deployed via change sets, sfdx, or the Salesforce API, which is the method utilized by Salto.
However, this principle does not apply to CPQ data and Salesforce data in general. For instance, If you import a product record with the data loader to your sandbox and repeat the upload to your production org, Salesforce doesn’t automatically recognize that these two records are the same.
This is also the case when using Salto for CPQ; there are no out-of-the-box methods that Salto can use to identify two records in different orgs as the same.
What’s needed is an ID that Salto can use on both products so that when you do a “compare and deploy” operation, Salto can tell they are the same. This will allow you to align CPQ data across environments and more.
Three ways to create a Salto ID
Salto provides three mechanisms for specifying how records are matched across environments. Let’s review the three mechanisms at a high-level first, followed by an in-depth explanation of each.
Use Salesforce record ID (default & recommended)
In this mechanism, the Salesforce ID of your production environment is used as a Salto ID. This is perfect when using CPQ data as metadata, as described in the previous section.
Use an external ID
In this mechanism, you must create a cpq_external_id__c
field on every CPQ object that you want to manage with Salto. You are responsible for populating this field with a unique value. Salto will then use the value in this field to match records across environments.
Use a field-value-based ID
In this last mechanism, the Salto ID is generated by concatenating multiple field values from your CPQ records. For example, the Product Code
, Product Family
, and Name
fields are concatenated to create a Salto ID. If the same combination exists in another Salesforce org, Salto considers these 2 records to be the same.
After changing the configuration that determines how Salto IDs are generated, you need to perform a fetch with the 'Regenerate Salto IDs' option enabled. This action will update the Salto IDs for elements that have already been fetched.
Now, let’s explore these three mechanisms in detail, along with some guidelines on when to use each.
Use Salesforce Record ID (default & recommended)
This method is meant to be used when Production is considered the source of truth for CPQ data, and you want to manage CPQ data as metadata; again, that means that:
You consider production the source of truth for CPQ data
You want the exact same data to exist in other sandboxes
You want to be able to make changes to this data in a sandbox and deploy the changes to production (just like you do with metadata)
CPQ data is ideally not created in production without using Salto. If you run into this scenario, read this article for instructions on how to resolve it.
Let’s see what this looks like in practice:
For all the sections below, assume that CPQ1 is production and CPQ2 is a sandbox
I have this product record in my production org:
And I’ve fetched it into my Salto production environment:
When I hover over its name, I can see the Salto ID is 01t3H000003FaZgQAK
:
This is the same ID that you can see in the Salesforce URL in the first screenshot.
That means the Salesforce ID is used as the Salto ID: a unique string to identify this record across other Salesforce environments.
Using Salto, I have deployed this product to my sandbox. When I look at the product in my Salto sandbox environment, I see that the Salto ID is exactly the same:
This means that as far as Salto is concerned, these 2 products are the same.
But what about the actual Salesforce ID in the sandbox? It’s not the same:
And this is expected: when you deploy data to other Salesforce orgs, Salesforce generates the IDs on the fly, and you have no control over it.
This might be a little mind-bending, so let’s summarise it with a table:
Org | Record | Salesforce ID | Salto ID |
Production | StarTech Keyboard | 01t3H000003FaZgQAK | 01t3H000003FaZgQAK |
Sandbox | StarTech Keyboard | 01t3H000003FayUQAS | 01t3H000003FaZgQAK |
As you can see, the Salesforce ID of the record in production is used as the Salto ID for both Salto environments, and it doesn’t matter that the Salesforce ID in the sandbox is different; Salto only cares about the Salto ID.
Now, as explained above, this is only one of three methods Salto offers for matching data across environments, and while this is the default and recommended one, it’s important that you are aware of its pros and cons:
Pros
No setup is required; it just works out of the box
The best method to truly treat CPQ data as metadata
Consistent and logical
Cons
Inflexible. The Salesforce ID is used as the Salto ID, and there’s no way to change that. For example, you can’t take 2 different records in 2 different orgs and tell Salto to treat them as one.
CPQ records created outside of Salto will have mismatched Salto IDs even if they are logically the same.
Let’s now move on to the next mechanism.
Use an External ID
This method is also meant to be used for treating CPQ data as metadata. Here, you must create a unique text field marked as an external ID in all the CPQ objects that you want to manage through Salto.
Salto does not provide a method to populate these records with a unique value in this field. You are responsible for creating such a mechanism, which is typically done by creating a batch apex job that goes through these records and stamps that field with a unique value.
The unique value can be anything you want, it can be the Salesforce ID or the Salesforce ID plus other field values, etc.
Once the ID is in the record, Salto will treat it as the Salto ID, and all Salto operations will behave as expected when a record in another environment has the same Salto ID.
Here are the pros and cons of this approach:
Pros
Extremely flexible. You have full control of what becomes the Salto ID, and you can update your records in any way you want, be it automated or even manually.
You can tell Salto that 2 records are meant to be treated as one simply by making sure both of them have the same value in the external ID field.
Supports records created outside of Salto (see point above)
Cons
You are responsible for all the logic and infrastructure required to ensure the IDs are unique and always populated. If IDs are missing or are not unique, Salto will behave in unexpected ways.
Salto is unable to offer any support in regard to the logic and infrastructure for generating the IDs.
It’s not straightforward to know how an ID was generated. Only someone from your team with intimate knowledge of your setup can answer that question.
To enable this mechanism, please contact support.
Use field values-based IDs
The final method creates a Salto ID by concatenating field values from a record, where it is assumed that the result of this concatenation will be a unique value.
Let’s say you have a product record with the following field values:
Name: Laptop
Family: Electronics
Product Code: 004
You can configure Salto to use these 3 fields to create a Salto ID, which would result with Laptop_Electronics_004
. If another product is found in another org with the same field values, its Salto ID will be the same, and Salto will consider them to be the same record.
Salto provides a default configuration for all standard CPQ objects and the fields that determine the ID. You can, however, modify this configuration or come up with your own. Contact support for more details on enabling this option.
Here are the pros and cons of this approach:
Pros
Flexible. You can decide which field values (and in what order) make up the Salto ID.
Easy to reason about how the Salto ID was generated—just look at your Salto configuration.
You can tell Salto to treat 2 different records as one by making sure the field values that make up the ID match.
Cons
Very prone to conflicts. It’s possible for multiple records to end up with the same combination of field values, resulting in duplicate Salto IDs. These records will not be fetched to your Salto environment.
When the field values change, so does the Salto ID. This may or may not be what you want or expect.
This method is considered suboptimal to the previous two; however, you can still use it if you want.
Summary
In conclusion, Salto offers three distinct methods for managing CPQ data: Salesforce Record ID, External ID, and field values-based IDs.
Each method has its unique merits and drawbacks, tailored to cater to different circumstances.
The Salesforce Record ID method stands out for its simplicity and out-of-the-box functionality, making it our top recommendation for those treating CPQ data as metadata. It offers predictability, replicability across sandboxes, and minimal setup.
Using an External ID is also a viable choice, particularly for those seeking high flexibility and control. Although it requires more setup and maintenance, it allows you to have complete control over what constitutes a Salto ID.
On the other hand, while the field values-based IDs offer a degree of flexibility, they are more prone to conflicts and may lead to unexpected changes to Salto IDs. Therefore, it's less ideal unless the specific use case warrants this approach.
Choosing the right method ultimately depends on your specific needs, the resources available for setup and maintenance, and your long-term data management strategy.
Here is a summary of the three approaches:
Approach | Recommended | Complexity | Flexibility |
Salesforce ID | Yes | Minimal | Rigid |
External ID field | Only if you want full control | High | Very flexible |
Field-value ID | Yes, for basic implementations | Medium | Flexible |
And here’s what Salto recommends you use each method for:
Approach | Sandbox seeding | CPQ data as metadata |
Salesforce ID | Recommended | Recommended |
External ID field | No—too complex | Recommended—if you are happy to own the ID generation logic |
Field-value ID | Only in simple seeding scenarios | No—ID conflicts are highly likely |