With MuleSoft Salesforce Integration and Anypoint Studio, Apex represents every Salesforce record as an sObject. Before inserting a record, Apex creates it as an sObject, and when Salesforce retrieves persisted records, Apex stores them in an sObject variable. As a result, Apex maps both standard and custom Salesforce objects directly to their corresponding sObject types.
In this first part of the series, we focus on how Salesforce sObjects work in combination with the Composite Connector, with an emphasis on understanding object structure and request composition.
SObject
Apex represents every Salesforce record as an sObject. Before inserting a record into Salesforce, Apex converts it into an sObject. Likewise, when Salesforce retrieves records, Apex stores them in sObject variables. This consistent behavior applies to both standard and custom objects, which enables uniform handling across Apex logic and MuleSoft integrations.
Apex commonly uses the following sObject type names for standard Salesforce objects:
- Account
- Contact
- Lead
- Opportunity
If you have added custom objects in your Salesforce organization, you must use the API names of those objects in Apex. For example, a custom object named MainframeAccounts maps to the MainframeAccounts__c sObject in Apex.
Working with SObject Tree
An sObject tree is a collection of nested parent-child records that share a single root record. This structure allows you to create multiple related Salesforce records in a single API request, which significantly improves efficiency and transactional consistency.
Using the Salesforce Composite Connector, you can create one or more sObject trees with root records of a specified type. To do this, add the Salesforce Composite Connector from Anypoint Exchange and configure it to create sObject trees.
Key points to remember when working with an sObject tree:
- Used for creating one or more sObject trees with root records of the specified type
- An sObject tree represents a collection of nested parent-child records
- Each record in the request must include a type and a reference ID

DataWeave Request Structure
The request can contain the following DataWeave transformation, which maps incoming payload data into the required Salesforce sObject tree format:
%dw 2.0
output application/java
payload.records map ((record , indexOfRecord) -> {
"attributes": {
"type": record.attributes.objectType,
"referenceId": record.attributes.referenceId
},
"Name": record.Name,
"Phone": record.Phone,
"Website": record.Website,
"NumberOfEmployees": record.NumberOfEmployees as Number,
("ChildAccounts": {
"records": record.ChildAccounts.records map ((record01, indexOfRecord01) -> {
"attributes": {
"type": record01.attributes.objectType,
"referenceId": record01.attributes.referenceId
},
"Name": record01.Name,
"Phone": record01.Phone,
"Website": record01.Website,
"NumberOfEmployees": record01.NumberOfEmployees as Number
})
}),
"Contacts": {
"records": record.Contacts.records map ((record01, indexOfRecord01) -> {
"attributes": {
"type": record01.attributes.objectType,
"referenceId": record01.attributes.referenceId
},
"LastName": record01.LastName,
"Email": record01.Email,
"Title": record01.Title
})
}
})
Salesforce enforces the following limits when working with sObject trees:
- Up to 200 records across all trees
- Up to five records of different types
- sObject trees can be up to five levels deep
Request Body
The request body contains a records collection that represents one or more sObject trees. Each record includes a defined set of properties required by the Salesforce Composite API.
Below is a JSON request example for creating one Account object with two related Contact objects:
{
"records": [
{
"attributes": {
"type": "Account",
"referenceId": "ref1"
},
"Phone": "4321098765",
"Website": "www.salesforce.com",
"Name": "Mule Account",
"Contacts": {
"records": [
{
"attributes": {
"type": "Contact",
"referenceId": "ref2"
},
"Email": "[email protected]",
"Title": "President",
"LastName": "Rush",
"FirstName": "Jake"
},
{
"attributes": {
"type": "Contact",
"referenceId": "ref3"
},
"Email": "[email protected]",
"Title": "Administrator",
"LastName": "Devis",
"FirstName": "Jane"
}
]
}
}
]
}
Each record includes:
- Attributes
- type: The Salesforce object type, such as Account or Contact
- referenceId: A unique identifier within the request that starts with an alphanumeric character
- Object fields
- Field names and values specific to the record
- Child relationships
- Nested child objects, such as Contacts within an Account
Response Body
If the request is successful, the response contains the IDs of all created records. However, if any error occurs while creating a record, none of the records are processed. In that case, the response returns only the reference ID of the record that caused the error along with error details.
The response includes two main properties:
- hasErrors
- true if an error occurred while creating a record
- false if all records were created successfully
- results
- On success: Contains the reference ID and newly created record ID
- On failure: Contains the reference ID, error status code, error message, and affected fields
Response Example
{
"hasErrors": false,
"results": [
{
"referenceId": "ref1",
"id": "0012x00000ELhrzAAD"
},
{
"referenceId": "ref2",
"id": "0032x00000AKPESAA5"
},
{
"referenceId": "ref3",
"id": "0032x00000AKPETAA5"
}
]
}
After successful execution, both the Account and associated Contact records are created in Salesforce.

In Part II, we extend these concepts by implementing complex sObject trees, managing references, and optimizing Composite Connector requests in MuleSoft.