Salesforce - SOQL Query
↩ Part of the Salesforce integration.
Description
Section titled “Description”Runs a SOQL query (GET /query?q=...) and returns the records array directly in data.
This is the most flexible node of the family: filters, ordering, aggregations and parent-child relationships all live in the query itself. Use it to find records when you do not have their id, to build a report, or to feed a loop.
Configuration
Section titled “Configuration”| Field | Type | Required | Description |
|---|---|---|---|
credentials_id | credentials | Yes | Salesforce credential |
soql | textarea | Yes | SOQL query, e.g. SELECT Id, Name FROM Account LIMIT 10 |
soql accepts dynamic variables, so {{data.email}} can be injected into the WHERE clause. This node has no sobject parameter — the object comes from the FROM clause of the query.
Credentials
Section titled “Credentials”This module requires a Salesforce credential:
| Field | Description |
|---|---|
login_url | https://login.salesforce.com or https://test.salesforce.com for a sandbox |
client_id / client_secret | Consumer Key and Secret of the Connected App |
username | Salesforce user |
password | Password plus the security token, concatenated |
Output
Section titled “Output”data is the array of records (the records field of the Salesforce response), not the envelope:
[ { "attributes": { "type": "Account", "url": "/services/data/v59.0/sobjects/Account/0015g00000AbCdEFGH" }, "Id": "0015g00000AbCdEFGH", "Name": "ACME S.A.", "Industry": "Manufacturing" }, { "attributes": { "type": "Account", "url": "/services/data/v59.0/sobjects/Account/0015g00000IjKlMNOP" }, "Id": "0015g00000IjKlMNOP", "Name": "Globex", "Industry": "Retail" }]The counters travel in _meta:
{ "moduleVersion": "1.0.0", "success": true, "count": 2, "totalSize": 2, "done": true, "totalMs": 340 }count— records returned in this call.totalSize— records matching the query.done—falsewhen Salesforce split the result into several pages.
A query that matches nothing returns [] and count: 0 — not an error.
Usage Example
Section titled “Usage Example”Find a contact by email
Section titled “Find a contact by email”SELECT Id, FirstName, LastName, AccountId FROM Contact WHERE Email = '{{data.email}}' LIMIT 1Opportunities closing this month
Section titled “Opportunities closing this month”SELECT Id, Name, Amount, StageName, CloseDateFROM OpportunityWHERE CloseDate = THIS_MONTH AND StageName != 'Closed Lost'ORDER BY Amount DESCLIMIT 200Accounts with their contacts (parent-child)
Section titled “Accounts with their contacts (parent-child)”SELECT Id, Name, (SELECT Id, Email FROM Contacts) FROM Account WHERE Industry = 'Manufacturing' LIMIT 50Count with an aggregate
Section titled “Count with an aggregate”SELECT COUNT(Id) total FROM Lead WHERE CreatedDate = LAST_N_DAYS:7- The node returns only the first page. Salesforce pages long results (2.000 records by default) and sets
done: falseplus anextRecordsUrl; this node does not follow it. Narrow the query withWHEREandLIMIT, or call the pagination endpoint with the HTTP node. - Text values in the query go between single quotes:
WHERE Email = 'ana@acme.com'. A value containing a quote breaks the query — sanitise it before injecting it. - Every record carries an
attributesblock with its type and URL. Use a data mapping node to drop it before exporting. - Aggregate queries (
COUNT,SUM,GROUP BY) returnAggregateResultrows, where unaliased columns are namedexpr0,expr1… Alias them, as in the last example. - Date literals such as
TODAY,THIS_MONTHorLAST_N_DAYS:7go without quotes. - A malformed query returns
400 MALFORMED_QUERYwith the position of the problem. It is not retried.
Related Nodes
Section titled “Related Nodes”- Salesforce: Get record — simpler when you already have the id.
- Salesforce: Update record — update each record while iterating the result.
- Salesforce: Create record — create the record when the query returns nothing.