Salesforce Automation: From Flow Rules to an Agent That Reads the Pipe

Flow handles the rules you can write down. The work that needs judgment across accounts, calls, and contracts still lands on a human. Here is what the Salesforce API actually gives an external agent, the governor limits you trade for, and a worked pipeline-hygiene build.

Jose Giron
salesforce-automation-hero.png

What Salesforce automation covers (and what people mean by it)

The phrase points at two different things depending on who says it. A sales leader means the category: pipeline tracking, activity capture, forecasting, quota rollups. An engineer means the machinery that changes records without anyone clicking Save.

On the engineering side there are five surfaces, and they are not interchangeable.

Flow Builder is the declarative one. Record-triggered flows, scheduled flows, screen flows. It covers the rules you can write down in advance.

Apex is code running inside the platform. Triggers, scheduled classes, invocable methods, for logic Flow cannot express.

Approval processes attach a state machine to a record and route it through named approvers.

Agentforce is Salesforce's own reasoning layer, assembled from subagents (called topics until the April 2026 rename) and actions.

External integrations are everything calling the REST API from outside the org: your own service, an ETL job, an AI agent.

The first four execute inside Salesforce's transaction boundary and pay Salesforce's per-transaction taxes. The fifth executes on your infrastructure and pays a completely different one. Which side of that boundary your work belongs on is the decision this article is actually about.

Flow, Apex, Agentforce, or your own agent

| Option | Where it runs | Who owns the reasoning | Limits that bind | What it costs you | |---|---|---|---|---| | Flow | In-platform, declarative | Nobody. You encode the rules up front | Shares the Apex per-transaction budget when it touches records | Included with the license, plus admin time to maintain | | Apex | In-platform code | Nobody. Fully deterministic | 100 synchronous SOQL queries, 50,000 records retrieved, 150 DML statements per transaction | Included with the license, plus developer time and required test coverage | | Agentforce | In-platform, on Salesforce's model | Salesforce | 8 LLM calls per user utterance; action results truncated near 65,000 characters; 128,000-token context | Metered per agent action in Flex Credits, and gated behind a Data 360 provisioning requirement | | Your own agent | Your infrastructure, over the REST API | You. Model choice, prompt, and loop | Org-wide 24-hour API allocation, 25 concurrent long-running requests, and the integration user's sharing rules | Your model spend and your hosting, with no per-action metering by Salesforce |

The Agentforce row's last cell is the one people miss. Data 360 has to be provisioned and enabled before the Einstein Trust Layer, agent event logs, and consumption billing tracking work at all. Salesforce states it twice in the org setup guide: "Data 360 is required to ensure that the Einstein Trust Layer functions correctly and protects your data." Budget for it before you scope the project, not after. One more caveat belongs in any governance conversation about that trust layer: per Salesforce's own Trailhead module, "data masking for LLMs is currently disabled for agents."

Here is the position that matters more than the table. Most "AI on Salesforce" projects should not start with a reasoning loop. They should start by deciding which steps never need one. If the logic is genuinely deterministic, meaning this stage plus this amount routes to this queue, a record-triggered Flow is cheaper, faster, and easier to hand to an admin than anything you will build. Save the model for the part where the answer depends on reading a call transcript against a contract, not the part where it depends on a picklist value.

When an AI agent over Salesforce actually helps

Four patterns where the judgment is real.

Opportunity lifecycle triage. A Flow can flag every opportunity past its close date. It cannot tell you which of those forty deals are dead and which are waiting on a procurement cycle that always runs three weeks long. That distinction lives in call notes and email threads, and it is a judgment call.

Lead scoring on unstructured signal. Scoring on firmographics is a formula field. Scoring on what a prospect actually said on a discovery call, weighted against how similar accounts converted, is not.

RevOps pipeline reporting. Reports render numbers. The weekly question is why the numbers moved, which means correlating stage changes against activity, ownership churn, and competitive mentions. This is where RevOps and pipeline reporting stops being a dashboard problem.

Account-based outreach prep. Assembling the last six months of touchpoints across four systems and deciding what is worth saying to this account this week. The assembly is mechanical. The decision is not.

Each of these has the same shape: a large deterministic gathering step, one small judgment step, and a deterministic write step. Recognizing that shape is most of the work. For the general version of this, see how to structure an agentic workflow.

What you need to build one

The Salesforce API in 200 words

Authentication first, and start with a warning that invalidates most tutorials online: as of Spring '26, creating new connected apps is restricted by default, and Salesforce directs you to external client apps instead. Existing connected apps keep working. New ones need Support.

Two OAuth flows fit a server-side agent with no human at the keyboard: JWT bearer and client credentials. The username-password flow is blocked by default for orgs created Summer '23 or later, so ignore it. Client credentials is the simpler option and has four sharp edges. It requires a designated Run As user. It does not work against login.salesforce.com or test.salesforce.com, so you POST to the org's My Domain host. It returns no refresh token. And you must not send a scope parameter.

POST https://yourdomain.my.salesforce.com/services/oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=CONSUMER_KEY&client_secret=CONSUMER_SECRET

The response carries access_token and instance_url. Use instance_url as the base for every subsequent call. Do not hardcode a hostname.

After that: sObject CRUD at /services/data/v67.0/sobjects/{Object}/{Id}, SOQL at /query, and upsert by external ID (PATCH /sobjects/Account/External_Id__c/12345), which is the idempotency primitive that stops a re-run from double-writing. Then the composite family, which is where the real efficiency lives.

Pros and cons of the Salesforce API

The coverage is excellent. Nearly every object is reachable, SOQL is expressive, upsert-by-external-ID is a genuinely good idempotency story, and /composite lets you fold a lot of work into a single billed call.

The cons are specific and worth internalizing.

The sharing trap is the one that bites in production. All API calls respect the sharing model, which means your calls run with the permissions of the logged-in user. In a Private-OWD org, an under-permissioned integration user receives a partial result set with no error raised. Your agent then reasons over a truncated query and is confidently wrong. Nothing in the response tells you this happened. Note also that View All Data overrides sharing but does not bypass field-level security. They are two independent gates.

Batching is opt-in and easy to get backwards. /composite bundles up to 25 subrequests and counts as one call. /composite/batch takes the same 25 and counts each separately. Same ceiling, 25x the allocation cost.

API versions retire. v7 through v30 are gone and return HTTP 410. Versions v31 through v40 are announced for retirement in Summer '28. Pin a version and track the deprecation calendar.

And if you are wiring this through a connector layer, check what it asks for. Pipedream's instant Salesforce triggers require Apex REST Services, Author Apex, and Modify Metadata permissions, because they deploy Apex into your org to work.

| Limit | Value | Source | |---|---|---| | 24-hour API allocation, Enterprise/Unlimited | 100,000 baseline, plus per-license allocations and any add-ons | Limits cheatsheet | | 24-hour API allocation, Developer Edition | 15,000 flat | Limits cheatsheet | | Concurrent long-running requests | 25, applying only to calls lasting 20 seconds or longer | Limits cheatsheet | | Apex per-transaction | 100 synchronous SOQL queries, 50,000 records retrieved, 150 DML statements | Apex governor limits | | /composite | Up to 25 subrequests, counted as one API call | Composite docs | | /composite/batch | Up to 25 subrequests, each counted separately | Composite batch docs | | Bulk API 2.0 | 150 MB of batch content per job | Limits cheatsheet | | Agentforce reasoning | 8 LLM calls per user utterance | Salesforce Help |

The build sequence, in order

  1. Create an external client app in Setup. Not a connected app.
  2. Enable the OAuth flow you picked, JWT bearer or client credentials, and set the Run As user.
  3. Provision a dedicated Salesforce Integration user on the Minimum Access - API Only Integrations profile. One user per integration, never a shared service account.
  4. Grant object and field permissions scoped to exactly the objects the agent touches, and confirm field-level security separately from sharing.
  5. POST to your My Domain token endpoint and capture access_token plus instance_url.
  6. Call /services/data/v67.0/limits first. It confirms auth and shows your remaining allocation in one request.
  7. Run your real query as the integration user and diff the row count against the same query run as an admin. If they differ, you found the sharing trap before production did.

Step 7 is the one nobody does and everybody should.

A worked example: the pipeline-hygiene agent

What it does

It answers the question a RevOps lead asks every week: which open opportunities are quietly rotting, and what should happen to each one.

It runs at 7am on weekday mornings, ahead of pipeline review. It pulls open opportunities past their expected close date or with no logged activity in 21 days, assembles context for each (recent Gong call mentions, last email touch, contract status in DocuSign), decides which are genuinely at risk versus merely slow, drafts a specific next step for each owner, writes its findings back to the opportunity record, and posts a ranked digest to the deal team's Slack channel. Ambiguous cases and anything above a value threshold route to a named human instead of being auto-updated.

How the steps wire together

  1. Trigger. Scheduled, 7am weekdays. Not event-driven, because the question is a weekly one.
  2. Read. One SOQL query for at-risk opportunities, then related records fetched through /composite so up to 25 subrequests land as a single call against the org's allocation.
  3. Enrich. Pull call signal from Gong and contract state from DocuSign, keyed by account.
  4. Decide. The model reads the assembled context and makes the call: at risk or not, and what the next step should be. This is the only step that needs a model.
  5. Write. Update opportunity fields via upsert by external ID, so a re-run after a failure does not double-write.
  6. Notify. Post the ranked digest to Slack and route flagged cases to their owner. The mechanics of routing the digest into Slack are the same as any other scheduled digest.

Running a different CRM does not change the shape. The same pattern on HubSpot swaps the query layer and keeps steps 1, 3, 4, and 6 intact.

What governance the agent needs

A dedicated Salesforce Integration user on the Minimum Access - API Only Integrations profile, used by this integration and nothing else. Object and field permissions scoped to Opportunity, Account, and Task only, with field-level security checked as a separate gate from sharing. OAuth through an external client app using JWT bearer or client credentials. Write scope narrowed to the specific fields it updates, with human approval required before any stage change or any write to a closed opportunity. Every write attributable in the app's own audit log, which is the practical form of scoped credentials at the point of action.

Build this in Major

Look at the six steps again. Steps 1, 2, 3, 5, and 6 are identical on every single run. The schedule, the SOQL query, the composite batching, the upsert, the Slack post. Only step 4 changes with the input.

That split is the whole design. On Major, an agent reasons once about how this workflow should work and then builds a deployed app for the repeatable five steps. The app holds its own state in a managed database, so last week's findings are still there this week. It batches through /composite the same way every time, which is what keeps a weekly job from eating the org's 24-hour allocation. It runs under scoped credentials with an audit trail on every write. The model runs only at step 4, on the judgment call, which is the part that actually needs it.

An agent that re-reasons the whole workflow every Monday fires individual REST calls per record, burns allocation, and gives you a different answer each week for reasons nobody can reconstruct. Reason once, run forever, with a rate limit to prove it. For the agent-side view of this same architecture, see Salesforce AI agent workflows beyond Agentforce.

If you already have the pipeline-hygiene query written and you are staring at the gap between "I can find the at-risk deals" and "something governed runs this every Monday and writes back safely," that gap is the app. Major is the enterprise platform where agents build the software they run on, so the deterministic five steps become a deployed app with its own database, permissions, and logs, and the model handles the one call it should. Get started on Major and build your Salesforce pipeline-hygiene agent.

Related articles

Frequently asked questions

What does Salesforce automation do?
Salesforce automation executes work on CRM records without manual clicks. Inside the platform, Flow Builder runs declarative record-triggered and scheduled processes, Apex runs custom code, and approval processes route records through approvers. Outside the platform, external services and AI agents call the Salesforce REST API to read, enrich, and write records on their own schedule and infrastructure.
Can you automate Salesforce without code?
Yes. Flow Builder handles record-triggered, scheduled, and screen-based processes declaratively, and approval processes route records without code. Declarative automation covers any rule you can specify in advance, such as stage changes, field updates, and task creation. It stops where judgment starts. Deciding whether a stalled deal is dead or waiting on procurement requires reading call notes and contracts, which no Flow condition expresses.
What is the difference between Salesforce automation and CRM?
The CRM is the system of record. It stores accounts, contacts, opportunities, and activity history. Automation is the layer that acts on those records: Flow, Apex, approval processes, and external API integrations that read, update, and route them. CRM holds the state. Automation changes it. You can run a CRM with no automation at all, just with more manual work.
What are Salesforce API limits?
Two limits matter most. The 24-hour allocation is org-wide and rolling: Developer Edition gets 15,000 requests flat, while Enterprise and Unlimited start at 100,000 plus per-license allocations and any purchased add-ons. Separately, orgs allow 25 concurrent requests, a ceiling that applies only to calls lasting 20 seconds or longer. Both are documented in Salesforce's platform API limits cheatsheet.
Does Agentforce require Data Cloud?
Yes. Data 360, formerly Data Cloud, must be provisioned and enabled before Agentforce works properly. Salesforce's org setup guide states that Data 360 is required for the Einstein Trust Layer to function correctly, and elsewhere names it as required for agent event logs and consumption billing tracking. That is a real cost of entry. It also means Salesforce owns the reasoning loop and meters it per action, rather than you owning a governed app you built.