Integration Procedure Invocation from Apex

Starting with Summer’ 25, use the ConnectAPI.OmniDesignerConnect.integrationProcedureExecute(ipName, apexInput) Connect API for Integration Procedure calls from the IntegrationProcedureService Apex class. This Connect API removes the dependency on the managed package and provides up to 21% better performance for Integration Procedure calls from an Apex class compared to the previous method.

Important
Important The performance figures in this document are provided for informational purposes only and are based on internal validation and testing under specific conditions. Actual results may vary depending on your component design, production environment, and other factors. These figures provide ‌general guidance and aren't a guarantee of performance.

Prerequisites

Before using the Connect API for Integration Procedure invocations, enable Enhanced Runtime Performance on the Omnistudio Settings page. When Enhanced Runtime Performance is disabled, requests do not route through the Connect API.

For instructions, see Enable Enhanced Runtime Performance of Components.

Invoke an Integration Procedure and return its data

Invokes an Integration Procedure and returns its data. Ignores Sharing Rules and Custom Permissions, which ensures that the Integration Procedure is private. See Sharing Rules and Custom Permissions in Salesforce Help.

Connect API for Integration Procedure Invocation Existing Method (Replace with Connect API)
String ipName = 'FindContacts_LastNames';
Map<String, Object> inputMap = new Map<String, Object>();
inputMap.put('ContactLastName', 'Smith');

Map<String, Object> optionsMap = new Map<String, Object>();
optionsMap.put('isDebug', false);

ConnectAPI.IntegrationProcedureServiceRunInputRepresentation apexInput = new ConnectAPI.IntegrationProcedureServiceRunInputRepresentation();
List<String> stringList = new List<String>();
String serializedInputMap = JSON.serialize(inputMap);
stringList.add(serializedInputMap);
apexInput.input = stringList;

ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation options = new ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation();
for (String key: optionsMap.keySet()){
    if (key == 'isDebug') {
        options.isDebug = (Boolean)optionsMap.get(key);
    } else if (key == 'chainable') {
        options.chainable = (Boolean)optionsMap.get(key);
    } else if (key == 'resetCache') {
        options.resetCache = (Boolean)optionsMap.get(key);
    } else if (key == 'ignoreCache') {
        options.ignoreCache = (Boolean)optionsMap.get(key);
    } else if (key == 'queueableChainable') {
        options.queueableChainable = (Boolean)optionsMap.get(key);
    } else if (key == 'useQueueableApexRemoting') {
        options.useQueueableApexRemoting = (Boolean)optionsMap.get(key);
    } else if (key == 'vlcApexResponse') {
        options.vlcApexResponse = (Boolean)optionsMap.get(key);
    } else if (key == 'useFuture') {
        options.useFuture = (Boolean)optionsMap.get(key);
    } else if (key == 'useQueueable') {
        options.useQueueable = (Boolean)optionsMap.get(key);
    } else if (key == 'vlcIPData') {
        options.vlcIPData = (String)optionsMap.get(key);
    } else if (key == 'vlcStatus') {
        options.vlcStatus = (String)optionsMap.get(key);
    } else if (key == 'vlcMessage') {
        options.vlcMessage = (String)optionsMap.get(key);
    }
}
options.shouldSendLegacyResponse = true;
apexInput.options = options;

ConnectAPI.IntegrationProcedureServiceRunOutputRepresentation output = ConnectAPI.OmniDesignerConnect.integrationProcedureExecute(ipName, apexInput);

List<String> responseList = output.response;
String currentSerResponse = responseList[0];
Map<String, Object> currentResponseObj = (Map<String, Object>)JSON.deserializeUntyped(currentSerResponse);

Object ipOutput = currentResponseObj.get('result');
String ipName = 'FindContacts_LastNames';
Map<String, Object> inputMap = new Map<String, Object>();
inputMap.put('ContactLastName',
'Smith');

Map<String, Object> optionsMap = new Map<String, Object>();
optionsMap.put('isDebug', false);

Object ipOutput = devopsimpkg11.Integration ProcedureService.runIntegrationService(ipName, inputMap, optionsMap);

Invoke an Integration Procedure and return its data ignoring Sharing Rules and Custom Permissions

Invokes an Integration Procedure and returns its data. Ignores sharing rules and custom permissions, which ensures that the Integration Procedure is private. See Sharing Rules and Custom Permissions in Salesforce Help.

Connect API for IP Invocation Existing Method (Replace with Connect API)

Users must have appropriate permissions to execute the Integration Procedure.


String ipName = 'FindContacts_LastNames';
Map<String, Object> inputMap = new Map<String, Object>();
inputMap.put('ContactLastName', 'Smith');

Map<String, Object> optionsMap = new Map<String, Object>();
optionsMap.put('isDebug', false);

ConnectAPI.IntegrationProcedureServiceRunInputRepresentation apexInput = new ConnectAPI.IntegrationProcedureServiceRunInputRepresentation();
List<String> stringList = new List<String>();
String serializedInputMap = JSON.serialize(inputMap);
stringList.add(serializedInputMap);
apexInput.input = stringList;

ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation options = new ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation();
for (String key: optionsMap.keySet()){
    if (key == 'isDebug') {
        options.isDebug = (Boolean)optionsMap.get(key);      
    } else if (key == 'chainable') {
        options.chainable = (Boolean)optionsMap.get(key);  
    } else if (key == 'resetCache') {
        options.resetCache = (Boolean)optionsMap.get(key);  
    } else if (key == 'ignoreCache') {
        options.ignoreCache = (Boolean)optionsMap.get(key);  
    } else if (key == 'queueableChainable') {
        options.queueableChainable = (Boolean)optionsMap.get(key);  
    } else if (key == 'useQueueableApexRemoting') {
        options.useQueueableApexRemoting = (Boolean)optionsMap.get(key);  
    } else if (key == 'vlcApexResponse') {
        options.vlcApexResponse = (Boolean)optionsMap.get(key);  
    } else if (key == 'useFuture') {
        options.useFuture = (Boolean)optionsMap.get(key);  
    } else if (key == 'useQueueable') {
        options.useQueueable = (Boolean)optionsMap.get(key);  
    } else if (key == 'vlcIPData') {
        options.vlcIPData = (String)optionsMap.get(key);  
    } else if (key == 'vlcStatus') {
        options.vlcStatus = (String)optionsMap.get(key);  
    } else if (key == 'vlcMessage') {
        options.vlcMessage = (String)optionsMap.get(key);  
    } 
}
options.shouldSendLegacyResponse = true;
apexInput.options = options;

ConnectAPI.IntegrationProcedureServiceRunOutputRepresentation output = ConnectAPI.OmniDesignerConnect.integrationProcedureExecute(ipName, apexInput);

List<String> responseList = output.response;
String currentSerResponse = responseList[0];
Map<String, Object> currentResponseObj = (Map<String, Object>)JSON.deserializeUntyped(currentSerResponse);

Object ipOutput = currentResponseObj.get('result');

String ipName = 'FindContacts_LastNames';
Map<String, Object> inputMap = new Map<String, Object>();
inputMap.put('ContactLastName', 'Smith');

Map<String, Object> optionsMap = new Map<String, Object>();
optionsMap.put('isDebug', false);
Object ipOutput = devopsimpkg11.IntegrationProcedureService.runIntegrationProcedureServiceFromApex(ipName, inputMap, optionsMap);

Invoke an Integration Procedure with a @future annotation applied

Connect API for Integration Procedure Invocation Existing Method (Replace with Connect API)

String ipName = 'FindContacts_LastNames';
String inputMap = '{"ContactLastName": "Smith"}';
String optionsMap = '{"isDebug": false}';

ConnectAPI.IntegrationProcedureServiceRunInputRepresentation apexInput = new ConnectAPI.IntegrationProcedureServiceRunInputRepresentation();
List<String> stringList = new List<String>();
stringList.add(inputMap);
apexInput.input = stringList;

Map<String, Object> optionsMapDeserialized = (Map<String, Object>)JSON.deserializeUntyped(optionsMap);

ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation options = new ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation();
 
 for (String key: optionsMapDeserialized.keySet()){
    if (key == 'isDebug') {
        options.isDebug = (Boolean)optionsMapDeserialized.get(key);  
    } else if (key == 'chainable') {
        options.chainable = (Boolean)optionsMapDeserialized.get(key);  
    } else if (key == 'resetCache') {
        options.resetCache = (Boolean)optionsMapDeserialized.get(key);  
    } else if (key == 'ignoreCache') {
        options.ignoreCache = (Boolean)optionsMapDeserialized.get(key);  
    } else if (key == 'queueableChainable') {
        options.queueableChainable = (Boolean)optionsMapDeserialized.get(key);  
    } else if (key == 'useQueueableApexRemoting') {
        options.useQueueableApexRemoting = (Boolean)optionsMapDeserialized.get(key);  
    } else if (key == 'vlcApexResponse') {
        options.vlcApexResponse = (Boolean)optionsMapDeserialized.get(key);  
    } else if (key == 'useFuture') {
        options.useFuture = (Boolean)optionsMapDeserialized.get(key);  
    } else if (key == 'useQueueable') {
        options.useQueueable = (Boolean)optionsMapDeserialized.get(key);  
    } else if (key == 'vlcIPData') {
        options.vlcIPData = (String)optionsMapDeserialized.get(key);  
    } else if (key == 'vlcStatus') {
        options.vlcStatus = (String)optionsMapDeserialized.get(key);  
    } else if (key == 'vlcMessage') {
        options.vlcMessage = (String)optionsMapDeserialized.get(key);  
    } 
}
  
options.shouldSendLegacyResponse = true;
options.useFuture = true;
apexInput.options = options;

ConnectAPI.OmniDesignerConnect.integrationProcedureExecute(ipName, apexInput);
String ipName = 'FindContacts_LastNames';
String inputMap = '{"ContactLastName": "Smith"}';
String optionsMap = '{"isDebug": false}';

devopsimpkg11.IntegrationProcedureService.runIntegrationServiceFuture(ipName, inputMap, optionsMap);

Invoke an Integration Procedure as a Queueable Apex Job for Asynchronous Processing

Returns the ID of the Queueable job. See Queueable Apex in Salesforce Help.

Connect API for Integration Procedure Invocation Existing Method (Replace with Connect API)

String ipName = 'FindContacts_LastNames';

Map<String, Object> inputMap = new Map<String, Object>();
inputMap.put('ContactLastName', 'Smith');

Map<String, Object> optionsMap = new Map<String, Object>();
optionsMap.put('isDebug', false);

ConnectAPI.IntegrationProcedureServiceRunInputRepresentation apexInput = new ConnectAPI.IntegrationProcedureServiceRunInputRepresentation();
List<String> stringList = new List<String>();
String serializedInputMap = JSON.serialize(inputMap);
stringList.add(serializedInputMap);
apexInput.input = stringList;

ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation options = new ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation();
for (String key: optionsMap.keySet()){
    if (key == 'isDebug') {
        options.isDebug = (Boolean)optionsMap.get(key);  
    } else if (key == 'chainable') {
        options.chainable = (Boolean)optionsMap.get(key);  
    } else if (key == 'resetCache') {
        options.resetCache = (Boolean)optionsMap.get(key);  
    } else if (key == 'ignoreCache') {
        options.ignoreCache = (Boolean)optionsMap.get(key);  
    } else if (key == 'queueableChainable') {
        options.queueableChainable = (Boolean)optionsMap.get(key);  
    } else if (key == 'useQueueableApexRemoting') {
        options.useQueueableApexRemoting = (Boolean)optionsMap.get(key);  
    } else if (key == 'vlcApexResponse') {
        options.vlcApexResponse = (Boolean)optionsMap.get(key);      
    } else if (key == 'useFuture') {
        options.useFuture = (Boolean)optionsMap.get(key);  
    } else if (key == 'useQueueable') {
        options.useQueueable = (Boolean)optionsMap.get(key);  
    } else if (key == 'vlcIPData') {
        options.vlcIPData = (String)optionsMap.get(key);  
    } else if (key == 'vlcStatus') {
        options.vlcStatus = (String)optionsMap.get(key);  
    } else if (key == 'vlcMessage') {
        options.vlcMessage = (String)optionsMap.get(key);  
    } 
}    
options.shouldSendLegacyResponse = true;
options.useQueueable = true;
apexInput.options = options;

ConnectAPI.IntegrationProcedureServiceRunOutputRepresentation output = ConnectAPI.OmniDesignerConnect.integrationProcedureExecute(ipName, apexInput);

List<String> responseList = output.response;
String currentSerResponse = responseList[0];
Map<String, Object> currentResponseObj = (Map<String, Object>)JSON.deserializeUntyped(currentSerResponse);

Object currentResult = currentResponseObj.get('result');
Map<String, Object> mapCurrentResult = (Map<String, Object>)currentResult;

Object ipResultObj = mapCurrentResult.get('IPResult');
Map<String, Object> IpResultMap = (Map<String, Object>)ipResultObj;
Id ipOutput = (Id)IpResultMap.get('queueableJobId');

String ipName = 'FindContacts_LastNames';
Map inputMap = new Map();
inputMap.put('ContactLastName', 'Smith');
Map optionsMap = new Map();
optionsMap.put('isDebug', false);


Id ipOutput = devopsimpkg11.IntegrationProcedureService.runIntegrationProcedureQueueable(ipName, inputMap, optionsMap);

Invokes an Integration Procedure passing in a map of input parameters and receiving the output in another map

Connect API for Integration Procedure Invocation Existing Method (Replace with Connect API)

String ipName = 'FindContacts_LastNames';
    
Map<String, Object> inputMap = new Map<String, Object>();
inputMap.put('ContactLastName', 'Smith');
   Map<String, Object> outputMap = new Map<String, Object>();


Map<String, Object> optionsMap = new Map<String, Object>();
optionsMap.put('isDebug', false);

ConnectAPI.IntegrationProcedureServiceRunInputRepresentation apexInput = new ConnectAPI.IntegrationProcedureServiceRunInputRepresentation();
List<String> stringList = new List<String>();
String serializedInputMap = JSON.serialize(inputMap);
stringList.add(serializedInputMap);
apexInput.input = stringList;

ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation options = new ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation();
for (String key: optionsMap.keySet()){
    if (key == 'isDebug') {
        options.isDebug = (Boolean)optionsMap.get(key);  
    } else if (key == 'chainable') {
        options.chainable = (Boolean)optionsMap.get(key);      
    } else if (key == 'resetCache') {
        options.resetCache = (Boolean)optionsMap.get(key);  
    } else if (key == 'ignoreCache') {
        options.ignoreCache = (Boolean)optionsMap.get(key);  
    } else if (key == 'queueableChainable') {
        options.queueableChainable = (Boolean)optionsMap.get(key);  
    } else if (key == 'useQueueableApexRemoting') {
        options.useQueueableApexRemoting = (Boolean)optionsMap.get(key);  
    } else if (key == 'vlcApexResponse') {
        options.vlcApexResponse = (Boolean)optionsMap.get(key);  
    } else if (key == 'useFuture') {
        options.useFuture = (Boolean)optionsMap.get(key);  
    } else if (key == 'useQueueable') {
        options.useQueueable = (Boolean)optionsMap.get(key);  
    } else if (key == 'vlcIPData') {
        options.vlcIPData = (String)optionsMap.get(key);  
    } else if (key == 'vlcStatus') {
        options.vlcStatus = (String)optionsMap.get(key);  
    } else if (key == 'vlcMessage') {
        options.vlcMessage = (String)optionsMap.get(key);  
    } 

}

options.shouldSendLegacyResponse = true;
apexInput.options = options;

ConnectAPI.IntegrationProcedureServiceRunOutputRepresentation output = ConnectAPI.OmniDesignerConnect.integrationProcedureExecute(ipName, apexInput);

List<String> responseList = output.response;
String currentSerResponse = responseList[0];
Map<String, Object> currentResponseObj = (Map<String, Object>)JSON.deserializeUntyped(currentSerResponse);
Object ipOutput = currentResponseObj.get('result');

if (options.useQueueable == true) {
    Map<String, Object> mapCurrentResult = (Map<String, Object>)ipOutput;
    Object ipResultObj = mapCurrentResult.get('IPResult');
    ipOutput = ipResultObj;
}
else if (options.useFuture == true) {
    ipOutput = new Map<String, Object>();
}    

outputMap.put('IPResult', ipOutput);

String ipName = 'FindContacts_LastNames';

Map<String, Object> inputMap = new Map<String, Object>();
inputMap.put('ContactLastName', 'Smith');

Map<String, Object> outputMap = new Map<String, Object>();

Map<String, Object> optionsMap = new Map<String, Object>();
optionsMap.put('isDebug', false);

devopsimpkg11.IntegrationProcedureService ipService = new devopsimpkg11.IntegrationProcedureService();

ipService.invokeMethod(ipName, inputMap, outputMap, optionsMap); // Returns Boolean

Object ipOutput = outputMap.get('IPResult');

Integration Procedure Call Examples

You can invoke an Integration Procedure from Apex code in two ways using the IntegrationProcedureService class.

Example 1


class IntegrationProcedureService {
/*
procedureAPIName - the Type_SubType of Procedure
input - The payload / initial data in the Map<String, Object> format for the Procedure
*/

String ipName = 'FindContacts_LastNames';
Map<String, Object> inputMap = new Map<String, Object>();
inputMap.put('ContactLastName', 'Smith');

Map<String, Object> optionsMap = new Map<String, Object>();
optionsMap.put('isDebug', false);

ConnectAPI.IntegrationProcedureServiceRunInputRepresentation apexInput = new ConnectAPI.IntegrationProcedureServiceRunInputRepresentation();
List<String> stringList = new List<String>();
String serializedInputMap = JSON.serialize(inputMap);
stringList.add(serializedInputMap);
apexInput.input = stringList;

ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation options = new ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation();
for (String key: optionsMap.keySet()){
if (key == 'isDebug') {
        options.isDebug = (Boolean)optionsMap.get(key);
    } else if (key == 'chainable') {
        options.chainable = (Boolean)optionsMap.get(key);
    } else if (key == 'resetCache') {
        options.resetCache = (Boolean)optionsMap.get(key);
    } else if (key == 'ignoreCache') {
        options.ignoreCache = (Boolean)optionsMap.get(key);
    } else if (key == 'queueableChainable') {
        options.queueableChainable = (Boolean)optionsMap.get(key);
    } else if (key == 'useQueueableApexRemoting') {
        options.useQueueableApexRemoting = (Boolean)optionsMap.get(key);
    } else if (key == 'vlcApexResponse') {
        options.vlcApexResponse = (Boolean)optionsMap.get(key);
    } else if (key == 'useFuture') {
        options.useFuture = (Boolean)optionsMap.get(key);
    } else if (key == 'useQueueable') {
        options.useQueueable = (Boolean)optionsMap.get(key);
    } else if (key == 'vlcIPData') {
        options.vlcIPData = (String)optionsMap.get(key);
    } else if (key == 'vlcStatus') {
        options.vlcStatus = (String)optionsMap.get(key);
    } else if (key == 'vlcMessage') {
        options.vlcMessage = (String)optionsMap.get(key);
    }
}
options.shouldSendLegacyResponse = true;
apexInput.options = options;

ConnectAPI.IntegrationProcedureServiceRunOutputRepresentation output = ConnectAPI.OmniDesignerConnect.integrationProcedureExecute(ipName, apexInput);

List<String> responseList = output.response;
String currentSerResponse = responseList[0];
Map<String, Object> currentResponseObj = (Map<String, Object>)JSON.deserializeUntyped(currentSerResponse);

Object ipOutput = currentResponseObj.get('result');

Example 2

/* Initialize variables */
String procedureName = 'Type_SubType';
Map<String, Object> ipInput = new Map<String, Object> ();
Map<String, Object> ipOutput = new Map<String, Object> ();
Map<String, Object> ipOptions = new Map<String, Object> ();

/* Populating input map for an Integration Procedure. 
Follow whatever structure your VIP expects */
String orderId = '80100000000abcd';
ipInput.put('orderId', orderId);

/* Call the Integration Procedure via runIntegrationService, 
and save the output to ipOutput */
ipOutput = (Map<String, Object>) 

String ipName = 'FindContacts_LastNames';
Map<String, Object> inputMap = new Map<String, Object>();
inputMap.put('ContactLastName', 'Smith');

Map<String, Object> optionsMap = new Map<String, Object>();
optionsMap.put('isDebug', false);

ConnectAPI.IntegrationProcedureServiceRunInputRepresentation apexInput = new ConnectAPI.IntegrationProcedureServiceRunInputRepresentation();
List<String> stringList = new List<String>();
String serializedInputMap = JSON.serialize(inputMap);
stringList.add(serializedInputMap);
apexInput.input = stringList;

ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation options = new ConnectAPI.IntegrationProcedureServiceRunOptionsRepresentation();
for (String key: optionsMap.keySet()){
    if (key == 'isDebug') {
        options.isDebug = (Boolean)optionsMap.get(key);
    } else if (key == 'chainable') {
        options.chainable = (Boolean)optionsMap.get(key);
    } else if (key == 'resetCache') {
        options.resetCache = (Boolean)optionsMap.get(key);
    } else if (key == 'ignoreCache') {
        options.ignoreCache = (Boolean)optionsMap.get(key);
    } else if (key == 'queueableChainable') {
        options.queueableChainable = (Boolean)optionsMap.get(key);
    } else if (key == 'useQueueableApexRemoting') {
        options.useQueueableApexRemoting = (Boolean)optionsMap.get(key);
    } else if (key == 'vlcApexResponse') {
        options.vlcApexResponse = (Boolean)optionsMap.get(key);
    } else if (key == 'useFuture') {
        options.useFuture = (Boolean)optionsMap.get(key);
    } else if (key == 'useQueueable') {
        options.useQueueable = (Boolean)optionsMap.get(key);
    } else if (key == 'vlcIPData') {
        options.vlcIPData = (String)optionsMap.get(key);
    } else if (key == 'vlcStatus') {
        options.vlcStatus = (String)optionsMap.get(key);
    } else if (key == 'vlcMessage') {
        options.vlcMessage = (String)optionsMap.get(key);
    }
}
options.shouldSendLegacyResponse = true;
apexInput.options = options;

ConnectAPI.IntegrationProcedureServiceRunOutputRepresentation output = ConnectAPI.OmniDesignerConnect.integrationProcedureExecute(ipName, apexInput);

List<String> responseList = output.response;
String currentSerResponse = responseList[0];
Map<String, Object> currentResponseObj = (Map<String, Object>)JSON.deserializeUntyped(currentSerResponse);

Object ipOutput = currentResponseObj.get('result');

System.debug('IP Output: ' + ipOutput);