Skip to main content

Salesforce Module

Overview

SalesforceModule connects a ValkyrAI workflow to one Salesforce tenant through REST API v62.0. Version 2 replaces the legacy raw auth object and password-grant flow with a READY IntegrationAccount, validates the tenant origin, bounds every request and response, and verifies the exact provider status before reporting success.

The module supports one read page or one record mutation per execution:

  • run a bounded SOQL SELECT query;
  • continue that query with an opaque Salesforce cursor;
  • create one SObject record;
  • update one record by Salesforce ID;
  • upsert one record by an external-ID field; or
  • delete one record after a separate explicit confirmation.

It does not accept a raw access token, client secret, username, password, security token, arbitrary endpoint, or provider URL in workflow input.

Usage

  1. Create or select a least-privilege Salesforce OAuth integration.
  2. Store the tenant HTTPS origin and OAuth access token in an IntegrationAccount.
  3. Bind that account through the normalized ExecModuleConfig.authConfig.integrationAccount relationship.
  4. Select one documented operation and provide its required inputs.
  5. Set confirmMutation: true for create, update, or upsert. Set confirmDelete: true only for an intentional delete.
  6. Inspect status, attempts, httpStatus, and either the query-page or mutation outputs.

Queries may be retried after bounded transient failures. Mutations are sent at most once because a timeout can occur after Salesforce commits the change.

Inputs

InputTypeRequiredBoundPurpose
operationstringYesquery, create, update, upsert, or deleteSelects one fixed Salesforce REST operation.
soqlstringFor an initial queryStarts with SELECT; at most 20,000 charactersDefines the read-only SOQL query.
nextCursorstringFor a later query pageRelative /services/data/vXX.0/query/... path onlyContinues an existing Salesforce query without accepting an absolute URL.
limitintegerNo200 through 2,000; default 2,000Requests the provider query batch size.
sobjectstringFor mutationsSalesforce API-name characters; at most 128Names the standard or custom SObject.
recordIdstringUpdate/deleteExactly 15 or 18 Salesforce ID charactersSelects the record to mutate.
externalIdFieldstringUpsertSalesforce field API-name charactersNames the configured external-ID field.
externalIdstringUpsertNon-empty; at most 255 charactersSelects the external identity; path encoding is automatic.
recordobjectCreate/update/upsertNon-empty; at most 100 fields and 256 KiBContains Salesforce field API names and values.
confirmMutationbooleanCreate/update/upsertMust be trueConfirms one outbound record mutation.
confirmDeletebooleanDeleteMust be trueSeparately confirms an irreversible record deletion.
timeoutMsintegerNo100 through 300,000; default 30,000Bounds connection and response time.

record rejects Id, attributes, credential-like field names at every nesting level, oversized arrays, excessive nesting, and oversized text values. Salesforce still validates object-specific required fields, field types, picklists, validation rules, and permissions.

Outputs

OutputTypeWhen presentMeaning
statusstringAlwayssuccess or error.
operationstringAlwaysNormalized operation name.
itemsarrayQuery successOne bounded Salesforce query page with attributes metadata removed.
countintegerQuery successNumber of records in items.
totalSizeintegerQuery successProvider-reported total matching records.
hasMorebooleanQuery successWhether Salesforce returned another query locator.
nextCursorstringIncomplete queryOpaque relative cursor for a later execution.
resourceIdstringMutation success when knownVerified Salesforce record ID.
createdbooleanUpsert successtrue for HTTP 201 create; false for HTTP 204 update.
providerAcceptedbooleanMutation successtrue only after the operation-specific HTTP status is verified.
httpStatusintegerProvider responseExact Salesforce HTTP status.
attemptsintegerAlwaysProvider attempts consumed; mutations are at most one.
errorobjectFailureSafe code, redacted message, and retryable flag.

OAuth tokens, authorization headers, raw provider bodies, and record payloads are never returned.

IntegrationAccount Requirements

SettingRequirement
ProviderSalesforce OAuth 2.0 connected app or external client app
accountNameHuman-readable automation identity
accountIdCredential-free tenant origin such as https://acme.my.salesforce.com
apiKeyEncrypted current OAuth access token
statusMust be READY

The tenant origin must be HTTPS, have no user info, port, query, fragment, or non-root path, and end in a Salesforce-controlled salesforce.com or force.com domain. The module never authenticates against login.salesforce.com, refreshes a token, or reconstructs a password grant from workflow data. Token acquisition and refresh belong to the platform integration-account lifecycle.

Grant only the API and object/field permissions needed by the selected workflow. Salesforce sharing rules, CRUD/FLS, restriction rules, and connected-app policies remain authoritative.

Configuration

{
"version": "2.0.0",
"authConfig": {
"authStrategy": 1,
"integrationAccount": "integration-account:salesforce-sales-ops"
},
"executionConfig": {
"timeoutMs": 30000
},
"payloadConfig": {
"parameters": "{\"operation\":\"query\",\"limit\":500}"
}
}

The relationship value is symbolic. Persisted workflows bind an actual IntegrationAccount; they never place the access token in payloadConfig.parameters or module input.

Operations

OperationSalesforce resourceRequired dataSide effect and retry policy
query/services/data/v62.0/query or a validated locatorsoql or nextCursorRead-only; transient 408, 429, 500, 502, 503, and 504 responses may be retried up to three attempts.
create/services/data/v62.0/sobjects/{sobject}sobject, record, confirmMutation:trueCreates one record; exactly one attempt; requires HTTP 201 plus success:true and a valid ID.
update/services/data/v62.0/sobjects/{sobject}/{recordId}sobject, recordId, record, confirmMutation:trueUpdates one record; exactly one attempt; requires HTTP 204.
upsert/services/data/v62.0/sobjects/{sobject}/{externalIdField}/{externalId}SObject, external identity, record, confirmationCreates or updates one record; exactly one attempt; requires HTTP 201 or 204.
delete/services/data/v62.0/sobjects/{sobject}/{recordId}sobject, recordId, confirmDelete:trueDeletes one record; exactly one attempt; requires HTTP 204.

Errors and Failure Modes

CodeTypical causeRetryableRecovery
VALIDATION_ERRORInvalid query, cursor, tenant, record, identifier, bound, confirmation, or provider success shape.NoCorrect the named input or account configuration.
UNSUPPORTED_OPERATIONUnknown operation name.NoSelect one of the five documented operations.
INTEGRATION_ACCOUNT_REQUIREDNo account relationship is bound.NoBind a Salesforce IntegrationAccount.
INTEGRATION_ACCOUNT_NOT_READYBound account is not READY.NoRepair or reconnect the account.
SALESFORCE_HTTP_400Invalid SOQL, field, object, value, or provider rule.NoCorrect the bounded provider message and request.
SALESFORCE_HTTP_401OAuth access token is invalid or expired.NoRefresh or reconnect the IntegrationAccount.
SALESFORCE_HTTP_403Missing API, object, field, or sharing permission.NoGrant the minimum required authority.
SALESFORCE_HTTP_404Record, object, or external identity is missing or invisible.NoReconcile under the same Salesforce identity.
SALESFORCE_HTTP_429Salesforce API limit was reached.Yes for query onlyRespect the retry window or resume later.
SALESFORCE_HTTP_5xxProvider-side transient failure.Yes for query onlyRetry reads; reconcile mutations before manual re-execution.
NETWORK_ERRORDNS, TLS, timeout, or connectivity failure.Yes for query onlyVerify connectivity; inspect Salesforce before repeating a mutation.
RESPONSE_TOO_LARGEResponse exceeded 5 MiB.NoNarrow the SOQL projection or result set.
EXECUTION_ERRORUnexpected local runtime failure.NoInspect sanitized logs and module validation evidence.

Salesforce error messages are limited, redacted through the shared sensitive-data policy, and never logged with exception payloads or bearer credentials.

Example

Query the most recently modified open opportunities:

{
"operation": "query",
"soql": "SELECT Id, Name, StageName, Amount, CloseDate FROM Opportunity WHERE IsClosed = false ORDER BY LastModifiedDate DESC",
"limit": 500
}

Expected result shape:

{
"status": "success",
"operation": "query",
"items": [
{
"Id": "006A0000008abcQIAQ",
"Name": "Enterprise renewal",
"StageName": "Proposal/Price Quote",
"Amount": 125000,
"CloseDate": "2026-09-30"
}
],
"count": 1,
"totalSize": 1,
"hasMore": false,
"httpStatus": 200,
"attempts": 1
}

To update a record, a workflow must provide the exact SObject and record ID and set confirmMutation:true. To delete it, the workflow must instead set the distinct confirmDelete:true guard.

Notes

  • Pagination: each execution returns one query page. When done:false, preserve nextCursor and pass it to a later execution without soql. Absolute and cross-host cursor URLs are rejected.
  • Batch size: Salesforce accepts query batch-size requests from 200 through 2,000 but may return fewer records. The module rejects a provider page that exceeds the requested bound.
  • API limits: calls consume the bound integration user's Salesforce API allocation. The module does not hide limits with an unbounded loop.
  • Idempotency: queries are safe to retry. Create, update, upsert, and delete are single-attempt because transport failure can be ambiguous. Use stable external IDs for upsert and perform read-after-write reconciliation before a manual retry.
  • Rate limits: query retries honor a bounded numeric Retry-After value and otherwise use bounded local backoff. Mutations never retry automatically.
  • Destructive behavior: delete permanently changes Salesforce state and requires confirmDelete:true. Salesforce recycle-bin and retention behavior depends on the tenant and object.
  • Consistency: automation, flows, triggers, duplicate rules, validation rules, and asynchronous processing can change records after a successful response.
  • Data classification: selected CRM fields leave ValkyrAI for Salesforce. Choose inputs and downstream outputs consistent with tenant policy.
  • External verification: local tests cover request construction, origin and cursor confinement, confirmations, response mapping, transient read retry, single-attempt writes, redaction, and catalog discovery. Real OAuth scopes, object permissions, tenant automation, API limits, and provider behavior require a Salesforce test tenant and are not exercised by repository tests.
  • Deferred operations: Bulk API 2.0, Composite API, queryAll, search, object describe, file/blob operations, relationship traversal endpoints, OAuth refresh, CDC subscriptions, and arbitrary REST calls are intentionally outside this bounded release.
  • Runtime boundary: merged source and published documentation do not update Workflow Studio until the backend serving /v1/modules/metadata is separately deployed. The live endpoint remains authoritative for deployed version and configuration.
  • Provider references: Salesforce REST object-data overview, REST query pagination guidance, and Composite authentication example.