Salesforce REST API

CRUD operations on Salesforce SObjects, composite batch operations, and SOSL search.

Output

SObject CRUD

FormatCrateDescription
JSONsalesforce_coreSalesforce API response. For create: includes id, success, errors. For get / get_by_external_id: the full record object. Record ID is set as event.id.

Composite

FormatCrateDescription
JSONsalesforce_coreArray of sub-request results, each with statusCode, result, and errors.

Search / Query

FormatCrateDescription
JSONsalesforce_coreSalesforce SOSL/SOQL response with searchRecords or records array.

SObject operations

Single-record operations: create, get, get_by_external_id, update, upsert, delete.

- salesforce_restapi_sobject:
    name: create_account
    operation: create
    credentials_path: /etc/salesforce/credentials.json
    sobject_type: Account
    payload:
      Name: "{{event.data.company_name}}"
      Industry: "Technology"

Fields

FieldTypeDefaultDescription
namestringrequiredTask name.
operationstringrequiredcreate, get, get_by_external_id, update, upsert, delete.
credentials_pathstringrequiredPath to Salesforce credentials.
sobject_typestringrequiredSObject type (e.g., Account, Contact).
payloadobjectRecord fields — explicit values or from_event: true.
record_idstringSalesforce record ID (for get, update, delete). Supports templating.
fieldsstringComma-separated field list (for get).
external_id_fieldstringExternal ID field name (for upsert, get_by_external_id).
external_id_valuestringExternal ID value. Supports templating.
allow_duplicate_saveboolfalseSend Sforce-Duplicate-Rule-Header: allowSave=true so the request bypasses Salesforce duplicate-detection rules. See Duplicate-rule override.
depends_onlistUpstream task names.
retryobjectRetry configuration.

Examples

Upsert by external ID:

- salesforce_restapi_sobject:
    name: upsert_contact
    operation: upsert
    credentials_path: /etc/salesforce/credentials.json
    sobject_type: Contact
    external_id_field: External_Id__c
    external_id_value: "{{event.data.external_id}}"
    payload:
      FirstName: "{{event.data.first_name}}"
      LastName: "{{event.data.last_name}}"

Get a record:

- salesforce_restapi_sobject:
    name: get_account
    operation: get
    credentials_path: /etc/salesforce/credentials.json
    sobject_type: Account
    record_id: "{{event.data.account_id}}"
    fields: "Id,Name,Industry"

Composite operations

Batch operations on multiple records: create, get, update, upsert, delete, tree.

- salesforce_restapi_composite:
    name: bulk_create
    operation: create
    credentials_path: /etc/salesforce/credentials.json
    sobject_type: Account
    payload:
      from_event: true

Composite fields

FieldTypeDefaultDescription
namestringrequiredTask name.
operationstringrequiredcreate, get, update, upsert, delete, tree.
credentials_pathstringrequiredPath to Salesforce credentials.
sobject_typestringSObject type.
payloadobjectRecords — explicit list or from_event: true.
idslistRecord IDs (for get, delete).
fieldslistField list (for get).
external_id_fieldstringExternal ID field (for upsert).
all_or_noneboolAtomic transaction — all succeed or all fail.
allow_duplicate_saveboolfalseSend Sforce-Duplicate-Rule-Header: allowSave=true so the batch bypasses Salesforce duplicate-detection rules. See Duplicate-rule override.
depends_onlistUpstream task names.
retryobjectRetry configuration.

Duplicate-rule override

Salesforce ships duplicate detection rules with a default action of Block on standard SObjects (Account, Lead, Contact). When a request tries to create or update a record that matches an existing one on a rule-watched field (e.g. Email, Phone, Name), the call returns a 200 OK but the record is rejected with DUPLICATES_DETECTED in the per-record errors array — silently from the caller’s perspective.

Set allow_duplicate_save: true on the task to attach the Sforce-Duplicate-Rule-Header: allowSave=true header to the request. Salesforce will then save the record and surface a duplicate warning instead of blocking the write.

- salesforce_restapi_composite:
    name: upsert_contacts
    operation: upsert
    credentials_path: /etc/salesforce/credentials.json
    sobject_type: Contact
    external_id_field: ExternalId__c
    all_or_none: true
    allow_duplicate_save: true
    payload:
      from_event: true

The flag applies to write operations only:

  • salesforce_restapi_sobject: create, update, upsert
  • salesforce_restapi_composite: create, update, upsert, tree

It is a no-op on get, get_by_external_id, and delete.

Execute SOSL queries to search across multiple objects simultaneously. Returns matching records as a JSON event.

- salesforce_restapi_search:
    name: find_accounts
    credentials_path: /etc/salesforce/credentials.json
    query: "FIND {Acme} IN ALL FIELDS RETURNING Account(Id, Name, Industry)"

Search fields

FieldTypeDefaultDescription
namestringrequiredTask name.
credentials_pathstringrequiredPath to Salesforce credentials.
querystringrequiredSOSL query string. Supports templating.
depends_onlistUpstream task names.
retryobjectRetry configuration.

Templating the search term

SOSL wraps the search term in curly braces (FIND {term} ...). Since Handlebars only treats double {{ as special, a single { is a literal character. Wrap the templated term in double quotes to make it a phrase search, then use single-quoted YAML so the inner " doesn’t need escaping:

- salesforce_restapi_search:
    name: dynamic_search
    credentials_path: /etc/salesforce/credentials.json
    query: 'FIND {"{{event.data.search_term}}"} IN ALL FIELDS RETURNING Account(Id, Name), Contact(Id, FirstName, LastName, Email)'

Inside the {"..."} phrase, the processor auto-escapes SOSL reserved characters (- ? & | ! { } [ ] ( ) ^ ~ * : \ " ' +) before sending the query, so search terms with hyphens, spaces, or other reserved characters work without manual escaping.

Prefix matching

Phrase search matches whole tokens. To match terms that start with the search input (e.g. test should also find test-rmp and Test Account 1), append * inside the phrase:

query: 'FIND {"{{event.data.search_term}}*"} IN ALL FIELDS RETURNING Account(Id, Name)'

Examples

Search with specific scope and field limits:

- salesforce_restapi_search:
    name: search_name_fields
    credentials_path: /etc/salesforce/credentials.json
    query: "FIND {Acme} IN NAME FIELDS RETURNING Account(Id, Name, Industry LIMIT 10), Contact(Id, FirstName, LastName LIMIT 5)"

Webhook-triggered search:

flow:
  name: salesforce_search
  tasks:
    - http_endpoint:
        name: trigger
        method: POST
        endpoint: /search

    - salesforce_restapi_search:
        name: sosl_search
        credentials_path: $SALESFORCE_CREDENTIALS_PATH
        query: 'FIND {"{{event.data.term}}"} IN ALL FIELDS RETURNING Account(Id, Name), Contact(Id, Email)'

    - log:
        name: log_results
        level: info
        structured: true